簡體   English   中英

SciPy中的指數曲線擬合

[英]Exponential curve fitting in SciPy

我有兩個NumPy數組xy 當我嘗試通過此簡單代碼使用指數函數和curve_fit (SciPy)擬合數據時

#!/usr/bin/env python
from pylab import *
from scipy.optimize import curve_fit

x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25])
y = np.array([109,62,39,13,10,4,2,0,1,2])

def func(x, a, b, c, d):
    return a*np.exp(b-c*x)+d

popt, pcov = curve_fit(func, x, y)

我得到錯誤的系數popt

[a,b,c,d] = [1., 1., 1., 24.19999988]

問題是什么?

第一條評論:由於a*exp(b - c*x) = (a*exp(b))*exp(-c*x) = A*exp(-c*x) ,因此ab是多余的。 我將刪除b並使用:

def func(x, a, c, d):
    return a*np.exp(-c*x)+d

那不是主要問題。 問題很簡單,當您使用默認的初始猜測(全為1)時, curve_fit無法收斂到該問題的解決方案。 檢查pcov ; 您會看到它是inf 這並不奇怪,因為如果c為1,則exp(-c*x)大多數值都下溢為0:

In [32]: np.exp(-x)
Out[32]: 
array([  2.45912644e-174,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000,   0.00000000e+000,   0.00000000e+000,
         0.00000000e+000])

這表明c應該很小。 更好的初始猜測是,例如p0 = (1, 1e-6, 1) 然后我得到:

In [36]: popt, pcov = curve_fit(func, x, y, p0=(1, 1e-6, 1))

In [37]: popt
Out[37]: array([  1.63561656e+02,   9.71142196e-04,  -1.16854450e+00])

這看起來很合理:

In [42]: xx = np.linspace(300, 6000, 1000)

In [43]: yy = func(xx, *popt)

In [44]: plot(x, y, 'ko')
Out[44]: [<matplotlib.lines.Line2D at 0x41c5ad0>]

In [45]: plot(xx, yy)
Out[45]: [<matplotlib.lines.Line2D at 0x41c5c10>]

擬合圖

首先,我建議將您的方程式修改為a*np.exp(-c*(xb))+d ,否則指數將始終以x=0為中心,但並非總是如此。 您還需要指定合理的初始條件( curve_fit的第4個參數指定[a,b,c,d]初始條件)。

該代碼非常適合:

from pylab import *
from scipy.optimize import curve_fit

x = np.array([399.75, 989.25, 1578.75, 2168.25, 2757.75, 3347.25, 3936.75, 4526.25, 5115.75, 5705.25])
y = np.array([109,62,39,13,10,4,2,0,1,2])

def func(x, a, b, c, d):
    return a*np.exp(-c*(x-b))+d

popt, pcov = curve_fit(func, x, y, [100,400,0.001,0])
print popt

plot(x,y)
x=linspace(400,6000,10000)
plot(x,func(x,*popt))
show()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM