作者的话:
众所周知,有个神器名叫Matlab。
Matlab可以有很多应用,此处主要介绍智能仿真。
还是挺好用的,个人建议通过例程来进行学习,留意注释哦
多项式拟合,就是在得知两组数据具有相关性的前提下,通过多项式曲线(次数需要自己自行调整),来拟合原始数据。
多项式次数过高:拟合速度慢,电脑运算时间长。在此例中,会发现,三次和四次的拟合效果差不多,那我们采用的就应该是三次。
多项式次数过低:拟合效果差,得不到想要的多项式拟合效果。在此例中,会发现,一次拟合严重不符合原始数据,就是拟合次数过低的体现。
相关性验证:用corrcoef(x,y)得到相关性矩阵,其中x,y都应该是矩阵,数值越接近1相关性越高
以下为代码:
%%针对matlab提供的census.mat数据文件,将其中的数据进行多项式拟合,
clear;clc; %清屏,初始化
load census.mat %导入数据
%计算样本的相关系数矩阵,并画散点图,证明二者有较强的相关性
subplot(3,3,1); %开启绘图窗口,创建9个子图,当前操作第一个子图
scatter(cdate,pop,'om') %用散点图的方式显示原始数据,用品红色的o标注
title('U.S. Population from 1790 to 1990'); %给图形窗口写一个标题
xlabel('Census Year'); %给x轴命名
ylabel('Population (millions)'); %给y轴命名
corrcoef(cdate,pop); %相关性矩阵
sdate=(cdate-mean(cdate))./std(cdate); %样本数据标准化
%根据不同的拟合次数先画拟合图和残差图,以选择合适的模型
k=2; %从第二个子图开始操作
for i=1:4 %循环,设置不同拟合次数
t=polyfit(sdate,pop,i); %拟合系数矩阵
fit_y=polyval(t,sdate); %计算y的拟合值
subplot(3,3,k);%操作第k个子图
k=k+1; %操作下一个子图
plot(cdate,fit_y,'+-',cdate,pop,'om'); %显示拟合后的线和原数据
title('U.S. Population from 1790 to 1990')
legend('Polynomial Model','Data','Location','NorthWest');
xlabel('Census Year');
ylabel('Population (millions)');
hold off;
subplot(3,3,k);%操作第k个子图
k=k+1; %操作下一个子图
res = pop - fit_y; %计算拟合值与原数据的差
plot(cdate,res,'+m') %可视化残差
title(['Residuals for the Quadratic Polynomial Model(n=',num2str(i),')’]); %给不同的子图显示标题
end %结束循环标志
t=polyfit(sdate,pop,3); %计算3次拟合的残差和拟合优度,polyfit返回的是不同次方项的系数矩阵
fit_y=polyval(t,sdate); %拟合后的y值,将系数矩阵与对应的y按次方相乘
yresid = pop - fit_y;
SSresid = sum(yresid.^2);
SStotal = (length(pop)-1) * var(pop);
rsq = 1 - SSresid/SStotal %最小二乘法计算平方误差,公式在最后的tips中
运行结果:
观察数据曲线和残差图,可以得出三次多项式拟合得很不错了
所以得到的多项式为:
tips:
- Matlab的安装可以在网上或者淘宝上找资源,请预留相当大的内存空间
- %为Matlab中的注释标志
- Matlab有命令行和脚本两种,以上所给出的完整代码放入复制到脚本中可以运行。但是也可以一行一行在命令行中运行,更方便观察。
- census.mat是Matlab自带的,直接引用就行。
- 在Matlab命令行中,语句结束带;就不会显示运行结果,所以如果大家要在命令行中一行一行尝试的话,记得把末尾的;删去。
- 记得标准化数据(自变量x)
- 最后记得运算残差,用最小二乘法。公式为