Scipy Curve_fit: Почему мой фитинг так плох и как его улучшить? - PullRequest
1 голос
/ 05 июня 2019

Я пытаюсь подогнать свои данные, используя библиотеку кривой python.Хотя я могу зафиксировать структуру данных, реальная подгонка довольно скудная.Можно ли как-нибудь улучшить качество посадки?

enter image description here

Вот мой код:

import numpy as np
from scipy.optimize import curve_fit
from matplotlib import pyplot as plt

x=np.array([ 4.29977288,  4.18759576,  3.937875  ,  3.68784896,  3.43711213,
    3.19099287,  2.94166468,  2.68543877,  2.4289324 ,  2.19035861,
    1.93962193,  1.69285434,  1.44271633,  1.18869615,  0.94761142,
    0.69828307,  0.44606364,  0.19355101, -0.05367106, -0.30303661,
   -0.55272018, -0.79877747, -1.04806864, -1.29706657, -1.54567223,
   -1.79685098, -2.05011095, -2.29874144, -2.54813208, -2.80178461,
   -3.04828379, -3.29893363, -3.54727073, -3.79908534, -4.04661293]);

y=np.array([ 20.8744534 ,  20.89824536,  20.3763843 ,  19.79924837,
    19.19485964,  18.57716717,  17.93772371,  17.28834168,
    16.62367817,  15.94336213,  15.24389099,  14.52471466,
    13.7787734 ,  13.00299723,  12.18721413,  11.31510566,
    10.36672642,   9.32224105,   8.14237084,   6.78034367,
     5.19700447,   3.32945537,   1.10437136,  -1.48805508,
    -4.25695201,  -6.94906329,  -9.41648974, -11.54747381,
   -13.33444597, -14.90663076, -16.36783375, -17.72241553,
   -18.9592222 , -20.06703821, -21.07669491])

def func(x,A,B,C):
    a=1+B/A
    b=1-B/A
    k=C/np.log(a/b)
    y=A*np.tanh((x-C)/(2*k))
    return y

A_0=25
B_0=10
C_0=1.2


popt,pcov = curve_fit(func,x,y,p0=[A_0,B_0,C_0])
print(pcov)

plt.plot(x,y,label='Data')
plt.plot(x,func(x, *popt),'.',label='Fit')
plt.legend()
plt.show()

Ответы [ 3 ]

2 голосов
/ 05 июня 2019

Я не уверен, что вы обязаны использовать такие функции, которые используете, или вы также можете жить с полиномом. В последнем случае вы можете использовать polyfit.

Помните, что вы не можете просто использовать любой многочлен высшего порядка, иначе вы в конечном итоге перегрузите свои данные. Вы можете посмотреть среднеквадратичную ошибку подбора, чтобы оценить ее точность

fit = np.poly1d(np.polyfit(x, y, 5))

plt.plot(x, y, '.', label='Data')
plt.plot(x, fit(x), label='Fit')
plt.legend()

enter image description here

2 голосов
/ 05 июня 2019

это не проблема curve_fit, а функции, которую вы используете.Найти функцию, которая будет выполнять эту работу, не всегда легко, но функция ошибок, например, работает намного лучше:

import numpy as np
from scipy import special
from scipy.optimize import curve_fit
from matplotlib import pyplot as plt

x=np.array([ 4.29977288,  4.18759576,  3.937875  ,  3.68784896,  3.43711213,
    3.19099287,  2.94166468,  2.68543877,  2.4289324 ,  2.19035861,
    1.93962193,  1.69285434,  1.44271633,  1.18869615,  0.94761142,
    0.69828307,  0.44606364,  0.19355101, -0.05367106, -0.30303661,
   -0.55272018, -0.79877747, -1.04806864, -1.29706657, -1.54567223,
   -1.79685098, -2.05011095, -2.29874144, -2.54813208, -2.80178461,
   -3.04828379, -3.29893363, -3.54727073, -3.79908534, -4.04661293]);

y=np.array([ 20.8744534 ,  20.89824536,  20.3763843 ,  19.79924837,
    19.19485964,  18.57716717,  17.93772371,  17.28834168,
    16.62367817,  15.94336213,  15.24389099,  14.52471466,
    13.7787734 ,  13.00299723,  12.18721413,  11.31510566,
    10.36672642,   9.32224105,   8.14237084,   6.78034367,
     5.19700447,   3.32945537,   1.10437136,  -1.48805508,
    -4.25695201,  -6.94906329,  -9.41648974, -11.54747381,
   -13.33444597, -14.90663076, -16.36783375, -17.72241553,
   -18.9592222 , -20.06703821, -21.07669491])

def func(x,A,B,C):
    a=1+B/A
    b=1-B/A
    k=C/np.log(a/b)
    y=A*np.tanh((x-C)/(2*k))
    return y

def erf(x, a, b, c, d):
    return d + 0.5*c*(1 + special.erf(a*(x-b)))

A_0=25
B_0=10
C_0=1.2


popt,pcov = curve_fit(func,x,y,p0=[A_0,B_0,C_0])
perf, pecov = curve_fit(erf, x, y, p0=(0.5,0,40,-20))

plt.plot(x,y, 'o', label='Data')
plt.plot(x,func(x, *popt),'-',label='Fit')
plt.plot(x, erf(x, *perf), '--', label='erf fit')
plt.legend()
plt.show()

enter image description here

0 голосов
/ 05 июня 2019

Я подумал, что, возможно, сигмоидное или пиковое уравнение может моделировать данные, и вот примеры графиков пикового уравнения и ошибок моделирования:

models errors

Это как если бы было два комбинированных сигнала, один из которых является циклическим сигналом низкой амплитуды.Этот второй сигнал не простая синусоида.Я думаю, что вам может понадобиться сложная модель, которая является суммой двух разных уравнений, чтобы объединить оба эти компонента в одну модель.

...