参考学习b站:数学建模学习交流
例一
找出y和x之间的拟合曲线
Excel放入matlab矩阵里:
给出随机数生成的用法:
%(1)randi : 产生均匀分布的随机整数(i = int)
%产生一个1至10之间的随机整数矩阵,大小为2x5;
s1 = randi(10,2,5);
%产生一个-5至5之间的随机整数矩阵,大小为1x10;
s2 = randi([-5,5],1,10);
%(2)rand: 产生0至1之间均匀分布的随机数
%产生一个0至1之间的随机矩阵,大小为1x5;
s3 = rand(1,5)
%产生一个a至b之间的随机矩阵,大小为1x5;
% a + (b-a) * rand(1,5); 如:a,b = 2,5
s4 = 2 + (5-2) * rand(1,5)
%(3)normrnd:产生正态分布的随机数
%产生一个均值为0,标准差(方差开根号)为2的正态分布的随机矩阵,大小为3x4;
s5 = normrnd(0,2,3,4)
%(4)roundn—任意位置四舍五入
% 0个位 1十位 2百位 -1小数点后一位
a = 3.1415
roundn(a,-2) % ans = 3.1400
roundn(a,2) % ans = 0
a =31415
roundn(a,2) % ans = 31400
roundn(5.5,0) %6
roundn(5.5,1) %10
clear;clc
x = rand(30,1) * 10; % x是0-10之间均匀分布的随机向量(30个样本)
y = 3 * exp(0.5*x) -5 + normrnd(0,1,30,1);
举个匿名函数的小例子
% z=@(x,y) x^2+y^2;
% z(1,2)
% ans = 5
% fplot函数可用于画出匿名一元函数的图形。
% fplot(f,xinterval) 将匿名函数f在指定区间xinterval绘图
% xinterval = [xmin xmax] 表示定义域的范围
拟合代码:
clear;clc
load('D:\D其他\数学建模\拟合\代码和例题数据\data1')
plot(x,y,'o')
% 给x和y轴加上标签
xlabel('x的值')
ylabel('y的值')
n = size(x,1);% 矩阵x的行数
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 % 显示网格线
f=@(x) k*x+b;
fplot(f,[2.5,7]);
legend('样本数据','拟合函数','location','SouthEast')
结果:
如何评价拟合的好坏,不再赘述(队友的事情咯😅)直接上代码:
% mean()是求均值的函数
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 %拟合优度R^2
也可以用cftool
指数拟合:
我们在工具箱Generate Code一下,生成了:
function [fitresult, gof] = createFit(x, y)
%CREATEFIT(X,Y)
% Create a fit.
%
% Data for 'csp_test' fit:
% X Input : x
% Y Output: y
% Output:
% fitresult : a fit object representing the fit.
% gof : structure with goodness-of fit info.
%
% 另请参阅 FIT, CFIT, SFIT.
% 由 MATLAB 于 15-Jul-2021 21:59:26 自动生成
%% Fit: 'csp_test'.
[xData, yData] = prepareCurveData( x, y );
% Set up fittype and options.
ft = fittype( 'poly1' );
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft );
% Plot fit with data.
figure( 'Name', 'csp_test' );
h = plot( fitresult, xData, yData );
legend( h, 'y vs. x', 'csp_test', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y', 'Interpreter', 'none' );
grid on
运行就可以出现图像+评估参数,放附录就好
例二
给出近2个世纪的美国人口统计数据(单位:百万人),请使用最下面给定的拟合函数预测后30年的美国人口
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];
x ( t ) = x m 1 + ( x m 3.9 − 1 ) e − r ( t − 1790 ) x\left( t\right) =\dfrac{x_{m}}{1+\left( \dfrac{x_{m}}{3.9}-1\right) e^{-r\left( t-1790\right) }} x(t)=1+(3.9xm−1)e−r(t−1790)xm
x m x_{m} xm和 r r r是两个拟合参数, t t t表示年份, x ( t ) x(t) x(t)表示第 t t t年的人口
刚开始是这样:
Fit computation did not converge:
Fitting stopped because the number of iterations or function evaluations exceeded the specified maximum.
发现结果不收敛,改一下变量初始值就好了
Generate Code:
function [fitresult, gof] = createFit(year, population)
%CREATEFIT(YEAR,POPULATION)
% Create a fit.
%
% Data for 'csp_test' fit:
% X Input : year
% Y Output: population
% Output:
% fitresult : a fit object representing the fit.
% gof : structure with goodness-of fit info.
%
% 另请参阅 FIT, CFIT, SFIT.
% 由 MATLAB 于 15-Jul-2021 22:23:28 自动生成
%% Fit: 'csp_test'.
[xData, yData] = prepareCurveData( year, population );
% Set up fittype and options.
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.0975404049994095 100];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', 'csp_test' );
h = plot( fitresult, xData, yData );
legend( h, 'population vs. year', 'csp_test', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'year', 'Interpreter', 'none' );
ylabel( 'population', 'Interpreter', 'none' );
grid on
加上预测后30年的代码:
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')
% 调用createFit函数得到参数的拟合值和预测的效果
[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,'.') % 绘制预测结果图
运行(参数比较难调,预测的还是不太准):
总结
多项式逼近中, R 2 R^2 R2越接近1且函数形式越简单,拟合效果越好,对于其他非线性函数,SSE值越低,拟合效果越好