web-dev-qa-db-fra.com

Ajustement de courbe sigmoïde Scipy

J'ai quelques points de données et je voudrais trouver une fonction appropriée, je suppose qu'une fonction sigmoïde gaussienne cumulative conviendrait, mais je ne sais pas vraiment comment le réaliser.

Voici ce que j'ai en ce moment:

import numpy as np
import pylab
from scipy.optimize
import curve_fit

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

xdata = np.array([400, 600, 800, 1000, 1200, 1400, 1600])
ydata = np.array([0, 0, 0.13, 0.35, 0.75, 0.89, 0.91])

popt, pcov = curve_fit(sigmoid, xdata, ydata)
print(popt)

x = np.linspace(-1, 2000, 50)
y = sigmoid(x, *popt)

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

Mais je reçois l'avertissement suivant:

.../scipy/Optimize/minpack.py: 779: OptimizeWarning: La covariance des paramètres n'a pas pu être estimée category = OptimizeWarning)

Quelqu'un peut-il aider? Je suis également ouvert à toute autre possibilité de le faire! J'ai juste besoin d'une courbe adaptée de quelque façon que ce soit à ces données.

6
Johanna Köllner

Vous pouvez définir des limites raisonnables pour les paramètres, par exemple, faire

def fsigmoid(x, a, b):
    return 1.0 / (1.0 + np.exp(-a*(x-b)))

popt, pcov = curve_fit(fsigmoid, xdata, ydata, method='dogbox', bounds=([0., 600.],[0.01, 1200.]))

J'ai une sortie

[7.27380294e-03 1.07431197e+03]

et la courbe ressemble

enter image description here

Le premier point à (400,0) a été supprimé car inutile. Vous pouvez l'ajouter, mais le résultat ne changera pas grand-chose ...

METTRE À JOUR

Notez que les limites sont définies comme ([low_a, low_b], [high_a, high_b]), j'ai donc demandé que l'échelle soit dans [0 ... 0,01] et l'emplacement dans [600 ... 1200]

1
Severin Pappadeux

Vous avez peut-être remarqué que l'ajustement résultant est complètement incorrect. Essayez de passer des paramètres initiaux décents à curve_fit, avec le p0 argument:

popt, pcov = curve_fit(sigmoid, xdata, ydata, p0=[1000, 0.001])

devrait donner un bien meilleur ajustement, et probablement aucun avertissement non plus.

(Les paramètres de démarrage par défaut sont [1, 1]; c'est trop loin des paramètres réels pour obtenir un bon ajustement.)

3
9769953