scipy.optimize терпит неудачу с очень хорошим начальным предположением - PullRequest
2 голосов
/ 04 ноября 2019

Я пытаюсь приспособить функцию вида 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 и получаю только неправильные результаты, что привело кна этом графике: Failed regression Сначала я подумал, что, возможно, мое первоначальное предположение было неверным / его необходимо было предоставить, поэтому я вручную приблизил хорошее соответствие, а затем предоставил эти значения как 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...