scipy.optimize.leastsq 返回最佳猜测参数而不是新的最佳拟合 [英] scipy.optimize.leastsq returns best guess parameters not new best fit

查看:162
本文介绍了scipy.optimize.leastsq 返回最佳猜测参数而不是新的最佳拟合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将洛伦兹峰拟合到一组数据 x 和 y 中,数据很好.OriginLab 等其他程序非常适合它,但我想用 python 自动化拟合,所以我有以下基于 http://mesa.ac.nz/?page_id=1800

I want to fit a lorentzian peak to a set of data x and y, the data is fine. Other programs like OriginLab fit it perfectly, but I wanted to automate the fitting with python so I have the below code which is based on http://mesa.ac.nz/?page_id=1800

我遇到的问题是 scipy.optimize.leastsq 返回最适合我传递给它的相同初始猜测参数,基本上什么都不做.这是代码.

The problem I have is that the scipy.optimize.leastsq returns as the best fit the same initial guess parameters I passed to it, essentially doing nothing. Here is the code.

#x, y are the arrays with the x,y  axes respectively
#defining funcitons
def lorentzian(x,p):
  return p[2]*(p[0]**2)/(( x - (p[1]) )**2 + p[0]**2)

def residuals(p,y,x):
  err = y - lorentzian(x,p)
  return err      

p = [0.055, wv[midIdx], y[midIdx-minIdx]]   
pbest = leastsq(residuals, p, args=(y, x), full_output=1)
best_parameters = pbest[0]
print p
print pbest

p 是初始猜测,best_parameters 是从 leastsq 返回的最佳拟合"参数,但它们始终相同.

p are the initial guesses and best_parameters are the returned 'best fit' parameters from leastsq, but they are always the same.

这是 full_output=1 返回的内容(长数值数组已被缩短但仍具有代表性)

this is what returned by the full_output=1 (the long numeric arrays have been shortened but are still representitive)

    [0.055, 855.50732, 1327.0]
    (array([  5.50000000e-02,   8.55507324e+02,   1.32700000e+03]), 
    None, {'qtf':array([ 62.05192947,  69.98033905,  57.90628052]), 
    'nfev': 4, 
    'fjac': array([[-0.,  0.,  0., 0.,  0.,  0.,  0.,],
    [ 0., -0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.],
    [ 0.,  0., -0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
    0.,  0.]]), 
    'fvec': array([  62.05192947,   69.98033905,   
    53.41218567,   45.49879837,   49.58242035,   36.66483688,
    34.74443436,   50.82238007,   34.89669037]), 
    'ipvt': array([1, 2, 3])},  
    'The cosine of the angle between func(x) and any column of the\n  Jacobian 
    is at most 0.000000 in absolute value', 4)

谁能看出哪里出了问题?

can anyone see whats wrong?

推荐答案

一个快速的谷歌搜索暗示了数据是单精度的问题(你的其他程序几乎肯定也被提升到双精度,尽管这显然是一个问题scipy 也是如此,另请参阅此错误报告).如果您查看 full_output=1 结果,您会看到雅可比行列式在任何地方都近似为零.因此,明确给出雅可比行列式可能会有所帮助(尽管即使如此,您也可能想要向上转换,因为使用单精度可以获得的相对误差的最小精度非常有限).

A quick google search hints at a problem with the data being single precision (your other programs almost certainly upcast to double precision too, though this explicitely is a problem with scipy as well, see also this bug report). If you look at your full_output=1 result, you see the the Jacobian is approximated as zero everywhere. So giving the Jacobian explicitely might help (though even then you might want to upcast, because the minimum precision for a relative error you can get with single precision is just very limited).

解决方案:最简单且数值上最好的解决方案(当然,给出真正的雅可比行列式也是一个奖励)是只转换你的 xy 数据为双精度(例如,x = x.astype(np.float64) 即可).

Solution: the easiest and numerically best solution (of course giving the real Jacobian is also a bonus) is to just cast your x and y data to double precision (x = x.astype(np.float64) will do for example).

我不建议这样做,但您也可以通过手动设置 epsfcn 关键字参数(可能还有公差关键字参数)来修复它,沿着 epsfcn=np.finfo(np.float32).eps.这似乎以某种方式解决了这个问题,但是(因为大多数计算都是用标量进行的,而标量不会强制计算中的向上转换)计算是在 float32 中完成的,并且精度损失似乎相当大,至少在没有时提供 Dfunc.

I would not suggest this, but you also may be able to fix it by setting epsfcn keyword argument (and also the tolerance keyword arguments probably) by hand, something along epsfcn=np.finfo(np.float32).eps. This seems to fix the issue in a way, but (since most calculations are with scalars, and scalars do not force an upcast in your calculation) the calculations are done in float32 and the precision loss seem to be rather big, at least when not providing Dfunc.

这篇关于scipy.optimize.leastsq 返回最佳猜测参数而不是新的最佳拟合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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