Я пытаюсь приспособить функцию вида a*tanh(b*x) + c
к моим данным, которая выглядит следующим образом:
x = [1. , 2., 3., 5., 6., 10., 15., 30.]
y = [1., 1.81498639, 2.51864814, 3.54771826, 3.99775936, 5.74444049,
8.06357414, 12.82164541]
Я использую scipy.optimize.curve_fit
и получаю только неправильные результаты, что привело кна этом графике: Сначала я подумал, что, возможно, мое первоначальное предположение было неверным / его необходимо было предоставить, поэтому я вручную приблизил хорошее соответствие, а затем предоставил эти значения как p0
arg to curve_fit()
. Это привело только к еще худшему приближению, когда кривая была поднята примерно на 1000 единиц по оси Y над данными.
Как может быть такое отклонение? Нужно ли указывать больше аргументов для функции curve_fit для получения разумных результатов?
Сообщение об ошибке:
OptimizeWarning: ковариация параметров не может быть оценена категория = OptimizeWarning
Мой код:
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
def fit(a,b,c,X):
eq = a*np.tanh(b*X) + c
return eq
def check_plot(x,y,lam,tp,mol,X,Y):
'''
Creates a plot of s_ineff vs t_block to check
for correct selection of block sizes, which
still produce consistent results.
'''
fig, ax = plt.subplots(figsize=(7,4))
ax.scatter(x,y)
ax.plot(X,Y,c='r')
ax.set_ylabel(r'$s_{ineff}$')
ax.set_xlabel(r'$\tau_{Block}$')
ax.text(0.04, 0.95,
'%s\n$\lambda_{%s} = %s$'%(mol,tp,lam),
horizontalalignment='left',
verticalalignment='top',
transform=ax.transAxes)
# plt.savefig("fitti.png",bbox_inches="tight",dpi=300)
plt.show()
plt.close(fig)
x = np.array([1. , 2., 3., 5., 6., 10., 15., 30.])
y = np.array([1., 1.81498639, 2.51864814, 3.54771826, 3.99775936, 5.74444049,
8.06357414, 12.82164541])
parms, parms_cov = optimize.curve_fit(fit, x, y)
a,b,c = parms[0],parms[1],parms[2]
# good initial guess: p0=[13,0.05,0.6]
X,Y = x,fit(a,b,c,x)
mol,tp,lam = 'toluene','elec',0.15
check_plot(x,y,lam,tp,mol,X,Y)