两个列表之间的指数拟合

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] 作为猜测。然后,优化可能会卡在某个局部最小值。您应该做的另一件事是将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()

结果:

【讨论】:

感谢您的解释,现在似乎一切正常!

以上是关于两个列表之间的指数拟合的主要内容,如果未能解决你的问题,请参考以下文章

什么是拟合指数?

R I 绘制对数 - 指数拟合的置信区间

回归分析的判定系数等于1是啥原因

最小二乘拟合(转)

matlab中怎么根据已经出来的两根曲线,去画出这两个曲线之间的相差值曲线,就像这两个图,怎么计算相差

拟合曲线时,R2值为负值表示啥意思