7

我正在使用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显然比返回的最小值更差(请参阅 anneal)。curve_fit

我怎样才能改善结果?SciPy 中是否有全局曲线拟合器?

4

3 回答 3

7

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

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

于 2011-03-22T06:28:41.347 回答
3

您可能想尝试使用leastsq()(curve_fit 实际上使用它,但您没有得到完整的输出)或ODR 包而不是curve_fit。

leastsq() 的完整输出为您提供了更多信息,例如卡方值(如果您想将其用作快速而肮脏的拟合优度测试)。

如果您需要加重合身度,您可以这样:

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'])
于 2011-03-22T19:25:55.070 回答
1

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

于 2011-04-13T13:57:57.817 回答