numpy.polyfit与scipy.odr

时间:2014-07-17 13:03:29

标签: python numpy scipy curve-fitting

我有一个理论上用二次多项式描述的数据集。我想要拟合这些数据,并使用numpy.polyfit来完成此操作。但是,缺点是返回系数的误差不可用。因此,我决定使用scipy.odr来拟合数据。奇怪的是,多项式的系数彼此偏离。

我不明白这一点,因此决定在我自己生成的一组数据上测试两个拟合例程:

import numpy
import scipy.odr
import matplotlib.pyplot as plt

x = numpy.arange(-20, 20, 0.1)
y = 1.8 * x**2 -2.1 * x + 0.6 + numpy.random.normal(scale = 100, size = len(x))

#Define function for scipy.odr
def fit_func(p, t):
  return p[0] * t**2 + p[1] * t + p[2]

#Fit the data using numpy.polyfit
fit_np = numpy.polyfit(x, y, 2)

#Fit the data using scipy.odr
Model = scipy.odr.Model(fit_func)
Data = scipy.odr.RealData(x, y)
Odr = scipy.odr.ODR(Data, Model, [1.5, -2, 1], maxit = 10000)
output = Odr.run()
#output.pprint()
beta = output.beta
betastd = output.sd_beta

print "poly", fit_np
print "ODR", beta

plt.plot(x, y, "bo")
plt.plot(x, numpy.polyval(fit_np, x), "r--", lw = 2)
plt.plot(x, fit_func(beta, x), "g--", lw = 2)

plt.tight_layout()

plt.show()

结果的一个例子如下:

poly [ 1.77992643 -2.42753714  3.86331152]
ODR [   3.8161735   -23.08952492 -146.76214989]

enter image description here

在包含的图像中,numpy.polyfit(红色虚线)的解决方案相当吻合。 scipy.odr(绿色虚线)的解决方案基本上完全关闭。我必须注意,numpy.polyfitscipy.odr之间的差异在我想要的实际数据集中较少。但是,我不明白两者之间的差异来自何处,为什么在我自己的测试例子中差异非常大,哪种拟合程序更好?

我希望你能提供答案,这些答案可以帮助我更好地理解两个适合的惯例,并在此过程中为我提出的问题提供答案。

2 个答案:

答案 0 :(得分:7)

在您使用ODR的方式中,它会执行完整的正交距离回归。要让它进行正常的非线性最小二乘拟合

Odr.set_job(fit_type=2)

在开始优化之前,你会得到你期望的结果。

fit result

完整ODR失败的原因是由于未指定权重/标准偏差。显然,很难解释那个点云,并假设x和y的平等轮数。如果你提供估计的标准偏差,odr也会产生良好的结果(虽然当然不同)。

Data = scipy.odr.RealData(x, y, sx=0.1, sy=10)

答案 1 :(得分:0)

实际问题是odr输出的β系数与numpy.polyfit相反。因此绿色曲线计算不正确。要绘制它,请改为使用

plt.plot(x, fit_func(beta[::-1], x), "g--", lw = 2)