matlab-非線性擬合函數lsqcurvefit的使用和初值選取


所解決問題:

我們知道我們的表達式是y=A+B*exp(-x.^2)-C./log(x), 而且現在我們手里面有x與y對應的一大把數據。

我們需要根據x, y的值找出最佳的A、B、C值。則我們現在借助Matlab的函數lsqcurvefit,當然你也可以使用nlinfit、lsqnonlin甚至cftool擬合工具箱.其具體用法請自己用Matlab的幫助命令進行查看。這里僅簡單介紹一下常用的函數lsqcurvefit

正文:

格式:lsqcurvefit(f,a,x,y)

f: 符號函數句柄,如果是以m文件的形式調用的時候,別忘記加@.這里需要注意,f函數的返回值是和y匹對的,即擬合參數的標准是(f-y)^2取最小值,具體看下面的例子

a:最開始預估的值(預擬合的未知參數的估計值)。如上面的問題如果我們預估A為1,B為2,C為3,則a=[1 2 3]

x:我們已經獲知的x的值

y:我們已經獲知的x對應的y的值

例:

問題:對於函數y=a*sin(x)*exp(x)-b/log(x)我們現在已經有多組(x,y)的數據,我們要求最佳的a,b值

%針對上面的問題,我們可以來演示下如何使用這個函數以及看下其效果
x=2:10;
y=8*sin(x).*exp(x)-12./log(x);
%上面假如是我們事先獲得的值
a=[1 2];
f=@(a,x)a(1)*sin(x).*exp(x)-a(2)./log(x);
%使用lsqcurvefit
[A,resnorm]=lsqcurvefit(f,a,x,y) %resnorm殘差平方和  A是參數

 答案是 A = 8.0000 12.0000   resnorm =7.7179e-20

 

問題:我們知道函數是 y=A+B*exp(-(x/C).^2), 以及x y的數據

xdata=[950;1150;1350];
ydata=[200;100;50];
fun1 = @(x,xdata)x(1)+x(2)*exp(-(xdata./x(3)).^2);  %自定義函數類型
X0=[0,1120,740];      %初始參數
[X,resnorm]=lsqcurvefit(fun1,X0,xdata,ydata); %resnorm殘差平方和  X是參數
disp(X) %得到所求參數

%畫圖
xi=800:1500;
yi=fun1(X,xi); %調用函數句柄
plot(xi,yi)
hold on
plot(xdata,ydata,'or')

關於這個問題,我們發現它的初值設置的非常巧妙,對於初值的選取,我在大佬的一篇文章(http://blog.163.com/shikang999@126/blog/static/172624896201463111856714/)閱讀到:

 

擬合初值的選取問題

因為初值對擬合速度甚至結果有一定影響,因此這里就簡單說一下確定數學模型后,擬合非線性問題時,初值的選取的問題。

1、如果已知數學模型,有一定物理意義,則建議根據物理意義選取。

2、當無法確定初值時,且你的數學模型有導數(如果求導模型很復雜甚至沒有導數,則可進行簡單的差分構造),則可以采用如下的辦法進行

步驟

(1)求出擬合函數的一階導數【如果有必要可求更高階導數】 

(2)使用已知數據求出近似點的一階導數 

(3)代入一階導數函數以及原函數求得初值近似值  

 

例子:  

已知一組數據x、y滿足如下關系式,求擬合數據a、b、c、d的初始近似值 

y = a + b * (x - c) ^ d 

步驟

(1) y' = b * d * (x - c) ^ (d - 1) 

(2)因為已知x、y數據,則根據差分法( y'=(y2-y1)/(x2-x1) )求得一組x、y' 的近似值,這里記 f = y'  

(3)將x、y' 代入(1)式的方程得到如下三個方程進而求解出b、c、d 

 f[1] = b * d * (x[1] - c) ^ (d - 1)      ① 

 f[2] = b * d * (x[2] - c) ^ (d - 1)      ② 

 f[3] = b * d * (x[3] - c) ^ (d - 1)      ③ 

(4)取任意一組x、y然后將b、c、d一起代入原方程 y = a + b * (x - c) ^ d 進而可以求得近似值 a 

(5)至此 a、b、c、d初始近似值確定完畢!

 

例:(多元的情況,注意看格式)

問題:我們已知z=a*(exp(y)+1)-sin(x)*b且有多組(x,y,z)的值,現在求最佳系數a,b

x=2:10;
y=10*sin(x)./log(x);
z=4.5*(exp(y)+1)-sin(x)*13.8;
f=@(a,x)a(1)*(exp(x(2,:))+1)-sin(x(1,:))*a(2);
%使用lsqcurvefit
lsqcurvefit(f,[1 2],[x;y],z)%注意這里面的[x;y],這里的[1 2]表示我們設置f函數里的初始值a(1)=1,,a(2)=2 

ans =4.5000 13.8000

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM