MATLAB 数据拟合¶
数据拟合是工程和科学分析中的一项基本任务,其目的是找到一个数学模型(通常是一个函数)来最佳地描述一组观测数据点。MATLAB 提供了从交互式工具到高级编程函数的全方位支持,能够处理从简单的线性回归到复杂非线性模型的各种拟合问题。
交互式拟合工具¶
Curve Fitter App (cftool) - 图形化曲线拟合工具¶
- 功能 对于快速的数据探索和模型比较,曲线拟合 App (Curve Fitter) 是最高效的选择。它提供了一个完整的图形化界面,让你无需编写代码即可尝试多种模型、评估拟合质量并导出结果。
- 启动方式
- 在 MATLAB App 选项卡中,找到并点击 Curve Fitter 图标。
- 在命令行窗口中输入
cftool。
- 核心优势
- 无需编程: 完全通过图形界面操作。
- 模型丰富: 内置大量常用拟合模型库(多项式、指数、高斯、傅里叶级数等)。
- 实时反馈: 调整参数或模型后,拟合曲线和拟合优度统计数据会立即更新。
- 代码生成: 完成拟合后,可以自动生成 MATLAB 函数来复现整个拟合过程,便于自动化处理。
- 示例
核心编程函数¶
polyfit - 拟合多项式曲线¶
- 功能
找到一个
n阶多项式的系数,使其在最小二乘意义下最佳地拟合一组给定的(x, y)数据点。 -
数学原理: 最小二乘法 (Least Squares Method)
polyfit旨在找到一组多项式系数 \(\bm{p} = [p_1, p_2, \dots, p_{n+1}]\),使得模型预测值 \(y_\mr{model}(x_i) = p_1 x_i^n + p_2 x_i^{n-1} + \dots + p_{n+1}\) 与实际观测值 \(y_i\)(共 \(m\) 个数据)之间的残差平方和 (Sum of Squared Residuals, SSR) 最小:\[ \min_{\bm{p}} \sum_{i=1}^{m} \left[ y_i - y_\mr{model}(x_i) \right]^2 \]这是一个可以通过求解线性方程组 \(A^T A \bm{p} = A^T \mathbf{y}\) (正规方程) 来精确解决的问题。
-
语法
-
语法说明
p = polyfit(x, y, n): 返回一个行向量p,其中包含n阶多项式的系数,按降幂排列。S: 返回一个结构体,用于polyval计算误差估计。mu: 返回一个二元向量[mean(x), std(x)],用于中心化和缩放数据,以提高拟合的数值稳定性。
-
示例
% 1. 生成带噪声的数据 x = linspace(0, 4*pi, 10); y = sin(x) + 0.15*randn(size(x)); % 2. 使用 3 阶多项式进行拟合 p = polyfit(x, y, 3); % p 是一个包含 4 个多项式系数的向量 % 3. 在更密集的点上评估拟合出的多项式 (需要 polyval) x_fit = linspace(0, 4*pi, 100); y_fit = polyval(p, x_fit); % 4. 绘图 figure; plot(x, y, 'ro', 'DisplayName', '原始数据'); hold on; plot(x_fit, y_fit, 'b-', 'LineWidth', 2, 'DisplayName', '3阶多项式拟合'); legend; title('polyfit 和 polyval 示例');
polyval - 评估多项式函数值¶
- 功能
与
polyfit配套使用,计算由系数向量p定义的多项式在指定x值处的函数值。 - 语法
-
语法说明
y = polyval(p, x): 计算多项式在x处的值。[y, delta] = polyval(p, x, S):S是polyfit返回的结构体,delta是 50% 置信区间的预测误差。
-
示例 (见
polyfit示例)
fit - 通用曲线拟合¶
-
功能 最强大、最推荐的通用拟合函数 (需要 Curve Fitting Toolbox)。它支持大量的库模型(如多项式、高斯、指数、傅里叶级数等),并且可以轻松地拟合用户定义的非线性方程。
-
数学原理
fit函数根据指定的模型类型,使用不同的优化算法来最小化模型与数据之间的残差平方和。- 线性模型: 使用线性最小二乘法。
- 非线性模型: 使用非线性最小二乘算法,如信赖域 (Trust-Region) 算法或 Levenberg-Marquardt 算法。这需要用户提供参数的初始猜测值 (StartPoint)。
-
语法
-
语法说明
fitresult: 一个cfit(曲线) 或sfit(曲面) 对象,包含了所有拟合结果。fitType: 指定模型类型。可以是库模型名称的字符串(如'poly2','exp1','gauss1'),也可以是一个由fittype创建的自定义模型对象。gof: 一个包含拟合优度统计量(如 R-square, SSE, RMSE)的结构体。fitOptions: 一个由fitoptions函数创建的选项对象,用于设置算法、初始值等。
-
示例 (自定义非线性拟合)
% 1. 生成带噪声的数据 x = (0:0.1:5)'; y = 2*exp(-0.5*x) + 0.2*randn(size(x)); % 2. 使用 fittype 定义自定义拟合模型 % fittype 定义模型方程,'a', 'b' 是待拟合参数 ft = fittype('a*exp(-b*x)', 'independent', 'x', 'dependent', 'y'); % 3. 使用 fitoptions 设置算法选项,如起始点 opts = fitoptions('Method', 'NonlinearLeastSquares'); opts.StartPoint = [1 1]; % 猜测 a=1, b=1 % 4. 使用 fit 函数进行拟合 [fitresult, gof] = fit(x, y, ft, opts); % 5. 显示和绘制结果 disp('拟合结果:'); disp(fitresult); disp('拟合优度 (R-square):'); disp(gof.rsquare); figure; plot(fitresult, x, y); % cfit 对象可以直接绘制 legend('原始数据', '拟合曲线'); title('fit 函数自定义模型拟合');
fittype - 创建自定义拟合模型¶
-
功能 与
fit配套使用,通过一个字符串或匿名函数来定义一个可重用的拟合模型,特别是对于非线性方程。 -
语法
-
示例 (见
fit示例)
lsqcurvefit - 非线性最小二乘拟合¶
-
功能 求解非线性曲线拟合(最小二乘)问题 (需要 Optimization Toolbox)。它专门用于寻找参数 \(\bm{p}\),使得用户定义的函数 \(F(x, \bm{p})\) 与观测数据 \(y\)(\(m\) 个数据)的残差平方和最小。
\[ \min_{\bm{p}} \sum_{i=1}^{m} \left[ F(x_i, \bm{p}) - y_i \right]^2 \] -
数学原理
lsqcurvefit使用迭代优化算法(如信赖域反射算法)来求解。从一个初始猜测值 \(\bm{p}_0\) 开始,算法在每一步迭代中寻找一个能使残差平方和下降的方向和步长,直到满足收敛条件。 -
语法
-
语法说明
fun: 一个函数句柄,形如@(p, xdata),它接受参数p和自变量xdata,并返回模型预测值。p0: 参数的初始猜测值向量。xdata,ydata: 观测数据。lb,ub: 参数的下界和上界(可选)。options: 优化选项(可选)。
-
示例
% 1. 定义要拟合的函数模型 % p(1) -> a, p(2) -> lambda model_fun = @(p, x) p(1) * x .* exp(-p(2)*x); % 2. 生成带噪声的数据 x_data = linspace(0, 5, 50); p_true = [3, 2]; % 真实参数 y_data = model_fun(p_true, x_data) + 0.1*randn(size(x_data)); % 3. 提供参数的初始猜测值 p0 = [1, 1]; % 4. 调用 lsqcurvefit p_fit = lsqcurvefit(model_fun, p0, x_data, y_data); % 5. 绘图比较 y_fit = model_fun(p_fit, x_data); figure; plot(x_data, y_data, 'ko', 'DisplayName', '原始数据'); hold on; plot(x_data, y_fit, 'r-', 'LineWidth', 2, 'DisplayName', 'lsqcurvefit 拟合'); legend; title('lsqcurvefit 示例'); disp('拟合出的参数 [a, lambda]:'); disp(p_fit);