ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Matlab拟合算法实战:从线性回归到非线性模型与工程应用

Matlab拟合算法实战:从线性回归到非线性模型与工程应用 1. 从“猜”到“算”为什么我们需要拟合算法做数据分析、搞科研、做工程的朋友估计没少和“拟合”这个词打交道。简单来说拟合就是给你一堆看起来乱糟糟的数据点让你找一条或者一个函数曲线能最好地描述这些数据点背后的规律。这听起来有点像“猜”但其实是“算”而且是基于数学原理的精密计算。我最早接触拟合是在处理一批传感器数据的时候。传感器传回来的温度、压力值总是带着各种噪声和波动直接看原始数据趋势是有的但具体是什么关系说不清。领导问“这俩参数到底啥关系给个公式看看。”这时候你就不能靠“目测”画条线了得用拟合算法从数学上找到那个最优的表达式。拟合算法的核心价值就在这里将观测数据转化为可量化、可预测的数学模型。无论是预测明天的销售额分析药物剂量与疗效的关系还是校准仪器误差背后都离不开拟合。而Matlab作为工程和科研领域的“瑞士军刀”其强大的矩阵运算能力和丰富的工具箱让实现各种拟合算法变得异常高效。所以这篇内容我就结合自己多年的使用经验抛开教科书上复杂的公式推导重点聊聊在实际项目中如何理解、选择并使用Matlab实现那些最常用、也最容易踩坑的拟合算法。我们会从最基础的线性拟合开始一步步深入到非线性拟合的复杂世界并探讨如何评估拟合结果的好坏。目标就一个让你拿到数据后知道该用什么工具怎么用以及如何判断结果靠不靠谱。2. 拟合的基石线性最小二乘法及其Matlab实战当我们说“拟合一条直线”时99%的情况下指的就是线性最小二乘法。这是所有拟合算法的入门课也是理解更复杂算法的基础。2.1 原理速览误差平方和最小化假设我们有一组数据点(x_i, y_i)我们想用一条直线y a*x b来拟合它们。所谓“最好”的直线就是让所有数据点到这条直线的垂直距离的平方和最小。为什么是平方和而不是直接求距离和主要有两个原因一是平方项保证了距离恒为正且放大了大误差的影响让拟合线对异常值更敏感这既是优点也是缺点二是数学上对平方和求导找极值最小化问题会得到一组漂亮的线性方程求解非常方便。这个最小化的过程最终会导出一个关于系数a和b的线性方程组正规方程。Matlab在背后就是通过矩阵运算高效地解这个方程。2.2 Matlab实现从polyfit到矩阵除法在Matlab里实现线性拟合简单到令人发指。最常用的函数是polyfit。% 示例1使用polyfit进行一元线性拟合 x [1, 2, 3, 4, 5, 6]; y [2.1, 3.9, 6.2, 8.1, 9.8, 12.1]; % 大致符合 y 2*x 0.5 % 进行1次多项式即直线拟合 p polyfit(x, y, 1); % p是一个包含两个系数的向量p(1)是斜率ap(2)是截距b a p(1); % 应接近2 b p(2); % 应接近0.5 % 用拟合出的系数生成拟合直线上的y值 y_fit polyval(p, x); % 绘图对比 figure; plot(x, y, o, MarkerSize, 8, DisplayName, 原始数据); % 原始数据点 hold on; plot(x, y_fit, r-, LineWidth, 2, DisplayName, 拟合直线); % 拟合线 xlabel(x); ylabel(y); title(一元线性最小二乘拟合); legend(show); grid on;polyfit(x, y, n)中的n代表多项式的阶数。n1是直线n2是抛物线以此类推。它返回的是多项式系数从最高次幂到常数项排列。另一种更通用、能直接体现矩阵运算本质的方法是使用反斜杠运算符\求解线性最小二乘问题。对于模型y a*x b我们可以将其写成矩阵形式Y X * Beta其中Beta [a; b]。% 示例2使用矩阵运算\进行线性拟合 x x(:); % 确保是列向量 y y(:); % 构造设计矩阵X。第一列是x对应a第二列是全1对应b X [x, ones(size(x))]; % 使用反斜杠运算符求解最小二乘解 Beta X \ y Beta X \ y; a_matrix Beta(1); b_matrix Beta(2); % 验证结果与polyfit一致 disp([polyfit结果: a, num2str(a), , b, num2str(b)]); disp([矩阵运算结果: a, num2str(a_matrix), , b, num2str(b_matrix)]);注意polyfit在内部也是通过构造范德蒙德矩阵并调用\运算符来求解的。对于简单的一元线性拟合两者等价。但\运算符的矩阵形式更具一般性可以轻松扩展到多元线性回归多个自变量或自定义的线性组合模型。2.3 关键参数与结果解读不只是得到a和b拟合完直线我们至少需要关心三件事拟合优度 R²这个值介于0到1之间越接近1说明直线对数据变异的解释能力越强。polyfit函数本身不直接返回R²但计算很简单。残差每个数据点的观测值y_i与拟合值y_fit_i的差。残差的分布能告诉我们模型是否合适是否应为非线性、数据是否存在异方差性等问题。系数的置信区间我们得到的a和b是估计值它们有多可靠Matlab的regress函数需要Statistics and Machine Learning Toolbox或fitlm函数可以提供这些统计信息。% 示例3计算R²和绘制残差图 y_mean mean(y); SS_total sum((y - y_mean).^2); % 总平方和 SS_residual sum((y - y_fit).^2); % 残差平方和 R_squared 1 - SS_residual / SS_total; disp([R² , num2str(R_squared)]); % 绘制残差图 residuals y - y_fit; figure; subplot(1,2,1); plot(x, residuals, bo, MarkerFaceColor, b); xlabel(x); ylabel(残差); title(残差 vs. x); hold on; plot([min(x), max(x)], [0, 0], k--); % 绘制y0参考线 grid on; subplot(1,2,2); histogram(residuals, 10); xlabel(残差); ylabel(频数); title(残差分布直方图);一个健康的残差图应该像“随机散点”一样围绕y0线上下均匀分布没有明显的趋势或规律。如果残差图呈现出喇叭形、弧形等模式说明线性模型可能不合适或者需要考虑加权最小二乘法。3. 当直线不够用非线性拟合的挑战与Matlab工具箱现实世界的数据关系远非直线所能全部描述。生长曲线、衰减曲线、周期波动等都需要非线性模型。非线性拟合的模型形式为y f(x, Beta)其中f是非线性函数Beta是待求参数。例如指数衰减y a * exp(-b*x)或正弦曲线y a * sin(b*x c)。非线性拟合的核心挑战在于其正规方程不再是线性的无法直接求解闭式解。通常需要迭代算法如高斯-牛顿法、Levenberg-Marquardt算法从一个初始猜测值开始逐步逼近最优参数。3.1 选择拟合工具fit函数与曲线拟合器Matlab提供了强大的fit函数和图形化的Curve Fitting Toolbox。对于大多数常见非线性拟合我强烈推荐使用fit函数。% 示例4使用fit函数进行指数衰减拟合 x linspace(0, 5, 50); y 2.5 * exp(-1.3 * x) 0.1 * randn(size(x)); % 生成带噪声的指数衰减数据 % 定义拟合模型类型。exp1代表单指数模型 y a*exp(b*x) ft fittype(exp1); % 进行拟合可以指定初始点 [a_start, b_start] [fitted_curve, gof] fit(x(:), y(:), ft, StartPoint, [2, -1]); % 查看拟合结果 disp(fitted_curve); % 显示拟合公式和参数 disp(gof); % 显示拟合优度统计量包括R² % 绘图 figure; plot(x, y, bo, DisplayName, 原始数据); hold on; plot(fitted_curve, r-, DisplayName, 指数拟合); xlabel(x); ylabel(y); legend(show); title(非线性拟合指数衰减模型);fittype可以指定非常多的内置模型如poly2二次多项式、sin1单正弦、gauss2双高斯等。更强大的是你可以使用自定义公式字符串。% 示例5使用自定义公式进行拟合幂律关系 y a * x^b x_custom [1, 2, 3, 4, 5]; y_custom [1.1, 3.8, 8.9, 15.5, 25.2]; % 大致符合 y x^2 % 定义自定义模型power1 是内置的这里演示自定义字符串 custom_ft fittype(a * x^b, independent, x, dependent, y); [custom_fit, custom_gof] fit(x_custom(:), y_custom(:), custom_ft, StartPoint, [1, 2]); disp(custom_fit);实操心得非线性拟合成功的关键一是模型选择要合理基于物理背景或数据散点图形状二是初始值要给得好。一个糟糕的初始值可能导致算法收敛到局部最优解甚至发散。图形化工具Curve Fitting Tool在命令窗口输入cftool非常适合用来探索数据、尝试不同模型和初始值直观又方便。确定好模型和大致参数后再用fit函数写入脚本进行批量或自动化处理。3.2 深入算法核心lsqcurvefit与lsqnonlin当你需要更底层的控制或者你的模型函数无法用简单字符串表示时例如模型是一个复杂的.m函数文件lsqcurvefit和lsqnonlin这两个优化工具箱的函数是你的利器。它们直接解决了非线性最小二乘问题。% 示例6使用lsqcurvefit拟合自定义复杂函数 % 假设模型为y p1 * sin(p2*x p3) * exp(-p4*x) x_data linspace(0, 10, 100); p_true [2, 1.5, 0.5, 0.2]; % 真实参数 [振幅, 频率, 相位, 衰减系数] y_data p_true(1) * sin(p_true(2)*x_data p_true(3)) .* exp(-p_true(4)*x_data); y_data y_data 0.1 * randn(size(y_data)); % 加入噪声 % 步骤1定义模型函数作为一个独立的函数句柄或文件 my_model (p, x) p(1) * sin(p(2)*x p(3)) .* exp(-p(4)*x); % 步骤2给出参数初始猜测值。这里我们故意给一个偏离真实值但不太远的猜测。 p0 [1.8, 1.0, 0.0, 0.1]; % 初始猜测 % 步骤3设置优化选项可选但推荐 options optimoptions(lsqcurvefit, Display, iter, MaxFunctionEvaluations, 2000); % Display, iter 会显示迭代过程便于调试。 % 步骤4调用lsqcurvefit [p_opt, resnorm, residual, exitflag, output] lsqcurvefit(my_model, p0, x_data, y_data, [], [], options); % 后两个空数组[]是参数的下界和上界约束这里不设约束。 disp(优化得到的参数); disp(p_opt); disp(真实参数); disp(p_true); % 计算拟合值并绘图 y_fit_lsq my_model(p_opt, x_data); figure; plot(x_data, y_data, bo, DisplayName, 带噪数据); hold on; plot(x_data, y_fit_lsq, r-, LineWidth, 2, DisplayName, lsqcurvefit拟合); xlabel(x); ylabel(y); legend(show); title(使用lsqcurvefit进行复杂非线性拟合);lsqcurvefit要求模型函数的形式是y fun(p, x)其中p是参数向量。lsqnonlin则更通用它要求你提供一个返回残差向量观测值-模型值的函数。对于纯最小二乘问题两者本质相通lsqcurvefit接口更直观。踩坑提醒使用这些迭代算法时务必关注输出信息中的exitflag退出标志。exitflag 0通常表示收敛成功。如果exitflag 0可能是迭代次数不够、函数评估次数超限、或者初始值太差导致无法收敛。此时需要调整options如增加MaxIterations或改进初始猜测。4. 拟合质量的“照妖镜”模型评估与诊断拟合出一条曲线远不是终点。你怎么知道这条曲线不是“过拟合”或者“欠拟合”怎么判断模型真的抓住了数据规律这就需要一套评估和诊断工具。4.1 量化指标不止看R²R²决定系数是最常用的指标但它有局限性。对于非线性拟合有时更关注调整后的R²、均方根误差RMSE或赤池信息准则AIC。RMSE衡量拟合值与观测值之间的平均差异单位与y相同非常直观。越小越好。AIC在比较多个不同复杂度的模型时特别有用。AIC值越小模型在拟合优度和简洁性之间权衡得越好。Matlab的fit函数返回的gof结构体就包含了sse误差平方和、rsquareR²、dfe自由度、adjrsquare调整R²、rmse等。对于lsqcurvefit我们可以手动计算。% 接示例6计算RMSE和R² SSE sum((y_data - y_fit_lsq).^2); % 误差平方和即resnorm RMSE sqrt(SSE / length(y_data)); % 均方根误差 y_mean_data mean(y_data); SST sum((y_data - y_mean_data).^2); % 总平方和 R2_lsq 1 - SSE / SST; disp([RMSE , num2str(RMSE)]); disp([R² , num2str(R2_lsq)]);4.2 图形化诊断残差分析是王道数字指标可能掩盖问题图形诊断则一目了然。我们之前看过残差vs.x的图这里再强调几个关键诊断图残差 vs. 拟合值图检查残差是否随机分布以及是否存在“异方差”残差方差随拟合值增大而改变。正态概率图Q-Q图检查残差是否近似服从正态分布。许多统计推断如参数置信区间基于正态假设。自相关图如果数据是时间序列需要检查残差是否存在自相关。独立的残差是许多模型的前提。% 示例7综合诊断图以lsqcurvefit结果为例 residuals_lsq y_data - y_fit_lsq; fitted_values y_fit_lsq; figure; % 子图1残差 vs. 拟合值 subplot(2,2,1); plot(fitted_values, residuals_lsq, o); xlabel(拟合值); ylabel(残差); title(残差 vs. 拟合值); hold on; plot([min(fitted_values), max(fitted_values)], [0,0], k--); grid on; % 子图2残差 vs. 数据序号适用于非时序数据检查顺序相关性 subplot(2,2,2); plot(1:length(residuals_lsq), residuals_lsq, o-); xlabel(数据序号); ylabel(残差); title(残差 vs. 序号); hold on; plot([1, length(residuals_lsq)], [0,0], k--); grid on; % 子图3残差直方图 正态分布曲线 subplot(2,2,3); histfit(residuals_lsq, 15); % histfit是统计工具箱函数 xlabel(残差); ylabel(频数); title(残差分布); % 子图4正态概率图Q-Q图 subplot(2,2,4); qqplot(residuals_lsq); % qqplot是统计工具箱函数 title(残差Q-Q图); grid on;理想的诊断图应显示残差随机分布在0线上下无趋势直方图近似钟形Q-Q图上的点大致落在对角线上。如果出现系统性的偏离如残差呈漏斗形、弧形Q-Q图严重偏离对角线则说明模型可能误设或需要数据变换。4.3 过拟合与欠拟合在复杂与简单间走钢丝这是建模中的永恒矛盾。欠拟合模型过于简单无法捕捉数据中的潜在规律。表现为训练数据上R²低残差大且有明显趋势。过拟合模型过于复杂不仅拟合了规律还拟合了噪声。表现为训练数据上R²很高但对新的、未见过的数据预测能力很差。对于多项式拟合polyfit的阶数n选择就是典型的权衡。如何选择一个实用的方法是使用交叉验证。将数据分为训练集和验证集用训练集拟合不同阶数的模型在验证集上测试其预测误差如RMSE选择验证误差最小的模型。% 示例8通过交叉验证选择多项式阶数简易演示 x_all rand(100,1)*10; % 100个随机x y_all 2 1.5*x_all - 0.3*x_all.^2 0.02*x_all.^3 2*randn(size(x_all)); % 三次多项式加噪声 % 随机划分80%训练20%验证 rng(1); % 设定随机种子使结果可重复 train_ratio 0.8; n_total length(x_all); n_train floor(train_ratio * n_total); idx_rand randperm(n_total); idx_train idx_rand(1:n_train); idx_val idx_rand(n_train1:end); x_train x_all(idx_train); y_train y_all(idx_train); x_val x_all(idx_val); y_val y_all(idx_val); max_degree 6; % 尝试1到6阶 val_rmse zeros(max_degree, 1); for degree 1:max_degree p polyfit(x_train, y_train, degree); y_val_pred polyval(p, x_val); val_rmse(degree) sqrt(mean((y_val - y_val_pred).^2)); end % 找到验证集RMSE最小的阶数 [~, best_degree] min(val_rmse); disp([交叉验证建议的最佳多项式阶数为, num2str(best_degree)]); figure; plot(1:max_degree, val_rmse, bo-, LineWidth, 2, MarkerFaceColor, b); xlabel(多项式阶数); ylabel(验证集RMSE); title(交叉验证选择模型复杂度); grid on; hold on; plot(best_degree, val_rmse(best_degree), r*, MarkerSize, 15);这个例子中如果真实模型是三次多项式加噪声那么通常3阶或4阶的验证误差会最小。阶数再高虽然训练误差可能继续下降但验证误差会开始上升这就是过拟合的信号。5. 进阶议题与实战避坑指南掌握了基本方法后在实际项目中还会遇到一些棘手问题。这里分享几个常见的“坑”和应对策略。5.1 数据预处理尺度问题与异常值尺度问题如果模型参数的数量级差异巨大例如一个参数是0.001另一个是10000很多迭代算法会收敛缓慢甚至失败。解决方案是进行数据标准化或归一化。对于自变量x可以减去均值除以标准差对于参数可以尝试给一个数量级相近的初始值或使用算法提供的缩放选项。异常值最小二乘法对异常值非常敏感一个偏离很远的点能把拟合线“拉”过去。此时可以考虑使用稳健回归方法如Matlab的robustfit函数针对线性模型或fit函数中的Robust选项如LAR最小绝对残差或Bisquare权重函数。% 示例9使用稳健拟合对抗异常值 x_clean 1:10; y_clean 2*x_clean 1 randn(1,10)*0.5; % 干净数据 % 加入一个异常点 x_outlier [x_clean, 5.5]; y_outlier [y_clean, 25]; % 在x5.5处y突然跳到25 % 普通最小二乘拟合 p_ols polyfit(x_outlier, y_outlier, 1); y_fit_ols polyval(p_ols, x_outlier); % 稳健拟合使用fit函数的Robust选项 ft_linear fittype(poly1); [fit_robust, ~] fit(x_outlier(:), y_outlier(:), ft_linear, Robust, Bisquare); coeff_robust coeffvalues(fit_robust); % 获取稳健拟合的系数 y_fit_robust coeff_robust(1)*x_outlier coeff_robust(2); figure; plot(x_outlier, y_outlier, ko, MarkerSize, 8, DisplayName, 数据含异常点); hold on; plot(x_outlier, y_fit_ols, b--, LineWidth, 1.5, DisplayName, 普通最小二乘); plot(x_outlier, y_fit_robust, r-, LineWidth, 2, DisplayName, 稳健拟合Bisquare); xlabel(x); ylabel(y); legend(show, Location, northwest); title(异常值对拟合的影响及稳健拟合效果); grid on;可以看到普通最小二乘的直线被异常点严重拉偏而稳健拟合的直线则基本忽略了异常点更贴近大多数数据点的趋势。5.2 参数约束与边界设定有时根据物理意义或先验知识我们知道参数应该在一定范围内。例如衰减系数必须为正浓度不能为负。lsqcurvefit和fit函数都支持设置参数上下界。% 示例10为拟合参数设置边界lsqcurvefit % 沿用示例6的模型和初始猜测 lb [0, 0, -pi, 0]; % 下界振幅0频率0相位无限制这里设了-pi衰减系数0 ub [5, 5, pi, 1]; % 上界 [p_opt_bounded, ~] lsqcurvefit(my_model, p0, x_data, y_data, lb, ub, options); disp(带约束的优化参数); disp(p_opt_bounded);在fit函数中可以通过fitoptions来设置。% 示例11为fit函数设置参数边界和算法选项 fo fitoptions(Method, NonlinearLeastSquares, ... Lower, [0, 0, -inf, 0], ... % 对应[a,b,c,d]的下界 Upper, [5, 5, inf, 1], ... % 上界 StartPoint, p0); custom_ft_bounded fittype(a*sin(b*x c)*exp(-d*x), options, fo); [fit_bounded, ~] fit(x_data(:), y_data(:), custom_ft_bounded);5.3 拟合函数的“黑盒”调试输出迭代信息当拟合不收敛或结果奇怪时打开算法的“黑盒”查看迭代过程非常有用。通过设置optimoptions的Display为iter可以看到每次迭代的参数值、函数值残差平方和和步长帮助你判断是初始值太差、模型不对还是需要调整算法参数如增大最大迭代次数MaxIterations。options_verbose optimoptions(lsqcurvefit, Display, iter, ... MaxIterations, 400, ... FunctionTolerance, 1e-10, ... StepTolerance, 1e-10); % 然后调用lsqcurvefit时传入options_verbose观察输出如果函数值First-Order Optimality在持续下降但很慢可能需要更多迭代。如果几乎不下降可能已收敛或陷入平台。如果出现NaN或Inf检查模型函数中是否有非法运算如对负数开平方、除以零。5.4 从拟合到预测置信区间与预测区间得到拟合参数后我们往往想预测新x对应的y值。但预测有两个层次均值置信区间给定x预测y的平均值的波动范围。它反映了模型参数不确定性导致的均值波动。预测区间给定x预测单个新观测值y的波动范围。它比置信区间更宽因为它额外包含了数据本身的随机误差残差。Matlab的predint函数需要Curve Fitting Toolbox可以方便地计算预测区间。% 示例12计算并绘制预测区间基于fit对象 % 使用示例4的指数拟合结果 fitted_curve x_new linspace(0, 6, 100); [ypred, yci] predict(fitted_curve, x_new); % predict函数也可以 % 或者使用 predint (语法略有不同注意查看文档) % yci predint(fitted_curve, x_new, 0.95, observation, off); % 均值置信区间 % ypi predint(fitted_curve, x_new, 0.95, observation, on); % 预测区间 figure; plot(x, y, bo, DisplayName, 原始数据); hold on; plot(fitted_curve, r-, DisplayName, 拟合曲线); % 绘制置信区间带 plot(x_new, yci(:,1), k--, DisplayName, 95% 预测区间下限); plot(x_new, yci(:,2), k--, DisplayName, 95% 预测区间上限); % 可以用fill函数填充区间更美观 % fill([x_new; flipud(x_new)], [yci(:,1); flipud(yci(:,2))], k, FaceAlpha, 0.1, EdgeColor, none); xlabel(x); ylabel(y); legend(show); title(拟合曲线及其预测区间); grid on;理解这两个区间的区别至关重要。如果你要预测的是“过程平均值”比如一批产品的平均寿命看置信区间。如果你要预测“下一个单个产品的寿命”看预测区间因为它考虑了单个观测的随机波动。6. 工程实践中的综合案例传感器温度补偿最后我们用一个接近真实工程的例子来串联以上所有知识点对温度传感器的输出进行非线性补偿以得到更精确的温度读数。场景某温度传感器的输出电压V与温度T的关系近似满足V a / (T b) c这是一个常见的非线性传感器模型。我们通过标定实验获得了一系列(T_true, V_measured)数据对目标是拟合出参数[a, b, c]从而在后续测量中根据测得的V反算出温度T。步骤与思考数据准备与可视化首先加载标定数据绘制V关于T的散点图确认非线性关系符合预期模型。% 假设已有数据 T_calib 和 V_calib figure; plot(T_calib, V_calib, o); xlabel(真实温度 T (°C)); ylabel(传感器输出电压 V (V)); title(传感器标定数据); grid on;模型选择与拟合根据物理背景选择模型V a / (T b) c。使用fit函数进行非线性拟合。关键点在于初始值设定。观察数据当T很大时V趋近于c可以粗略估计c。然后选取两个点代入方程估算a和b。% 定义模型。注意这里T是自变量V是因变量。 sensor_model fittype(a/(x b) c, independent, x, dependent, y); % 估算初始值假设高温时V约等于c取最后几个点的V平均值作为c0 c0 mean(V_calib(end-4:end)); % 选取两个数据点例如最小和中间温度点来估算a和b T1 T_calib(1); V1 V_calib(1); T2 T_calib(round(end/2)); V2 V_calib(round(end/2)); % 解方程组 V1 a/(T1b)c0, V2 a/(T2b)c0 来估算a0,b0 (这里简化可用试错法) % 更稳妥的方法是直接在cftool中手动调整或给一个合理的数量级猜测。 a0 1000; b0 200; % 示例猜测值实际需根据数据调整 start_point [a0, b0, c0]; opts fitoptions(sensor_model); opts.StartPoint start_point; opts.Lower [0, 0, -inf]; % a,b应为正数 opts.Upper [inf, inf, inf]; [fit_result, gof] fit(T_calib(:), V_calib(:), sensor_model, opts); disp(fit_result); disp(gof);模型诊断绘制拟合曲线与原始数据对比图计算并分析残差。检查残差是否随机、无趋势。如果R²很高且残差图健康则模型可接受。应用模型进行温度反算拟合得到的是V f(T)但我们需要的是T f^{-1}(V)。对于这个模型可以解析求逆T a/(V - c) - b。coeffs coeffvalues(fit_result); a_fit coeffs(1); b_fit coeffs(2); c_fit coeffs(3); % 定义一个函数根据测量的电压V计算温度T calc_T_from_V (V) a_fit ./ (V - c_fit) - b_fit; % 验证用标定数据本身验证反算精度 T_calculated calc_T_from_V(V_calib); error T_calculated - T_calib; max_abs_error max(abs(error)); rmse_error sqrt(mean(error.^2)); disp([最大绝对误差, num2str(max_abs_error), °C]); disp([RMSE, num2str(rmse_error), °C]); figure; subplot(2,1,1); plot(T_calib, error, o-); xlabel(真实温度 (°C)); ylabel(计算误差 (°C)); title(温度反算误差 vs. 真实温度); grid on; subplot(2,1,2); histogram(error, 20); xlabel(计算误差 (°C)); ylabel(频数); title(误差分布直方图);不确定性评估利用predint或nlpredci非线性预测置信区间函数可以计算在给定电压V下反算温度T的置信区间为测量结果提供精度说明。这个案例涵盖了从数据观察、模型选择、参数拟合、诊断验证到实际应用的全流程。其中初始值估计和模型诊断是确保成功的关键。在实际操作中可能需要反复调整模型或初始值直到获得物理意义合理、统计特性良好的结果。拟合算法不是魔法它是一套强大的数学工具但工具的价值取决于使用者的判断。理解数据背景、选择合适的模型、谨慎评估结果这三者结合才能让拟合真正服务于科学发现和工程实践。Matlab提供的丰富函数和工具箱极大地降低了实现门槛让我们能把更多精力集中在“判断”而非“编程”上。希望这些从实战中总结的经验能帮助你在下次面对一堆数据点时更加从容地找到那条隐藏的规律曲线。
返回列表