2024美赛数学建模常用数学建模模型之——最小二乘法

2.1 线性最小二乘法

       曲线拟合问题的提法 是,已知一组(二维)数据,即平面上的 n 个点 ( x i , y i ) i = 1,2, L , n x i 互不相同,寻求一个函数(曲线) y = f ( x ) ,使 f ( x ) 在某种准则下 与所有数据点最为接近,即曲线拟合得最好。
   线性最小二乘法 是解决曲线拟合最常用的方法,基本思路是,令

2.2 最小二乘法的 Matlab 实现

2.2.1 解方程组方法
在上面的记号下,
x=[19 25 31 38 44]'; 
y=[19.0 32.3 49.0 73.3 97.8]'; 
r=[ones(5,1),x.^2]; 
ab=r\y 
x0=19:0.1:44; 
y0=ab(1)+ab(2)*x0.^2; 
plot(x,y,'o',x0,y0,'r')
2.2.2 多项式拟合方法
如果取 { r 1 ( x ), L , r m + 1 ( x )} = {1, x , L , x m } ,即用 m 次多项式拟合给定数据, Matlab 中有现成的函数
                                                a=polyfit(x0,y0,m)
其中输入参数 x0,y0 为要拟合的数据, m 为拟合多项式的次数,输出参数 a 为拟合多项
y=a m x m + …+a 1 x+a 0 系数 a=[ a m , …, a 1 , a 0 ]。
多项式在 x 处的值 y 可用下面的函数计算
                                                y=polyval(a,x)。
例 5 某乡镇企业 1990-1996 年的生产利润如表 5
试预测 1997 年和 1998 年的利润。
作已知数据的的散点图,
x0=[1990 1991 1992 1993 1994 1995 1996]; 
y0=[70 122 144 152 174 196 202]; 
plot(x0,y0,'*')
发现该乡镇企业的年生产利润几乎直线上升。因此,我们可以用 y = a 1 x + a 0 作为
拟合函数来预测该乡镇企业未来的年利润。编写程序如下:
x0=[1990 1991 1992 1993 1994 1995 1996]; 
y0=[70 122 144 152 174 196 202]; 
a=polyfit(x0,y0,1) 
y97=polyval(a,1997) 
y98=polyval(a,1998)

2.3 最小二乘优化

        在无约束最优化问题中,有些重要的特殊情形,比如目标函数由若干个函数的平方和构成。这类函数一般可以写成:

lsqlin 函数

Matlab 中的函数为:
x=lsqlin(C,d,A,b,Aeq,beq,lb,ub,x0)
x=[19 25 31 38 44]'; 
y=[19.0 32.3 49.0 73.3 97.8]'; 
r=[ones(5,1),x.^2]; 
ab=lsqlin(r,y) 
x0=19:0.1:44; 
y0=ab(1)+ab(2)*x0.^2; 
plot(x,y,'o',x0,y0,'r')

lsqcurvefit 函数

解 该问题即解最优化问题:
function f=fun1(x,tdata);
f=x(1)+x(2)*exp(-0.02*x(3)*tdata); %其中 x(1)=a,x(2)=b,x(3)=k
调用函数 lsqcurvefit,编写程序如下:
td=100:100:1000; 
cd=[4.54 4.99 5.35 5.65 5.90 6.10 6.26 6.39 6.50 6.59]; 
x0=[0.2 0.05 0.05]; 
x=lsqcurvefit(@fun1,x0,td,cd)

lsqnonlin 函数

function f=fun2(x); 
td=100:100:1000; 
cd=[4.54 4.99 5.35 5.65 5.90 6.10 6.26 6.39 6.50 6.59]; 
f=x(1)+x(2)*exp(-0.02*x(3)*td)-cd;
调用函数 lsqnonlin,编写程序如下:
x0=[0.2 0.05 0.05]; %初始值是任意取的 
x=lsqnonlin(@fun2,x0)

lsqnonneg 函数

编写程序如下:
c=[0.0372 0.2869;0.6861 0.7071;0.6233 0.6245;0.6344 0.6170]; 
d=[0.8587;0.1781;0.0747;0.8405]; 
x=lsqnonneg(c,d)

曲线拟合的用户图形界面求法

Matlab 工具箱提供了命令 cftool ,该命令给出了一维数据拟合的交互式环境。具体
执行步骤如下:
1 )把数据导入到工作空间;
2 )运行 cftool ,打开用户图形界面窗口;
3 )对数据进行预处理;
4 )选择适当的模型进行拟合;
5 )生成一些相关的统计量,并进行预测。
可以通过帮助(运行 doc cftool )熟悉该命令的使用细节。

2.4 曲线拟合与函数逼近

前面讲的曲线拟合是已知一组离散数据{( x i , y i), i =1,L, n},选择一个较简单的函数 f ( x),如多项式,在一定准则如最小二乘准则下,最接近这些数据。
编写程序如下:
syms x 
base=[1,x^2,x^4]; 
y1=base.'*base 
y2=cos(x)*base.' 
r1=int(y1,-pi/2,pi/2) 
r2=int(y2,-pi/2,pi/2) 
a=r1\r2 
xishu1=double(a) 
digits(8),xishu2=vpa(a)
求得 xishu1=0.9996 -0.4964 0.0372,即所求的最佳平方逼近多项式为

2.5 黄河小浪底调水调沙问题

clc,clear 
load data.txt %data.txt 按照原始数据格式把水流量和排沙量排成 4 行,12 列
liu=data([1,3],:); 
liu=liu';liu=liu(:); 
sha=data([2,4],:); 
sha=sha';sha=sha(:); 
y=sha.*liu;y=y'; 
i=1:24; 
t=(12*i-4)*3600; 
t1=t(1);t2=t(end); 
pp=csape(t,y); 
xsh=pp.coefs %求得插值多项式的系数矩阵,每一行是一个区间上多项式的系数。
TL=quadl(@(tt)ppval(pp,tt),t1,t2)
也可以利用 3 B 样条函数进行插值,求得总的排沙量也为 1.844 × 10 9 t ,,计算
Matlab 程序如下:
clc,clear 
load data.txt %data.txt 按照原始数据格式把水流量和排沙量排成 4 行,12 列
liu=data([1,3],:); 
liu=liu';liu=liu(:); 
sha=data([2,4],:); 
sha=sha';sha=sha(:); 
y=sha.*liu;y=y'; 
i=1:24; 
t=(12*i-4)*3600; 
t1=t(1);t2=t(end); 
pp=spapi(4,t,y) %三次 B 样条
pp2=fn2fm(pp,'pp') %把 B 样条函数转化为 pp 格式
TL=quadl(@(tt)fnval(pp,tt),t1,t2)
对于问题( 2),研究排沙量与水量的关系,从试验数据可以看出,开始排沙量是随
着水流量的增加而增长,而后是随着水流量的减少而减少。显然,变化规律并非是线性
的关系,为此,把问题分为两部分,从开始水流量增加到最大值 2720m 3 /s (即增长的过
程)为第一阶段,从水流量的最大值到结束为第二阶段,分别来研究水流量与排沙量的
关系。
load data.txt 
liu=data([1,3],:); 
liu=liu';liu=liu(:); 
sha=data([2,4],:); 
sha=sha';sha=sha(:); 
y=sha.*liu; 
subplot(1,2,1), plot(liu(1:11),y(1:11),'*') 
subplot(1,2,2), plot(liu(12:24),y(12:24),'*')
从散点图可以看出,第一阶段基本上是线性关系,第二阶段准备依次用二次、三次、
四次曲线来拟合,看哪一个模型的剩余标准差小就选取哪一个模型。最后求得第一阶段
排沙量 y 与水流量 v 之间的预测模型为
clc, clear 
load data.txt %data.txt 按照原始数据格式把水流量和排沙量排成 4 行,12 列
liu=data([1,3],:); liu=liu'; liu=liu(:); 
sha=data([2,4],:); sha=sha'; sha=sha(:); 
y=sha.*liu; 
%以下是第一阶段的拟合
format long e 
nihe1_1=polyfit(liu(1:11),y(1:11),1) %拟合一次多项式,系数排列从高次幂到低次幂
nihe1_2=polyfit(liu(1:11),y(1:11),2)
yhat1_1=polyval(nihe1_1,liu(1:11)); %求预测值
yhat1_2=polyval(nihe1_2,liu(1:11)); 
%以下求误差平凡和与剩余标准差
cha1_1=sum((y(1:11)-yhat1_1).^2); rmse1_1=sqrt(cha1_1/9) 
cha1_2=sum((y(1:11)-yhat1_2).^2); rmse1_2=sqrt(cha1_2/8) 
%以下是第二阶段的拟合
for j=1:3 
 str1=char(['nihe2_' int2str(j) '=polyfit(liu(12:24),y(12:24),' int2str(j+1) ')']); 
 eval(str1) 
 str2=char(['yhat2_' int2str(j) '=polyval(nihe2_' int2str(j) ',liu(12:24));']); 
 eval(str2) 
 str3=char(['cha2_' int2str(j) '=sum((y(12:24)-yhat2_' int2str(j) ').^2);'... 
 'rmse2_' int2str(j) '=sqrt(cha2_' int2str(j) '/(11-j))']); 
 eval(str3) 
end 
format

更多美赛资料,请点击下方名片获取:

  • 35
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值