本篇算是开始数据处理了。首先明确俩概念:插值和拟合。两者最根本的共同点都是基于现有数据进行预测、推演,比如根据现有的天文观测数据预测天体位置。插值问题是数学史上的经典问题,拉格朗日、高斯、牛顿等著名数学家均有所研究。
插值的定义是:
在离散数据的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点。
插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。
%图像处理时也有“插值”:用来填充图像变换时像素之间的空隙。
说实话一开始我并没想通这个插值中的“插”是怎么回事,interpolation,前边inter是个插,后边polation是个“极”,在电线杆子间搭电线可不太妙……安利一个形象的起搏:生长着的树叶。
叶脉中的主叶脉就好比是自变量轴,那些一级支脉就好比是离散着的数据,它们描摹出一个大致的连续边缘,这个边缘就好比是插补进去的的连续函数,假设在叶子的继续生长过程中,边缘是相似的成比例放大,则可以根据叶子的边缘预测下一个叶脉的相对长短。
我们高中时就用过拟合,比如验证牛顿第二定律的描点连线,拟合得到的函数表达式即与牛顿第二定律相一致,不必经过每个数据点,因为微扰是常态,诚如伽利略所言“懂得忽略什么与懂得重视什么同样重要”。
MATLAB有插值库函数interp,语法如下:
讲义上给出了预测体温的示例:
hours=1:12;
temps=[5 8 9 15 25 29 31 30 22 25 27 24];
h=1:0.1:12;
t=interp1(hours,temps,h,'spline');
plot(hours,temps,'+',h,t,hours,temps,'r:')
% 作图,原散点数据用+标记
xlabel('Hour'),ylabel('Degrees Celsius')
运行后:
如图,曲线经过了每个数据点。
interp2就是2维的插值,即已知数据点(x,y)组成规则的矩阵(或称之为栅格),可使用meshgrid生成。另外,我觉得优先级更高的是griddata函数,它不要求数据规则排列,∴对随机无规律数据进行插值具有很好的效果。
话说我觉得拟合优先级更高,因为建模是建个规律性的玩意,描述趋势或规律拟合比插值强
拟合的时候是默认样本中已经包含噪声,因此不追求拟合曲线通过每一个数据点,衡量拟合数据的标准则是整体数据拟合的误差最小。一般情况下,MATLAB的曲线拟合方法用的是“最小方差”函数,比如polyfit函数。
ployfit(x,y,n)是找到次数为n的多项式系数,对于数据集合{(xi,yi)},满足最小平方差,讲义示例
x0=[1949 1954 1959 1964 1969 1974 1979 1984 1989 1994];%年份
y0=[5.4 6.0 6.7 7.0 8.1 9.1 9.8 10.3 11.3 11.8];%对应年份人口
a=polyfit(x0,y0,1); % 线性拟合
x1=[1949:0.5:1994];
y1=polyval(a,x1);%多项式拟合即:y1 = a(1)*x1 + a(2);
y1_=polyval(a,)
b=polyfit(x0,log(y0),1); % 指数函数拟合
y2=exp(b(2))*exp(b(1)*x1);
y2_=exp(b(2))*exp(b(1)*)
plot(x0,y0,'*')
hold on
plot(x1,y1,'--r')
hold on
plot(x1,y2,'-k')
legend('原数据散点图','线性拟合曲线','指数拟合曲线')
为啥最小二乘法最常见呢?我的直觉是能量(振幅的平方)最小作用原理,噪声就是振动,没有噪声就没有振动没有误差,则是完全准确的拟合。至于证明,我现在不会也不想会~
言归正传,我觉得线性拟合里边多元线性拟合的优先级高,建模肯定得建不少变量,讲义示例
food=[1.5 2 3 4.5 7.5 9.1 10.5 12];
n=length(food);
x=[ones(n,1), food'];
y=[5.6 6.6 7.2 7.8 10.1 10.8 13.5 16.5]';
[b,bint,r,rint,stat] = regress(y,x,0.05)
%regress函数语法:
然后是非线性拟合:非线性曲线拟合是已知输入向量xdata、输出向量ydata,而且还知道输入与输出的函数关系为ydata=F(x,xdata),但不清楚系数向量x,MATLAB中可以用函数curvefit。有个问题是非线性的方法多了去了,多到系统说用户你自己写个自定义非线性处理函数吧~
这里的‘fun’就是自定义的函数
这让主程序更简洁一些:
%%%%%%%%%%%%%%%%函数单独存为m文件%%%%%%%%%%%%%%%%%%
function f=curvefun2(x)
tdata=[100:100:1000]'; cdata=1e-03*[4.54,4.99,5.35,5.65,5.90,6.10,6.26,6.39,6.50,6.59]';
f=x(1)+x(2)*exp(-0.02*x(3)*tdata)- cdata;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%主程序:
x0=[0.2,0.05,0.05]';
[x,resnorm,residua]=lsqnonlin('curvefun2',x0)
讲义上还给了适用面更广的通用的非线性拟合函数这里的‘model’也是自定义的‘fun’
我还想提一嘴参数估计函数,参数估计包括点估计和区间估计,我们在概率论学过不少。MATLAB统计工具箱提供了很多与参数估计相关的函数,例如计算待估参数及其置信区间、估计服从不同分布的函数的参数。最常用的是高斯/正态分布进行参数估计——
[muhat,sigmahat,muci,sigmaci]=normfit(x),muhat是μ带帽^,sigimahat是σ带帽^,muci是μ的95%置信区间,sigmaci是σ的95%置信区间。
[muhat,sigmahat,muci,sigmaci]=normfit(x,alpha)进行参数估计并计算100(1-alpha)%置信区间。
其他的分布如β分布、泊松分布、二项分布、指数分布、伽马分布等也输出一个分布的参数估计表的向量。
下边是我觉得优先级最高的操作:MATLAB曲线拟合工具箱。
不过我的cftool和讲义上的截图界面不一太一样,功能应该一样,A=rand(4,4)、线性拟合
文件按钮里有我们想要的操作,比如封装成函数、保存、用figure打印图形等。
如果觉得《matlab插值与拟合例题_菜鸟进阶系列:MATLAB数学建模·数据插值与拟合》对你有帮助,请点赞、收藏,并留下你的观点哦!