我在擬合某些數據的曲線時遇到了一些麻煩,但無法計算出我要出錯的地方。指數衰減曲線擬合在numpy和scipy中
在過去我曾與numpy.linalg.lstsq的指數函數和乙狀結腸功能scipy.optimize.curve_fit做到了這一點。這次我想創建一個腳本,讓我指定各種功能,確定參數並測試它們對數據的適合性。在做這件事時,我注意到Scipy leastsq
和Numpy lstsq
似乎爲同一組數據和相同的功能提供了不同的答案。該功能簡單地爲y = e^(l*x)
,受限於y=1
在x=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 。
謝謝@Jaime - 偉大的答案!不幸的是,我的數學知識不是很好,是一個寫還是錯的[也見上面的編輯],還是隻是根本上不同......?例如,如果我想測試Sigmoid或Gompertz曲線對相同數據的擬合程度,對其他函數有什麼影響? – StacyR
@StacyR我沒有足夠的知識來正確回答你的問題,但我相當確定,像'np.linalg.lstsq'那樣擬合指數是一種快速的'不'計算技巧錯誤正確。這裏有一些討論(很難讓我跟隨):http://mathworld.wolfram.com/LeastSquaresFittingExponential.html如果你不想深入研究這些東西,我會用scipy的方法來處理所有事情:應該給予更好的配合,並且您的結果將對所有功能保持一致。 – Jaime
再次感謝!我已經做了一些更多的研究,正如你所提到的那樣,發現'np.linalg.lstsq'方法在低x值時過度地加權y-錯誤。你分享的鏈接以及我發現的其他一些資源,使我得到了另外一種分析方法(使問題變得棘手的是約束 - 所有書籍都描述了y = a * e^b * x的方法)比y = e^b * x),但是,這也會產生比迭代式的'scipy.optimize.leastsq'更糟的擬合曲線。 – StacyR