2个列表之间的指数拟合

时间:2015-02-09 16:05:56

标签: python numpy scipy

我有两个列表,我试图以y = a * e ^(bx)之间的形式进行指数拟合。我正在使用类似于here的第二个答案的方法,但结果与我使用excel测试时所知的结果不符。这是我的代码:

import numpy as np
from scipy.optimize import curve_fit
exp_constants = [62.5, 87.5, 112.5, 137.5, 162.5, 187.5, 212.5, 237.5, 262.5, 287.5]
means = [211.94, 139.30, 80.09, 48.29, 26.94, 12.12, 3.99, 1.02, 0.09, 0.02]
def func(x1, a, b):
  return a * np.exp(b * x1)
popt, pcov = curve_fit(func, exp_constants, means)

返回popt[0]popt[1]时,我分别得到3.222e-127和1.0。但是,使用excel检查时,正确的指数方程应为y = 7231.3e ^( - 0.04x)。我对curve_fit方法不是很熟悉,我的代码中是否存在某些内容,或者是否有更好的方法来获得正确的指数拟合?

编辑:这是使用以下代码制作的情节:

plt.figure()
plt.plot(exp_constants, means, 'ko', label="Data")
plt.plot(exp_constants, func(exp_constants, *popt), 'r-', label="Fitted Curve")
plt.legend()
plt.show

plot

1 个答案:

答案 0 :(得分:5)

我想问题是你没有提供参数的初始猜测,所以as per the manualcurve_fit使用[1,1]作为猜测。然后,优化可能会陷入局部最小值。您应该做的另一件事是将xdataydata列表更改为numpy数组,如this answer所示:

import numpy as np
from scipy.optimize import curve_fit
exp_constants = np.array([62.5, 87.5, 112.5, 137.5, 162.5, 187.5, 212.5,
                          237.5, 262.5, 287.5])
means = np.array([211.94, 139.30, 80.09, 48.29, 26.94, 12.12, 3.99,
                  1.02, 0.09, 0.02])
def func(x1, a, b):
  return a * np.exp(b * x1)
guess = [100, -0.1]
popt, pcov = curve_fit(func, exp_constants, means, p0 = guess)

猜测的确切值并不重要,但您应该至少具有数量级和符号,以便优化可以收敛到最佳值。我只是使用了一些接近正确答案的随机数字'你提到过。当您不知道猜测什么时,您可以执行polyfit(xdata, log(ydata), 1)和一些基本数学运算来获得初始值,如this answer所示,您所关联的问题就会显示。

快速情节:

x = np.linspace(exp_constants[0], exp_constants[-1], 1000)
plt.plot(exp_constants, means, 'ko', x, popt[0]*np.exp(popt[1]*x), 'r')
plt.show()

结果:

enter image description here