奇怪的结果与python的(scipy)曲线拟合

时间:2013-06-04 23:34:07

标签: python scipy curve-fitting

这是我的代码(这是一段更大的代码示例):

from scipy.optimize import curve_fit

def func(x, a, b):
   return a + b*x

xlist = [10, 30, 50, 70, 90, 110, 130, 150, 170, 190, 210, 230]
ylist = [0.0074999999999999997, 0.011875, 0.0057812499999999999, 0.0036458333333333334, 0.0020312500000000001, 0.0013125000000000001, 0.00098958333333333342, 0.00089285714285714283, 0.00074218750000000001, 0.00093749999999999997, 0.00071874999999999999, 0.00088068181818181821]

popt, pcov = curve_fit(func, xlist, ylist)

print(popt[0], popt[1])

正如您所看到的,我正在尝试使用非常简单的a + b*x函数进行非常简单的拟合。问题是这会返回值:

(-119.99689110581872, 1.0)

代表a=popt[0]b=popt[1],但与zunzun.com相同,可以提供更合理的值:

a = 7.8372289537296004E-03
b = -3.9402329475524466E-05

完全相同的功能。

我在这里做错了什么?


修改

下面的Warren说这可能是个错误。我应该这样报告,还是预期的行为?

2 个答案:

答案 0 :(得分:3)

如果将xlist中的值更改为numpy数组,则可以正常工作:

In [38]: popt, pcov = curve_fit(func, array(xlist, dtype=float), ylist)

In [39]: popt
Out[39]: array([  7.83722896e-03,  -3.94023294e-05])

首先,这看起来像一个错误,但是发生的事情是底层代码接受参数xdata并将未更改传递给您的函数。在您的示例中,这意味着在表达式a + b*x中,x是一个Python列表。 意味着b*x没有进行您想要的计算。

因此,为了使func定义工作,参数xdata必须是一个numpy数组。或者,您可以这样定义func

def func(x, a, b):
    return a + b*np.asarray(x)

答案 1 :(得分:2)

如果我没记错的话,scipy曲线拟合例程的默认初始参数都是1.0。虽然这适用于简单的情况,例如直线 - 因为误差空间对于直线曲线拟合更简单 - 如果您尝试适合误差空间“凹凸不平”的地方,您可能会再次看到结果与zunzun的结果之间的差异.COM。

如果您对最佳解决方案应该存在的正确值(或值范围)有所了解,那么使用这些值启动scipy例程几乎在所有情况下都会比从所有值开始提供更好的结果。

虽然zunzun.com允许输入初始参数“估计” - 或猜测 - 网站不要求这些参数,因为遗传算法用于确定初始参数估计。 zunzun.com网站的BSD许可Python配件源代码位于

http://code.google.com/p/pyeq2/

它附带了很多例子。查看zunzun.com网页的底部以获取代码的链接。如果您有任何问题,请告诉我,我很乐意提供帮助。

詹姆斯菲利普斯 zunzun@zunzun.com