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/),社区虽小但非常有帮助。