2013-01-16 93 views
6

我在擬合某些數據的曲線時遇到了一些麻煩,但無法計算出我要出錯的地方。指數衰減曲線擬合在numpy和scipy中

在過去我曾與numpy.linalg.lstsq的指數函數和乙狀結腸功能scipy.optimize.curve_fit做到了這一點。這次我想創建一個腳本,讓我指定各種功能,確定參數並測試它們對數據的適合性。在做這件事時,我注意到Scipy leastsq和Numpy lstsq似乎爲同一組數據和相同的功能提供了不同的答案。該功能簡單地爲y = e^(l*x),受限於y=1x=0

Excel趨勢線與Numpy lstsq結果一致,但由於Scipy leastsq能夠採取任何功能,因此找出問題所在是一件好事。

import scipy.optimize as optimize 
import numpy as np 
import matplotlib.pyplot as plt 

## Sampled data 
x = np.array([0, 14, 37, 975, 2013, 2095, 2147]) 
y = np.array([1.0, 0.764317544, 0.647136491, 0.070803763, 0.003630962,  0.001485394,  0.000495131]) 

# function 
fp = lambda p, x: np.exp(p*x) 

# error function 
e = lambda p, x, y: (fp(p, x) - y) 

# using scipy least squares 
l1, s = optimize.leastsq(e, -0.004, args=(x,y)) 
print l1 
# [-0.0132281] 


# using numpy least squares 
l2 = np.linalg.lstsq(np.vstack([x, np.zeros(len(x))]).T,np.log(y))[0][0] 
print l2 
# -0.00313461628963 (same answer as Excel trend line) 

# smooth x for plotting 
x_ = np.arange(0, x[-1], 0.2) 

plt.figure() 
plt.plot(x, y, 'rx', x_, fp(l1, x_), 'b-', x_, fp(l2, x_), 'g-') 
plt.show() 

編輯 - 附加信息

上面的MWE包括數據集的一小部分。當擬合實際數據時,曲線呈現0.82的R^2,而與Excel計算的曲線相同的曲線具有0.41的R^2曲線,其曲線的R^2爲0.41 。

回答

4

您正在最小化不同的錯誤功能。

當使用numpy.linalg.lstsq,被最小化的誤差函數是

np.sum((np.log(y) - p * x)**2) 

scipy.optimize.leastsq最小化函數

np.sum((y - np.exp(p * x))**2) 

第一種情況,需要因變量和自變量之間的線性相關性,但解決方案是已知的,而第二個可以處理任何依賴關係,但依賴於迭代方法。

在一個單獨的說明, 我現在不能使用 numpy.linalg.lstsq時測試,但 ,我你並不需要vstack零一排,下面的作品,以及:

l2 = np.linalg.lstsq(x[:, None], np.log(y))[0][0] 
+0

謝謝@Jaime - 偉大的答案!不幸的是,我的數學知識不是很好,是一個寫還是錯的[也見上面的編輯],還是隻是根本上不同......?例如,如果我想測試Sigmoid或Gompertz曲線對相同數據的擬合程度,對其他函數有什麼影響? – StacyR

+0

@StacyR我沒有足夠的知識來正確回答你的問題,但我相當確定,像'np.linalg.lstsq'那樣擬合指數是一種快速的'不'計算技巧錯誤正確。這裏有一些討論(很難讓我跟隨):http://mathworld.wolfram.com/LeastSquaresFittingExponential.html如果你不想深入研究這些東西,我會用scipy的方法來處理所有事情:應該給予更好的配合,並且您的結果將對所有功能保持一致。 – Jaime

+0

再次感謝!我已經做了一些更多的研究,正如你所提到的那樣,發現'np.linalg.lstsq'方法在低x值時過度地加權y-錯誤。你分享的鏈接以及我發現的其他一些資源,使我得到了另外一種分析方法(使問題變得棘手的是約束 - 所有書籍都描述了y = a * e^b * x的方法)比y = e^b * x),但是,這也會產生比迭代式的'scipy.optimize.leastsq'更糟的擬合曲線。 – StacyR

1

要在Jaime的觀點上闡述了一點,數據的任何非線性變換都會導致不同的誤差函數,從而導致不同的解決方案。這將導致擬合參數的不同置信區間。因此,您有三個可能的標準用於做出決定:您想要最小化哪個錯誤,哪個參數要更有信心,最後,如果您使用擬合來預測某個值,哪種方法在有趣的方面產生的誤差更小預測值。在解析和Excel中進行一些分析表明,數據中的不同種類的噪聲(例如,如果噪聲函數縮放振幅,影響時間常數或是相加的)會導致不同的解決方案選擇。

我還會補充一點,雖然這個技巧對於指數衰減爲「有效」,但它不能用於阻尼指數(上升或下降)的更一般(普通)情況下,假設爲0.