MATLAB之最小二乘法

一、算法原理

給定一些列點x1,x2,.....xn,對應的函數值爲y1,y2,......yn。若擬合曲線爲y=ax+b,根據條件可寫出線形方程組爲:

[x1 1;x2 1;...;x3;1]*[a;b]=[y1;...;yn]即A*[a;b]=[y2;...;yn]

因爲A不是方陣,無法求逆。故做如下變形:

方法一:

\Rightarrow A'*A*[a;b]=A'*[y1;...;yn]

\Rightarrow [a;b]=inv(A'*A)*A'*[y1,...,yn]

方法二:

對矩陣A做QR分解A=Q*R

\Rightarrow Q*R*W=[y1,...,yn]

\Rightarrow R*w=Q'*[y1,...,yn]

\Rightarrow w=inv(R)*Q'*[y1,...,yn]

二、matlab程序

%% 最小二乘法插值
%設擬合直線爲y=ax+b   ax1+b=y1...axn+b=yn
%寫成[x1 1;x2 1;...;x3;1]*[a;b]=[y2;...;yn]  即A*[a;b]=[y2;...;yn]
clear
clc
close
x=1:6; 
y=[1 4 5 8 10 11];%一系列插值點
plot(x,y,'o');%繪製散點圖
hold on
axis([-5 10 -2 15]);%座標軸範圍

A=[1 1;2 1;3 1;4 1;5 1;6 1];%A*[a;b]=[y2;...;yn]
y=y';
% y=[1;4;5;8;10;11];  %法方方程組 A*W=Y  即 A'*A*W=A'*Y  (
w=inv(A'*A)*A'*y;      %W=inv(A'*A)*A'*Y   求得係數W=[a,b]
y1=w(1).*x+w(2);
plot(x,y1,':');
% QR分解法做最小二乘擬合
Q=orth(A);  %QR分解法  A*W=Y  A=Q*R   Q*R*W=Y  W=inv(R)*Q'*Y
R=Q'*A;
a1=inv(R)*Q'*y;
x=0:8;
y2=a1(1).*x+a1(2);
plot(x,y2);

三、matlab自帶最小二乘擬合函數  lsqcurvefit

1、函數簡介

 x = lsqcurvefit(fun,a0,xdata,ydata,lb,ub,options)

非線性曲線擬合是已知輸入向量xdata和輸出向量ydata,
並且知道輸入與輸出的函數關係爲ydata=F(x, xdata),即已知擬合曲線的形式(一次函數,二次函數,...)
但不知道係數向量a。進行曲線擬合,求x使得輸出的最小二乘表達式成立:
x = lsqcurvefit(fun,a0,xdata,ydata)
x = lsqcurvefit(fun,a0,xdata,ydata,lb,ub)
x = lsqcurvefit(fun,a0,xdata,ydata,lb,ub,options)
 [x,resnorm] = lsqcurvefit(…)
 [x,resnorm,residual] = lsqcurvefit(…)
 [x,resnorm,residual,exitflag] = lsqcurvefit(…)
 [x,resnorm,residual,exitflag,output] = lsqcurvefit(…)
 [x,resnorm,residual,exitflag,output,lambda] = lsqcurvefit(…)
[x,resnorm,residual,exitflag,output,lambda,jacobian] =lsqcurvefit(…)
參數說明:
a0爲初始解向量;xdata,ydata爲滿足關係ydata=F(a, xdata)的數據;
lb、ub爲解向量的下界和上界lb≤a≤ub,若沒有指定界,則lb=[ ],ub=[ ];
options爲指定的優化參數;
fun爲待擬合函數,計算x處擬合函數值,其定義爲function F = myfun(a,xdata)或者匿名函數
resnorm=sum ((fun(a,xdata)-ydata).^2),即在x處殘差的平方和;
residual=fun(a,xdata)-ydata,即在x處的殘差;
exitflag爲終止迭代的條件;
output爲輸出的優化信息;
lambda爲解a處的Lagrange乘子;
jacobian爲解a處擬合函數fun的jacobian矩陣。

2、matlab程序

close
clc
clear
xdata=linspace(0,2*pi,15);
y=5*sin(xdata)+2*xdata+xdata.^2;
y=y+2*rand(1,15);
plot(xdata,y,'o') %繪製出原始數據的散點圖
hold on

fun=@(x,xdata) x(1)*sin(xdata)+x(2)*xdata+x(3)*xdata.^2;%待求擬合函數的形式
x=lsqcurvefit(fun,[0 0 0],xdata,y);% [0 0 0]爲插值多項式初始係數a0,
%xdata爲輸入原始數據x座標,y爲原始數據縱座標,返回值x爲待求係數矩陣
xx=linspace(0,2*pi,150);%擬合函數曲線的x座標
yy=fun(x,xx);%擬合函數曲線
plot(xx,yy)%繪製擬合函數曲線

lb=[-1 -1 -1];%係數下限
ub=[6 3 2]; %係數上限
x=lsqcurvefit(fun,[0 0 0],xdata,y,lb,ub);
xx=linspace(0,2*pi,150);
yy=fun(x,xx);
plot(xx,yy)
%選項設置
%options = optimset(Name,Value,...)不可以將求解器名稱作爲第一個參數
%options = optimoptions(SolverName,Name,Value,...)可以將求解器名稱作爲第一個參數
% options=optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt');%算法設置
options=optimoptions('lsqcurvefit','Display','final');%顯示設置
lb=[-1 -1 -1];
ub=[6 3 2];
[x,~,~,exitflag,~,~,jacobian]=lsqcurvefit(fun,[0 0 0],xdata,y,lb,ub,options)
xx=linspace(0,2*pi,150);
yy=fun(x,xx);
plot(xx,yy)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章