【4.0】 数学建模中拟合算法详解|内附清晰图片和详细代码实现

一、前言

与插值问题不同,在拟合问题中不需要曲线一定经过给定的点。拟合问题的目标是寻求一个函数(曲线),使得该曲线在某种准则下与所有的数据点最为接近,即曲线拟合的最好(最小损失函数)

在这里插入图片描述
插值和拟合的区别:插值算法中,得到的多项式 f ( x ) f(x) f(x)要经过所有的样本点。但是如果样本点过多,得到的多项式会次数很高,从而导致龙格现象。尽管可以采用分段的方法避免这种现象,大使更多的时候更倾向于得到一个确定的曲线,尽管这条曲线不能经过所有的样本点,但只要保证误差足够小即可,这就是拟合的思想(拟合的结果就是得到一个确定的曲线)。



二、最小二乘法

设样本点为 ( x i , y i ) , i = 1 , 2 , … , n (x_i,y_i),i=1,2,…,n (xi,yi),i=1,2,n,假设拟合曲线为 y = k x + b y=kx+b y=kx+b

利用最小二乘法求定义求拟合曲线的方法为:
y ^ i = k x i + b \hat{y}_i=kx_i+b y^i=kxi+b

其中: k ^ i , b ^ i = a r g min ⁡ k , b ( ∑ i = 1 n ( y i − y ^ i ) 2 ) \text{其中:}\hat{k}_i,\hat{b}_i=\underset{k,b}{arg\min}\left( \sum_{i=1}^n{\left( y_i-\hat{y}_i \right) ^2} \right) 其中:k^i,b^i=k,bargmin(i=1n(yiy^i)2)



三、求解最小二乘法

设样本点为 ( x i , y i ) , i = 1 , 2 , … , n (x_i,y_i),i=1,2,…,n (xi,yi),i=1,2,n,设置拟合曲线为 y = k x + b y=kx+b y=kx+b,令拟合值为 y ^ i = k x i + b \hat{y}_i=kx_i+b y^i=kxi+b

那么:
k ^ i , b ^ i = a r g min ⁡ k , b ( ∑ i = 1 n ( y i − y ^ i ) 2 ) = a r g min ⁡ k , b ( ∑ i = 1 n ( y i − k x i − b ) 2 ) \hat{k}_i,\hat{b}_i=\underset{k,b}{arg\min}\left( \sum_{i=1}^n{\left( y_i-\hat{y}_i \right) ^2} \right) =\underset{k,b}{arg\min}\left( \sum_{i=1}^n{\left( y_i-kx_i-b \right) ^2} \right) k^i,b^i=k,bargmin(i=1n(yiy^i)2)=k,bargmin(i=1n(yikxib)2)
L = ( ∑ i = 1 n ( y i − k x i − b ) 2 ) L=\left( \sum_{i=1}^n{\left( y_i-kx_i-b \right) ^2} \right) L=(i=1n(yikxib)2),要找 k k k b b b使得L最小,在机器学习中 L L L被称之为损失函数,在回归中也常被称之为残差平方和

求解满足要求的 k k k b b b步骤如下:

在这里插入图片描述



四、MATLAB实现最小二乘法拟合

拟合的原始数据为:

x = 4.2,5.9,2.7,3.8,3.8,5.6,6.9,3.5,3.6,2.9,4.2,6.1,5.5,6.6,2.9,3.3,5.9,6,5.6;

y = 8.4,11.7,4.2,6.1,7.9,10.2,13.2,6.6,6,4.6,8.4,12,10.3,13.3,4.6,6.7,10.8,11.5,9.9

相关源代码:

clear;clc
load  data1
plot(x,y,'o')
% 给x和y轴加上标签
xlabel('x的值')
ylabel('y的值')
n = size(x,1);
k = (n*sum(x.*y)-sum(x)*sum(y))/(n*sum(x.*x)-sum(x)*sum(x))
b = (sum(x.*x)*sum(y)-sum(x)*sum(x.*y))/(n*sum(x.*x)-sum(x)*sum(x))
hold on % 继续在之前的图形上来画图形
grid on % 显示网格线

% % 画出y=kx+b的函数图像 plot(x,y)
% % 传统的画法:模拟生成x和y的序列,比如要画出[0,5]上的图形
% xx = 2.5: 0.1 :7  % 间隔设置的越小画出来的图形越准确
% yy = k * xx + b  % k和b都是已知值
% plot(xx,yy,'-')

% 匿名函数的基本用法。
% handle = @(arglist) anonymous_function
% 其中handle为调用匿名函数时使用的名字。
% arglist为匿名函数的输入参数,可以是一个,也可以是多个,用逗号分隔。
% anonymous_function为匿名函数的表达式。
% 举个小例子
%  z=@(x,y) x^2+y^2; 
%  z(1,2) 
% % ans =  5
% fplot函数可用于画出匿名一元函数的图形。
% fplot(f,xinterval) 将匿名函数f在指定区间xinterval绘图。xinterval =  [xmin xmax] 表示定义域的范围

f=@(x) k*x+b;
fplot(f,[2.5,7]);
legend('样本数据','拟合函数','location','SouthEast')

代码运行结果如下所示:

在这里插入图片描述



五、评价拟合的好坏

几个相关指标

总体平方和SST: S S T = ∑ i = 1 n ( y i − y ˉ ) 2 SST=\sum_{i=1}^n{\left( y_i-\bar{y} \right)}^2 SST=i=1n(yiyˉ)2

误差平方和SSE: S S E = ∑ i = 1 n ( y i − y ^ i ) 2 SSE=\sum_{i=1}^n{\left( y_i-\hat{y}_i \right)}^2 SSE=i=1n(yiy^i)2

回归平方和SSR: S S R = ∑ i = 1 n ( y ^ i − y ˉ ) 2 SSR=\sum_{i=1}^n{\left( \hat{y}_i-\bar{y} \right)}^2 SSR=i=1n(y^iyˉ)2

可以证明得到: S S T = S S E + S S R SST=SSE+SSR SST=SSE+SSR


拟合优度(可决系数): 0 ⩽    R 2 = S S R S S T = S S T − S S E S S T = 1 − S S T − S S E S S T    ⩽    1 0 \leqslant \,\,R^2=\frac{SSR}{SST}=\frac{SST-SSE}{SST}=1-\frac{SST-SSE}{SST}\,\,\leqslant \,\,1 0R2=SSTSSR=SSTSSTSSE=1SSTSSTSSE1

说明: R 2 R^2 R2越接近于1,说明误差平方和月接近0,误差越小说明拟合的越好

注意: R 2 R^2 R2只能用于拟合函数是线性函数时(对参数为线性),拟合结果的评价。如果是比较线性函数和其他函数(例如复杂的指数函数)之间拟合的好坏,直接看 S S E SSE SSE指标即可


六 、计算拟合优度的代码

y_hat = k*x+b; % y的拟合值
SSR = sum((y_hat-mean(y)).^2)  % 回归平方和
SSE = sum((y_hat-y).^2) % 误差平方和
SST = sum((y-mean(y)).^2) % 总体平方和
SST-SSE-SSR   % 5.6843e-14  =   5.6843*10^-14   matlab浮点数计算的一个误差
R_2 = SSR / SST


七、MATLAB中一个好用的曲线拟合工具箱

在这里插入图片描述

在这里插入图片描述



八 、 利用拟合工具预测美国人口

下表给出而来进2个世界的美国人口统计数据(单位:百万人),请使用下面给定的拟合函数预测后30年美国的人口数

17901800181018201830184018501860
人口3.95.37.29.612.917.113.231.4
18701880189019001910192019301940
人口38.650.262.976.092.0106.5123.2131.7
195019601970198019902000
人口150.7179.3204.0226.5251.4281.4


拟合函数如下:


x ( t ) = x m 1 + ( x m 3.9 − 1 ) e − r ( t − 1790 ) x\left( t \right) =\frac{x_m}{1+\left( \frac{x_m}{3.9}-1 \right) e^{-r\left( t-1790 \right)}} x(t)=1+(3.9xm1)er(t1790)xm


x m x_m xm r r r是两个拟合参数, t t t表示年份, x ( t ) x(t) x(t)表示第 t t t年的人口

代码参考:

clear;clc
year = 1790:10:2000;
population = [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,population,'o')
cftool  % 拟合工具箱
% (1) X data 选择 year
% (2) Y data 选择 population
% (3) 拟合方式选择:Custom Equation (自定义方程)
% (4) 修改下方的方框为:x = f(t) = xm/(1+(xm/3.9-1)*exp(-r*(t-1790)))
% (5) 左边的result一栏最上面显示:Fit computation did not converge:即没有找到收敛解,右边的拟合图形也表明拟合结果不理想
% (6) 点击Fit Options,修改非线性最小二乘估计法拟合的初始值(StartPoint), r修改为0.02,xm修改为500 
% 有很多同学有疑惑,初始值为什么要这样设置?我们在未来学习微分方程模型和智能算法的课程时再来给大家介绍这里面蕴含的技巧。
% (7) 此时左边的result一览得到了拟合结果:r = 0.02735, xm = 342.4
% (8) 依次点击拟合工具箱的菜单栏最左边的文件—Generate Code(导出代码到时候可以放在你的论文附录),可以得到一个未命名的脚本文件
% (9) 在这个打开的脚本中按快捷键Ctrl+S,将这个文件保存到当前文件夹。
% (10) 在现在这个文件中调用这个函数得到参数的拟合值和预测的效果
[fitresult, gof] = createFit(year, population)
t = 2001:2030;
xm = 342.4;   
r =  0.02735;
predictions = xm./(1+(xm./3.9-1).*exp(-r.*(t-1790)));  % 计算预测值(注意这里要写成点乘和点除,这样可以保证按照对应元素进行计算)
figure(2)
plot(year,population,'o',t,predictions,'.')  % 绘制预测结果图

拟合结果:

在这里插入图片描述



更多有关于拟合算法的经典获奖论文,关注公众号,回复,“拟合算法”,即可免费领取!!!
在这里插入图片描述

% MATLAB数学建模工具箱 % % 本工具箱主要包含三部分内容 % 1. MATLAB常用数学建模工具的文帮助 % 2. 贡献MATLAB数学建模工具(打*号) % 3. 国大学生数学建模竞赛历年试题MATLAB程序 % 数据拟合 % interp1 - 一元函数插值 % spline - 样条插值 % polyfit - 多项式插值或拟合 % curvefit - 曲线拟合 % caspe - 各种边界条件的样条插值 % casps - 样条拟合 % interp2 - 二元函数插值 % griddata - 不规则数据的二元函数插值 % *interp - 不单调节点插值 % *lagrange - 拉格朗日插值法 % % 方程求根 % inv - 逆矩阵 % roots - 多项式的根 % fzero - 一元函数零点 % fsolve - 非线性方程组 % solve - 符号方程解 % *newton - 牛顿迭代法解非线性方程 % %微积分和微分方程 % diff - 差分 % diff - 符号导函数 % trapz - 梯形积分法 % quad8 - 高精度数值积分 % int - 符号积分 % dblquad - 矩形域二重积分 % ode45 - 常微分方程 % dsolve - 符号微分方程 % *polyint - 多项式积分法 % *quadg - 高斯积分法 % *quad2dg - 矩形域高斯二重积分 % *dblquad2 - 非矩形域二重积分 % *rk4 - 常微分方程RungeKutta法 % %随机模拟和统计分析 % max,min - 最大,最小值 % sum - 求和 % mean - 均值 % std - 标准差 % sort - 排序(升序) % sortrows - 按某一列排序(升序) % rand - [0,1]区间均匀分布随机数 % randn - 标准正态分布随机数 % randperm - 1...n 随机排列 % regress - 线性回归 % classify - 统计聚类 % *trim - 坏数据祛除 % *specrnd - 给定分布律随机数生成 % *randrow - 整行随机排列 % *randmix - 随机置换 % *chi2test - 分布拟合度卡方检验 % % 数学规划 % lp - 线性规划 % linprog - 线性规划(在MATLAB5.3使用) % fmin - 一元函数极值 % fminu - 多元函数极值拟牛顿法 % fmins - 多元函数极值单纯形搜索法 % constr - 非线性规划 % fmincon - 非线性规划(在MATLAB5.3使用) % % 离散优化 % *enum - 枚举法 % *monte - 蒙特卡洛法 % *lpint - 线性整数规划 % *L01p_e - 0-1整数规划枚举法 % *L01p_ie - 0-1整数规划隐枚举法 % *bnb18 - 非线性整数规划(在MATLAB5.3使用) % *bnbgui - 非线性整数规划图形工具(在MATLAB5.3使用) % *mintreek - 最小生成树kruskal算法 % *minroute - 最短路dijkstra算法 % *krusk - 最小生成树kruskal算法mex程序 % *dijkstra - 最短路dijkstra算法mex程序 % *dynprog - 动态规划 % % % 图形 % plot - 平面曲线(一元函数) % plot3 - 空间曲线 % mesh - 空间曲面(二元函数) % *meshf - 非矩形网格图 % *draw - 用鼠标划光滑曲线 % %国大学生数学建模竞赛题解 % jm96a - 捕鱼策略 % jm96b - 节水洗衣机 % jm96bfun - 节水洗衣机优化函数 % jm97a - 零件参数设计 % jm97afun - 零件参数函数 % jm97aoptim - 零件参数设计优化函数 % jm97b - 截断切割 % jm97bcount - 截断切割枚举法 % jm97brule - 截断切割优化准则 % jm98a1 - 风险投资模型求解 % jm98a2 - 风险投资模型讨论 % jm98a3 - 收益与风险非线性模型求解 % jm98a3fun - 收益与风险非线性模型优化函数 % jm98b - 灾情巡视路线(C程序) % jm99a1 - 自动化车床模型一 % jm99a1fun - 自动化车床模型目标函数 % jm99a1simu - 自动化车床模型随机模拟 % jm99asmfun - 自动化车床模型费用函数 % % 演示程序 % funtool - 函数计算器 % tutdemo - MATLAB优化工具箱教程 % mathmodl - 数学建模工具箱演示
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值