【数学建模】——拟合算法
拟合算法定义:与插值问题不同,在拟合问题中不需要曲线一定经过给定的点。拟合问题的目标是寻求一个函数(曲线),使得该曲线在某种准则下与所有的数据点最为接近,即曲线拟合的最好(最小化损失函数)。
插值和拟合的区别:
例子:
此例子中如果用插值算法,因为各点连起来需要的线段过去曲折不方便插值,所以我们可以利用拟合算法解决:
最小二乘法:
(最小二乘法作为我们拟合算法的一个铺垫为后续的检验我们拟合的函数是否符合真实的图形而做基础条件)
拟合值:将原xi代入到拟合的函数中得到的y^.
Matlab代码实现最小二乘法来检验拟合函数:
(这里我们的代码实现是直接自己求k和b再去检验,我们也可以直接传入数据让matlab直接给我们求出来,后面我们讲曲线拟合工具箱时会讲到)
我们构造的函数是y=kx+b
- 传入数据画出散点
- 求出n(行数)利用公式求出k和b
- Hold函数:继续在之前的图形上来画图,grid on函数:显示网格。
- 画出y=kx+b的函数图像
a.利用传统画法模拟生成x,y,y=kx+b,用plot画出
b.利用匿名函数法
匿名函数:在matlab中不能直接定一个含有未定义变量的函数方程,所以需要匿名含来解决此问题.
形式:函数名=@(自定义变量)函数方程
Eg:z=x^2+y^2 (false,xy没有被定义过)
Z=x@(x,y)x^2+y^2(true)。
匿名函数完成后再用fplot函数构图。
Fplot函数:可用于画出匿名一元函数的图像
fplot(函数名,[定义域范围])
eg:f=@(x)k*x+b; fplot(f,[2.5,7]);
如何让评价拟合的好坏?(出列)
拟合优度:到!
对于我们评价拟合的好坏有时需要看R^2(拟合优度),有时需要看SSE(误差)那如何区分什么时候看R^2,什么时候看SSE呢?
R^2只能用于判断线性函数时(此线性分彼线性)
如何让判断函数是否线性:
计算拟合有限度的代码:
MatLab——曲线拟合工具箱
a.位置:
b.也可以在命令行窗口输入cftool运行打开。
在拟合器中点击选择数据,会选择我们编译器中定义的变量,也可以取名字。
输入数据后会自动构建散点图,这样我们再从拟合类型中选择合适的方程或自定义方程(选择后会出拟合的线段,看看是否接近)
函数图像的保存:
- 截图(不清晰)
- 导出:上方由导出->导出为窗口(会形成一个小窗口)->文件->导出设置->(如果为了图像更加清晰可以点击->渲染->分辨率->600)->导出(选择jpg
/png格式)
Matlab拟合工具想生成图像后还可以帮你生成此图像的代码(作为自定义函数形式)
如何讲生成的代码保存的自己的代码中?
导出->生成代码
如何保存?
生成代码后->ctrl+s保存系统会自动以函数名定义问保存的文件名。
我们再把第一行function后面的复制到主函数中就可以应用了。
记得要把第一行后面的一些注释去掉就可以了
(类似这部分)
函数名复制完后我们在应用和的时候只需要在定义一个变量用来存放我们在生成此图像时用到的函数(如何时系统的拟合函数在拟合工具箱会显示),在一些拟合函数中的参数也要定义上。
Eg:
如下图我们输入的时自定义函数,它会自动帮我们求出参数的值
在主函数应用的时候我们需要先把这些参数变量定义出来
自己模拟数据进行演示:
- randi(10,2,5):随机产生一个1-10之间的随机值正数矩阵,每次生成的数都会变
也可以定义随机值的范围:
2.rand函数产生一个0-1之间随机值的矩阵(S3,S4)
- normrnd函数:
- roundn函数:任意位置四舍五入
(在第几为四舍五入,第几位后面的位数全部归0)(四舍五入0.5,5,50,500……)
例题预测美国人口:参考代码:
%主函数
clear;clc
%第一步传入数据
year = 1790 : 10 :2000;
populations = [3.9,5.3,7.2,9.6,12.9,17.1,23.2,31.4,38.6,50.2,62.9,76.0,92.0,106.5,123.2,131.7,150.7,179.3,204.0,226.5,251.4,281.4]
%第二部绘制散点图
plot(year,populations,'o')
%第三步进行拟合函数利用拟合工具箱
cftool;
%拟合完成后生成的自定义函数:
[fitresult, gof] = createFit_American(year, populations)
%第四步定义变量,函数传入要预测的年份,绘制预测的图像
t = 2001:2030;
r = 0.0274;
xm = 342.4412;
predictions = xm./(1+(xm./3.9-1).*exp(-r.*(t-1790))); % 计算预测值(注意这里要写成点乘和点除,这样可以保证按照对应元素进行计算)
figure(2)
plot(year,populations,'o',t,predictions,'.') % 绘制预测结果图
%生成拟合图像的自定义函数
function [fitresult, gof] = createFit_American(year, populations)
%% 拟合: '美国人口'。
[xData, yData] = prepareCurveData( year, populations );
% 设置 fittype 和选项。
ft = fittype( 'xm/(1+(xm/3.9-1)*exp(-r*(t-1790)))', 'independent', 't', 'dependent', 'x' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [0.779051723231275 100];
% 对数据进行模型拟合。
[fitresult, gof] = fit( xData, yData, ft, opts );
% 绘制数据拟合图。
figure( 'Name', '美国人口' );
h = plot( fitresult, xData, yData );
legend( h, 'populations vs. year', '美国人口', 'Location', 'NorthEast', 'Interpreter', 'none' );
% 为坐标区加标签
xlabel( 'year', 'Interpreter', 'none' );
ylabel( 'populations', 'Interpreter', 'none' );
grid on
注意事项:在我们输入自定义函数后如果线段不符合点我们可以在你和选项中函数方程下面->高级选项,修改系数的值(本题的系数时r和xm我们已将xm改为100后符合线段数据)
最后的结果:
博主主要跟着清风数学建模的课程学习,其中里面的一些图片都来源于上课视频的截图。