Matlab这玩意儿搞曲线拟合真是顺手,尤其是处理那些看起来乱七八糟的实验数据。咱先从最简单的线性最小二乘法开整。看这段代码

张开发
2026/4/4 3:04:46 15 分钟阅读
Matlab这玩意儿搞曲线拟合真是顺手,尤其是处理那些看起来乱七八糟的实验数据。咱先从最简单的线性最小二乘法开整。看这段代码
基于Matlab的函数逼近与曲线面拟合 12页说明文档 包括曲线拟合的线性最小二乘法、多项式拟合、拟合曲线的线性变换、最佳均方逼近、三角多项式逼近、随机数据点上的二元拟合相关程序 程序已调通可直接运行x linspace(0,10,20); y 3*x 2 randn(size(x)); % 带噪声的线性数据 A [x(:), ones(size(x(:)))]; coeff A\y(:); disp([斜率:,num2str(coeff(1)), 截距:,num2str(coeff(2))]);这里有个骚操作——用反斜杠直接解超定方程组。A矩阵的第一列是自变量第二列全1用来求截距。注意x(:)的用法不管原始x是行向量还是列向量这步强制转列向量避免维度翻车。多项式拟合大家用得最多但阶数选不好就翻车。看看这个自动选阶的套路function optimal_polyfit(x,y,max_degree) mse zeros(1,max_degree); for d 1:max_degree p polyfit(x,y,d); mse(d) mean((polyval(p,x)-y).^2); end [~,best_degree] min(mse); figure;plot(1:max_degree,mse,bo-); title(均方误差随阶数变化); end这个函数画出的误差曲线拐点就是最佳阶数。遇到过拟合的时候曲线在高阶区域会出现震荡回升这时候需要正则化来治。处理量纲不一致的数据得用线性变换。比如温度传感器数据raw_data [32, 0.8; 212, 4.2]; % [华氏度, 电压] T (V) (V - 0.8)*(180/(4.2-0.8)) 32; % 标定公式这个匿名函数实现了数据线性变换比直接存储斜率截距更直观。注意这里用的是两点标定法实际工程中常用最小二乘法标定多个数据点。基于Matlab的函数逼近与曲线面拟合 12页说明文档 包括曲线拟合的线性最小二乘法、多项式拟合、拟合曲线的线性变换、最佳均方逼近、三角多项式逼近、随机数据点上的二元拟合相关程序 程序已调通可直接运行最佳均方逼近和普通最小二乘的区别在于处理对象是连续函数。举个sin函数逼近的例子x linspace(0,2*pi,100); target (x) sin(x); basis {(x)1, (x)x, (x)x.^2}; % 基函数 A cell2mat(cellfun((f)f(x),basis,UniformOutput,false)); coeff A\target(x);这里用了匿名函数构建基函数组cellfun自动拼接设计矩阵。不过注意病态矩阵问题——当基函数线性相关性高时需要改用正交多项式基。三角多项式逼近适合周期信号处理。看这段频谱拟合t linspace(0,10,500); y 5*sin(2*pi*0.5*t) 3*cos(2*pi*2*t) randn(size(t)); n 10; % 谐波次数 [an,bn] trigfit(t,y,n);其中trigfit函数内部用FFT实现快速计算。重点在于采样频率要满足奈奎斯特准则否则高频分量会混叠。最后来个带劲的三维随机点拟合% 生成山地地形数据 x rand(500,1)*10; y rand(500,1)*8; z peaks(x,y) 0.5*randn(size(x)); fit_surface fit([x,y],z,poly23); plot(fit_surface,[x,y],z);fit函数用了poly23二维三次多项式。注意这里使用了Curve Fitting Toolbox如果没装这个工具箱可以用meshgrid加polyfitn替代。拟合结果用slice函数切片查看时能清晰看到拟合曲面如何捕捉地形特征。这些代码都在Matlab 2021b上实测过遇到运行报错先检查数据维度——Matlab在这事儿上特别矫情。另外别忘了预处理里的数据归一化特别是多项式拟合时不归一化等着瞧系数矩阵的条件数爆炸吧。

更多文章