5

我正在使用scipy.optimize.curve_fit,但我懷疑它正在收斂到局部最小值而不是全局最小值。SciPy全局最小曲線擬合

我試着用模擬退火以下列方式:

def fit(params): 
return np.sum((ydata - specf(xdata,*params))**2) 

p = scipy.optimize.anneal(fit,[1000,1E-10]) 

其中specf是我試圖擬合曲線。 p的結果顯然比curve_fit返回的最小值還要差,即使返回值表示達到全局最小值(see anneal)。

我該如何改進結果? SciPy中是否有全局曲線擬合?

回答

4

你說得對,因爲它使用了Levenburg-Marquardt算法,所以它只收斂到局部最小值(收斂時)。 SciPy中沒有全局曲線擬合器,您必須使用existing global optimizers來編寫您自己的曲線。但請注意,這還不一定會達到您想要的價值。在大多數情況下,這是impossible

改善結果的唯一方法是很好地猜測啓動參數。

+0

感謝您的回答。我意識到全局優化的麻煩,但我猜測(希望)這個輪廓表現相對較好。我使用L2標準來衡量健康是否正確? – Gus 2011-03-22 16:55:01

3

您可能想嘗試使用leastsq()(curve_fit實際使用此功能,但不會獲得完整輸出)或ODR package而不是curve_fit。

leastsq()的完整輸出給了你更多的信息,比如chisquared的值(如果你想用它作爲適合性測試的快速和骯髒的好處)。

如果需要加權擬合,你可以只是這樣:

fitfunc = lambda p,x: p[0]+ p[1]*exp(-x) 
errfunc = lambda p, x, y, xerr: (y-fitfunc(p,x))/xerr 
out = leastsq(errfunc, pinit, args=(x,y, xerr), full_output=1) 
chisq=sum(infodict['fvec']*infodict['fvec']) 
1

這是一個平凡的問題。你有沒有考慮過使用進化策略?我與ecspy取得了巨大成功(見http://code.google.com/p/ecspy/),社區雖小但非常有幫助。