找到指数曲线拟合的初始猜测
finding initial guesses for exponential curve fit
所以我不知道该怎么做,而且我不确定是否有一些我现在完全忘记的数学,但我不知所措。简而言之,我有一些使用 scipy 和 numpy 的相当简单的初始代码,我想为其拟合指数曲线:
from scipy.optimize import curve_fit
import numpy as np
# sample data
x = np.array([7620., 7730., 7901., 8139., 8370., 8448., 8737., 8824., 9089., 9233., 9321., 9509., 9568., 9642., 9756., 9915., 10601., 10942.])
y = np.array([0.01228478, 0.01280466, 0.01363498, 0.01493918, 0.01530108, 0.01569484, 0.01628133, 0.01547824, 0.0171548, 0.01743745, 0.01776848, 0.01773898, 0.01839569, 0.01823377, 0.01843686, 0.01875542, 0.01881426, 0.01977975])
# define type of function to search
def model_func(x, a, k, b):
return a * np.exp(-k*x) + b
# curve fit
p0 = (2.e-6,300,1)
opt, pcov = curve_fit(model_func, x, y, p0)
a, k, b = opt
# test result
x2 = np.linspace(7228, 11000, 3000)
y2 = model_func(x2, a, k, b)
fig, ax = plt.subplots()
ax.plot(x2, y2, color='r', label='Fit. func: $f(x) = %.3f e^{%.3f x} %+.3f$' % (a,k,b))
ax.plot(x, y, 'bo', label='data with noise')
ax.legend(loc='best')
plt.show()
我的问题是 try as I may 我无法弄清楚 p0 的初始参数 - 我尝试了一系列值,但坦率地说,我不知道我在做什么,所以我没有得到这里的解决方案。有人可以建议怎么做吗?谢谢!
对我来说,这个数据更接近 lign 而不是指数曲线,你确定你的模型是正确的吗?
关于最初的猜测,我假设你对该函数没有任何进一步的了解,如果是的话就使用它:
对于 x->\inf 函数接近 b。所以我会为 b 使用大约 0.025 的猜测。
对于其他两个变量,取 x
和 y
的子样本并显式求解方程:
a * np.exp(-k*x[0]) + 0.025 = y[0]
a * np.exp(-k*x[-1]) + 0.025 = y[-1]
解决这个问题得到:
a = (y[0]-0.025)/np.exp(-k*x[0])
e^(-k*(x[-1]-x[0])=(y[-1]-0.025)/(y[0]-0.025) # and then take logarithm
k = -np.log((y[-1]-0.025)/(y[0]-0.025))/(x[-1]-x[0])
a = (y[0]-0.025)/np.exp(-k*x[0])
给出 k=0.00026798747972760543
和 a=-0.80114087848462689
这个方法可以通用,根据需要丢弃尽可能多的点来精确求解方程,然后使用这些值作为初始最优值
所以我不知道该怎么做,而且我不确定是否有一些我现在完全忘记的数学,但我不知所措。简而言之,我有一些使用 scipy 和 numpy 的相当简单的初始代码,我想为其拟合指数曲线:
from scipy.optimize import curve_fit
import numpy as np
# sample data
x = np.array([7620., 7730., 7901., 8139., 8370., 8448., 8737., 8824., 9089., 9233., 9321., 9509., 9568., 9642., 9756., 9915., 10601., 10942.])
y = np.array([0.01228478, 0.01280466, 0.01363498, 0.01493918, 0.01530108, 0.01569484, 0.01628133, 0.01547824, 0.0171548, 0.01743745, 0.01776848, 0.01773898, 0.01839569, 0.01823377, 0.01843686, 0.01875542, 0.01881426, 0.01977975])
# define type of function to search
def model_func(x, a, k, b):
return a * np.exp(-k*x) + b
# curve fit
p0 = (2.e-6,300,1)
opt, pcov = curve_fit(model_func, x, y, p0)
a, k, b = opt
# test result
x2 = np.linspace(7228, 11000, 3000)
y2 = model_func(x2, a, k, b)
fig, ax = plt.subplots()
ax.plot(x2, y2, color='r', label='Fit. func: $f(x) = %.3f e^{%.3f x} %+.3f$' % (a,k,b))
ax.plot(x, y, 'bo', label='data with noise')
ax.legend(loc='best')
plt.show()
我的问题是 try as I may 我无法弄清楚 p0 的初始参数 - 我尝试了一系列值,但坦率地说,我不知道我在做什么,所以我没有得到这里的解决方案。有人可以建议怎么做吗?谢谢!
对我来说,这个数据更接近 lign 而不是指数曲线,你确定你的模型是正确的吗?
关于最初的猜测,我假设你对该函数没有任何进一步的了解,如果是的话就使用它:
对于 x->\inf 函数接近 b。所以我会为 b 使用大约 0.025 的猜测。
对于其他两个变量,取 x
和 y
的子样本并显式求解方程:
a * np.exp(-k*x[0]) + 0.025 = y[0]
a * np.exp(-k*x[-1]) + 0.025 = y[-1]
解决这个问题得到:
a = (y[0]-0.025)/np.exp(-k*x[0])
e^(-k*(x[-1]-x[0])=(y[-1]-0.025)/(y[0]-0.025) # and then take logarithm
k = -np.log((y[-1]-0.025)/(y[0]-0.025))/(x[-1]-x[0])
a = (y[0]-0.025)/np.exp(-k*x[0])
给出 k=0.00026798747972760543
和 a=-0.80114087848462689
这个方法可以通用,根据需要丢弃尽可能多的点来精确求解方程,然后使用这些值作为初始最优值