注意:代码文件仅供参考,一定不要直接用于自己的数模论文中
国赛对于论文的查重要求非常严格,代码雷同也算作抄袭
如何修改代码避免查重的方法:https://www.bilibili.com/video/av59423231 //清风数学建模
一、基础知识
1.类似但不同于插值算法
插值算法要经过所有样本点,但一般会有龙格现象导致精度降低,拟合则不一定要经过所有样本点,够精准就行(像高中做的线性拟合题)
2.最小二乘法
y=kx+b 参考代码如下,data1是x和y两个变量,都是一列19行(19*1)。
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 % 显示网格线
画出图像建议用 匿名函数(@变量)如下例子
z=@(x,y)x^2+y^2
z(1,2)
输出:5 //1^2+2^2=5
f=@(x) k*x+b;
fplot(f,[2.5,7]);
legend('样本数据','拟合函数','location','SouthEast')
3.评价拟合的好坏R^2(越接近1越好)
总体平方和SST、误差平方和SSE(线性于参数才能用R^2,否则一般用SSE,越小越好)、回归平方和SSR. SST=SSE+SSR
R^2=1-SSE/SST
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
注:mean()是求均值的函数
4.线性拟合工具箱
点上面一栏APP-》Curve Fitting点开(低版本输入cftool)
Xdata Ydata 就是x和y,右边方法选Polynomial,多用Custom Equation(自定义函数)当图像偏差太多时,点击Fit Options(StartPoint)更改初始值等。
注:指数 e^n=exp(n) //自然常数e为底的指数函数
把工具箱的代码弄出来:点上面文件-》Generate Code。可保存到同一目录下,把第一行:fuction[...,....]=...复制粘贴到主代码界面。
二、实战演练
利用拟合工具预测美国人口
先把我们的数据部署进去
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')
然后启动拟合工具箱
% (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))) //因为是x(t)
但得到的几乎是一条直线,这里点击Fit Options,把StartPoint的r调成0.02,xm调成500,这样得到的线基本和点重合,左侧R^2拟合很高(目前只能自己一个数一个数调的,为什么这样调以后在做解释)
之后点击文件-》 Generate Code
把代码保存在同一文件夹内。注:保存的名称和函数名一致
主函数接着调用即可
[fitresult, gof] = function1(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,'.') % 绘制预测结果图