Levenberg-Marquardt-Algorithm和ODR之间的区别 [英] Difference between Levenberg-Marquardt-Algorithm and ODR

查看:87
本文介绍了Levenberg-Marquardt-Algorithm和ODR之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够使用,它是Levenberg-Marquardt-Algorithm。但是,拟合需要更长的时间,并且在我看来,它不如O-mat峰结果准确:


起始值


具有固定线性背景的拟合结果 (从peak-o-mat结果中获取的线性背景值)


不带任何变量的拟合结果


我相信起始值已经非常接近,但是即使使用固定的线性背景,左洛伦兹定律显然也会降低拟合度。


对于完全自由运动的结果甚至更糟。


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


  1. 我犯了一些实现错误?

  2. odrpack更适合此特定问题?

拟合到一个更简单的问题(中间有一个峰的线性数据)显示,peak-o-mat与我的脚本之间具有很好的相关性。另外,我对ordpack的了解也不多。


编辑: 看来我可以自己回答这个问题,但是答案可以有点不安。即使没有任何限制,使用scipy.odr(允许使用odr或minimumsq方法进行拟合)都可以将结果显示为peak-o-mat。


下图再次显示了数据,即开始值(几乎完美),然后odr和Minimumsq适合。分量曲线是针对odr的



我将切换到odr,但这仍然让我不高兴。方法(mpfit.py,scipy.optimize.leastsq,scipy.odr(以Minimumsq模式)应该产生相同的结果。


对于那些绊倒这篇文章的人们: 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()


解决方案

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

  from peak_o_mat.project import项目
from peak_o_mat.fit import适合
从副本导入deepcopy

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

base = p [2] [0]#这是集合已适合p [2] [1:]中

的数据:#地块编号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')

请告诉我,是否需要更多详细信息。


I was able to fit curves to a x/y dataset using peak-o-mat, as shown below. Thats a linear background and 10 lorentzian curves.

Since I need to fit many similar curves I wrote a scripted fitting routine, using mpfit.py, which is a Levenberg-Marquardt-Algorithm. However the fit takes longer and, in my opinion, is less accurate than the peak-o-mat result:

Starting values

Fit result with fixed linear background (values for linear background taken from the peak-o-mat result)

Fit result with all variables free

I believe the starting values are already very close, but even with the fixed linear background, the left lorentzian is clearly a degradation of the fit.

The result is even worse for total free fit.

Peak-o-mat appears to use scipy.odr.odrpack. Now what is more likely:

  1. I did some implementation error?
  2. odrpack is more suitable for this particular problem?

Fitting to a more simple problem (linear data with one peak in the middle) shows very good correlation between peak-o-mat and my script. Also I did not find a lot about ordpack.

Edit: It seems I could answer the question by myself, however the answer is a bit unsettling. Using scipy.odr (which allows fitting with odr or leastsq method) both give the result as peak-o-mat, even without constraints.

The image below shows again the data, the start values (almost perfect) and then the odr and leastsq fits. The component curves are for the odr one

I will switch to odr, but this still leaves me upset. The methods (mpfit.py, scipy.optimize.leastsq, scipy.odr in leastsq mode) 'should' yield the same results.

And for people stumbling upon this post: to do the odr fit an error must be specified for x and y values. If there is no error, use small values with 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() 

解决方案

You can use peak-o-mat for scripting as well. The easiest would be to create project containing all data you want to fit via the GUI, clean it, transform it and attach (i.e. choose a model, provide an initial guess and fit) the base model to one of the sets. Then you can (deep)copy that model and attach it to all of the other data sets. Try this:

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')

Please tell me, if you need more details.

这篇关于Levenberg-Marquardt-Algorithm和ODR之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆