Подгонка сигмоидальной функции (кривая формы "S") к данным с использованием Python - PullRequest
3 голосов
/ 17 апреля 2019

Я пытаюсь приспособить сигмовидную функцию к некоторым имеющимся у меня данным, но продолжаю получать: ValueError: Unable to determine number of fit parameters.

Мои данные выглядят так:

enter image description here

Мой код:

from scipy.optimize import curve_fit

def sigmoid(x):
    return (1/(1+np.exp(-x)))

popt, pcov = curve_fit(sigmoid, xdata, ydata, method='dogbox')

Тогда я получаю:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-78540a3a23df> in <module>
      2     return (1/(1+np.exp(-x)))
      3 
----> 4 popt, pcov = curve_fit(sigmoid, xdata, ydata, method='dogbox')

~\Anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
    685         args, varargs, varkw, defaults = _getargspec(f)
    686         if len(args) < 2:
--> 687             raise ValueError("Unable to determine number of fit parameters.")
    688         n = len(args) - 1
    689     else:

ValueError: Unable to determine number of fit parameters.

Я не уверен, почему это не работает, это кажется тривиальнымдействие -> подогнать кривую к некоторой точке.Желаемая кривая будет выглядеть так:

enter image description here

Извините за графику .. Я сделал это в PowerPoint ...

Какя могу найти лучшую сигмовидную кривую (форма S)?

ОБНОВЛЕНИЕ

Благодаря @Brenlla я изменил свой код на:

def sigmoid(k,x,x0):
    return (1 / (1 + np.exp(-k*(x-x0))))

popt, pcov = curve_fit(sigmoid, xdata, ydata, method='dogbox')

Теперь я не получаю ошибку, но кривая не соответствует желаемому:

x = np.linspace(0, 1600, 1000)
y = sigmoid(x, *popt)

plt.plot(xdata, ydata, 'o', label='data')
plt.plot(x,y, label='fit')
plt.ylim(0, 1.3)
plt.legend(loc='best')

и результат:

enter image description here

Как я могу улучшить его, чтобы он лучше соответствовал данным?

ОБНОВЛЕНИЕ2

Код теперь:

def sigmoid(x, L,x0, k, b):
    y = L / (1 + np.exp(-k*(x-x0)))+b

Но результат все еще ...

enter image description here

UPDATE3

После большой помощи от @Brenlla theКод был изменен на:

def sigmoid(x, L ,x0, k, b):
    y = L / (1 + np.exp(-k*(x-x0)))+b
    return (y)

p0 = [max(ydata), np.median(xdata),1,min(ydata)] # this is an mandatory initial guess

popt, pcov = curve_fit(sigmoid, xdata, ydata,p0, method='dogbox')

И результат:

enter image description here

...