2015-02-09 71 views
2

我有两个列表,我试图做一个形式之间的指数拟合y = a * e ^(bx)。我使用的方法类似于here的第二个答案,但是结果与我从excel测试中得知的结果不匹配。这里是我的代码:2列表之间的指数拟合

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

+0

你有你的绘图配合和数据点? – 2015-02-09 16:22:57

+0

是的,看编辑添加到原始问题 – mbreezy 2015-02-09 16:55:53

回答

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

+0

感谢您的解释,一切似乎现在正常工作! – mbreezy 2015-02-09 19:25:44