两个列表之间的指数拟合
Posted
技术标签:
【中文标题】两个列表之间的指数拟合【英文标题】:Exponential Fit Between 2 Lists 【发布时间】:2015-04-09 10:37:49 【问题描述】:我有两个列表,我试图在它们之间进行 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
【问题讨论】:
您是否绘制了适合度和数据点? 是的,请参阅添加到原始问题的编辑 【参考方案1】:我猜问题是你没有提供参数的初始猜测,所以as per the manual, curve_fit
使用 [1, 1] 作为猜测。然后,优化可能会卡在某个局部最小值。您应该做的另一件事是将xdata
和ydata
列表更改为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()
结果:
【讨论】:
感谢您的解释,现在似乎一切正常!以上是关于两个列表之间的指数拟合的主要内容,如果未能解决你的问题,请参考以下文章