Ответ 1
Первый комментарий: поскольку a*exp(b - c*x) = (a*exp(b))*exp(-c*x) = A*exp(-c*x)
, a
или b
является избыточным. Я уроню b
и использую:
def func(x, a, c, d):
return a*np.exp(-c*x)+d
Это не главная проблема. Проблема в том, что curve_fit
не может сходиться к решению этой проблемы, когда вы используете начальное предположение по умолчанию (это все 1s). Проверьте pcov
; вы увидите, что это inf
. Это неудивительно, потому что если c
равно 1, большинство значений exp(-c*x)
underflow равно 0:
In [32]: np.exp(-x)
Out[32]:
array([ 2.45912644e-174, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000, 0.00000000e+000, 0.00000000e+000,
0.00000000e+000])
Это говорит о том, что c
должно быть небольшим. Лучшее исходное предположение, скажем, p0 = (1, 1e-6, 1)
. Затем я получаю:
In [36]: popt, pcov = curve_fit(func, x, y, p0=(1, 1e-6, 1))
In [37]: popt
Out[37]: array([ 1.63561656e+02, 9.71142196e-04, -1.16854450e+00])
Это выглядит разумно:
In [42]: xx = np.linspace(300, 6000, 1000)
In [43]: yy = func(xx, *popt)
In [44]: plot(x, y, 'ko')
Out[44]: [<matplotlib.lines.Line2D at 0x41c5ad0>]
In [45]: plot(xx, yy)
Out[45]: [<matplotlib.lines.Line2D at 0x41c5c10>]