2015-01-26 60 views
1

使用下面的代碼我無法將sigmoid函數擬合到我的數據集中。 但是,如果我在下面的代碼中添加一個偏移量t = x + 50 -x0,它很合適。爲什麼我無法使用scipy.optimize.curve_fit將sigmoid函數適用於此數據?

不應該x0照顧接頭?


import numpy as np 
import pylab 
from scipy.optimize import curve_fit 

listA = np.array([-110,-105,-100,-95,-90,-85,-80,-75,-70,-65,-60,-55,-50,-45]) 
listB = np.array([1,1,1,1,0.926470588,0.852941176,0.616803279,0.371212121, 
        0.191066998,0.088565022,0.06684492,0.019855596,0.015517241,0]) 

def sigmoid(x,x0,k,y0): 
    t = x -x0     
    y = y0-1/(1 + np.exp(-k*t)) 
    return y 

popt, pcov = curve_fit(sigmoid, listA, listB) 
print popt ,pcov  

x = np.linspace(-110,-45,50) 

y = sigmoid(x, *popt) 

pylab.plot(listA, listB, 'o', label='data') 
pylab.plot(x,y, label='fit') 
pylab.ylim(-0.05, 1.05) 
pylab.legend(loc='best') 
pylab.show() 

回答

3

您正在運行到初始條件敏感性的經典案例。 curve_fit函數接受關鍵字參數p0,它允許您爲函數的自由參數(在您的情況下爲x0ky0)選擇初始「猜測」。

當沒有提供p0時,scipy假定所有參數爲will start at one。對於你的函數來說,這意味着sigmoid的分母將非常接近於零,所以函數值會爆炸。這混淆了求解器,並導致了一個糟糕的解決方案。

不幸的是,這個問題沒有解決方案,因爲它需要了解您正在嘗試適配的功能的動態。在你的情況下,提供一個p0(-30, 1, 0)將允許解算器收斂到一個體面的解決方案。

+0

感謝perimosocordiae ......有道理..是否有R-square或迴歸scoe輸出,我可以從curve_fit得到這將幫助我猜這樣的問題.... – vivekbecks 2015-01-27 00:14:38

+0

雖然'p0'的假設不正確,但會導致錯誤分析。但是,您的陳述「初始條件敏感性的經典案例」爲真,以及您的最後一段。 – 2015-01-27 00:18:19

+0

@vivekbecks是的,總是檢查'pcov'的值。如果它是'inf',則出現問題。 – 2015-01-27 00:19:51

3

這是因爲問題處理的數量很大,使得曲線擬合算法很快發生分歧。

(默認的)初始猜測,p0,對於curve_fit都是一數組:

P0:無,標量,或者M-長度序列 的參數的初始猜測。如果沒有,那麼最初的 值將全部爲1(如果函數 的參數數量可以使用內省來確定,否則會引發ValueError )。

對於你的問題,這意味着[1,1,1]。已經使用了第一個x0值-110,這將導致指數的參數爲​​:-1 * (-110-1)導致np.exp(111)這是一個巨大的數字,遠遠大於它被添加到的常量1。即使對於初始猜測x0的小變化,結果也會是與y0總結的分數幾乎爲零。這就是爲什麼你也看到爲你的問題,popt將返回[1, 1, .51]:該算法沒有發現x0的小變化對結果有任何重大影響(y)。

解決方案確實提供了一個不錯的猜測。算法將用於參數的變化也取決於這些參數的大小。提供[-45, 1, 1]也將產生一個很好的解決方案,的初始猜測-90也是如此:只要確保水平偏移量至少與獨立變量的值「接近」(在您的情況下爲listA的值)即可。

相關問題