Scipy最小二乘法中的正交回归拟合

14
scipy库中的leastsq方法可以将曲线拟合到一些数据上。该方法意味着在这些数据中,Y值取决于某些X参数,并计算曲线与数据点在Y轴(dy)上的最小距离。
但是,如果我需要计算两个轴(dy和dx)上的最小距离怎么办?
是否有某种方法来实现这种计算?
以下是使用单个轴计算时的代码示例:
import numpy as np
from scipy.optimize import leastsq

xData = [some data...]
yData = [some data...]

def mFunc(p, x, y):
    return y - (p[0]*x**p[1])  # is takes into account only y axis

plsq, pcov = leastsq(mFunc, [1,1], args=(xData,yData))
print plsq

我最近尝试了scipy.odr库,它只能为线性函数返回正确的结果。对于其他函数,比如y=a*x^b,它会返回错误的结果。这是我的使用方法:

def f(p, x):      
    return p[0]*x**p[1]

myModel = Model(f)
myData = Data(xData, yData)
myOdr = ODR(myData, myModel , beta0=[1,1])
myOdr.set_job(fit_type=0) #if set fit_type=2, returns the same as leastsq
out = myOdr.run()
out.pprint()

这返回错误的结果,不是想要的,有些输入数据甚至与真实情况差距很大。也许有一些特殊的使用方法,我做错了什么吗?


1
Scipy确实有一个用于“正交距离回归”的模块 - 这是你需要的吗?http://docs.scipy.org/doc/scipy/reference/odr.html - Thomas K
是的,它似乎解决了这个问题,但当我尝试时,它返回与leastsq方法相同的结果。我遵循文档中给出的示例,但它并没有按照所需的方式工作。你有一些可行的示例吗? - Vladimir
当我尝试时,发现结果是相似的,但并非完全相同 - 我认为这意味着额外的计算对拟合程度没有太大影响。 - Thomas K
3
我明白了!我已经找到解决方法。问题出在odr求解器的初始猜测参数(beta0参数)不当。 - Vladimir
4个回答

9
我找到了解决方案。Scipy Odrpack正常工作,但需要一个好的初始猜测才能得到正确的结果。因此,我将过程分为两步。

第一步:使用普通最小二乘法找到初始猜测。

第二步:将这些初始猜测替换为ODR中的beta0参数。

这样做速度可接受,效果非常好。

谢谢大家,你们的建议指引了我找到了正确的解决方案。


3
我知道这是一篇旧帖子,但您能否在此发布您的代码片段。我正在尝试做一个隐式ODR,但我不确定如何在scipy中设置它。 - Barbarossa
1
@Barbarossa 你可能会喜欢这段代码片段 - gerrit
2
这并不是一个真正的答案。你本应该分享代码的。 - Foad S. Farimani

8

scipy.odr 实现了正交距离回归。在docstring文档中可以查看基本使用说明。


哦,是的,我尝试了它,它与leastsq的工作方式相同,返回相同的结果。 - Vladimir
4
完全相同的结果?我觉得这不太可能。你能否更新你的帖子并展示一个可运行的使用scipy.odr的例子,以便演示出错误的结果? - Robert Kern

0

如果/当您能够反转由p描述的函数时,您可以在mFunc中包含x-pinverted(y),我猜测为sqrt(a^2+b^2),因此(伪代码)

return sqrt( (y - (p[0]*x**p[1]))^2 + (x - (pinverted(y))^2)

例如,对于

y=kx+m   p=[m,k]    
pinv=[-m/k,1/k]

return sqrt( (y - (p[0]+x*p[1]))^2 + (x - (pinv[0]+y*pinv[1]))^2)

但是你所要求的在某些情况下是有问题的。例如,如果一个多项式(或者你的x^j)曲线在y(m)处有最小值ym,而你有一个比ym更低的点x,y,那么你想返回什么样的值呢?并不总是有解。


如果点x,y小于ym,则应返回到该ym的最小距离。sqrt((m-x)^2 + (ym-y)^2)/2。为什么这是一个问题? - Vladimir
如果你有一个函数y=f(x),这意味着对于任何x都有一个y值。但并不是所有的输入y都有一个x值。并非所有的函数都是可逆的。例如,y=x^2和任何x=-2的点。 - Johan Lundberg
哦,我现在明白了,是的,你说得对。但是有些软件如何在任何输入数据上为任何函数构建这个总最小二乘(Deming回归)拟合。一定有一种方法可以在Python中实现它。 - Vladimir
我认为Deming回归是线性的,因此反转并不复杂。因此,它类似于我给出的线性示例。您的曲线不是线性的,也不可逆。 - Johan Lundberg

0

你可以在R中使用ONLS包。


1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接