SciPy全局最小曲线拟合

时间:2011-03-22 06:03:11

标签: python scipy scientific-computing curve-fitting simulated-annealing

我正在使用scipy.optimize.curve_fit,但我怀疑它正在收敛到局部最小值而不是全局最小值。

我尝试以下列方式使用模拟退火:

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中是否有全局曲线钳工?

3 个答案:

答案 0 :(得分:6)

你是对的,它只会收敛到局部最小值(当它收敛时),因为它使用了Levenburg-Marquardt算法。 SciPy中没有全局曲线拟合器,您必须使用existing global optimizers自己编写。但要注意,这仍然不必收敛到你想要的价值。在大多数情况下,这是impossible

改善结果的唯一方法是很好地猜测起始参数。

答案 1 :(得分: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'])

答案 2 :(得分:1)

这是一个非常重要的问题。您是否考虑过使用进化策略?我在ecspy上取得了巨大成功(见http://code.google.com/p/ecspy/),社区规模虽小但非常有帮助。