Levenberg-Marquardt算法与ODR的区别

时间:2012-07-04 13:32:06

标签: python scipy curve-fitting

我能够使用peak-o-mat将曲线拟合到x / y数据集,如下所示。这是一个线性背景和10洛伦兹曲线。 Peak-o-mat results

由于我需要拟合许多类似的曲线,我使用mpfit.py编写了一个脚本拟合例程,这是一个Levenberg-Marquardt算法。然而,拟合需要更长时间,并且在我看来,不如峰值结果更准确:

起始值 Starting values

使用固定线性背景拟合结果(从峰值结果中获取的线性背景值) Fit fixed

适应所有变量的结果 Fit free

我相信起始值已经非常接近,但即使使用固定的线性背景,左洛伦兹显然也是适合的退化。

总体自由适合的结果更糟。

Peak-o-mat似乎使用scipy.odr.odrpack。现在更有可能:

  1. 我做了一些实现错误?
  2. odrpack更适合这个特殊问题吗?
  3. 拟合一个更简单的问题(中间有一个峰值的线性数据)显示了峰值和我的脚本之间非常好的相关性。我也没有找到很多关于ordpack的信息。

    编辑: 我似乎可以自己回答这个问题,但答案有点令人不安。使用scipy.odr(允许使用odr或leastsq方法拟合)都可以将结果作为peak-o-mat,即使没有约束也是如此。

    下图再次显示数据,起始值(几乎完美),然后是odr和leastsq拟合。组件曲线用于odr one

    scipy.odr

    我会切换到odr,但这仍然让我心烦意乱。方法(mpfit.py,scipy.optimize.leastsq,scipy.odr in leastsq mode)'应该'产生相同的结果。

    对于那些在这篇文章上磕磕绊绊的人来说:要做好odr fit,必须为x和y值指定一个错误。如果没有错误,请使用sx<<的小值。 SY。

    linear = odr.Model(f)
    mydata = odr.RealData(x, y, sx = 1e-99, sy = 0.01)
    myodr = odr.ODR(mydata, linear, beta0 = beta0, maxit = 2000)
    myoutput1 = myodr.run() 
    

1 个答案:

答案 0 :(得分:1)

您也可以使用peak-o-mat进行脚本编写。最简单的方法是创建包含您想要通过GUI拟合的所有数据的项目,清理它,转换它并将基础模型附加(即选择模型,提供初始猜测和拟合)到其中一个集合。然后,您可以(深入)复制该模型并将其附加到所有其他数据集。试试这个:

from peak_o_mat.project import Project
from peak_o_mat.fit import Fit
from copy import deepcopy

p = Project()
p.Read('in.lpj')

base = p[2][0]    # this is the set which has been fit already

for data in p[2][1:]: # all remaining sets of plot number 2

    mod = deepcopy(base.mod)
    data.mod = mod

    f = Fit(data, data.mod)
    res = f.run()

    pars = res[0]
    err = res[1]

    data.mod._newpars(pars, err)

    print data.mod.parameters_as_table()

p.Write('out')

如果您需要更多详细信息,请告诉我。