这是我的代码(这是一段更大的代码示例):
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
完全相同的功能。
我在这里做错了什么?
答案 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