2016-05-06 3 views
-2

Ich möchte die folgende Funktion zu lösen, so dass nach der Anpassung, ich den Wert x wenn y=0.5 erhalten möchte.Sigmoidale Kurve passen, wie der Wert von x erhalten, wenn y = 0,5

Die Funktion:

import numpy as np 
from scipy.optimize import curve_fit 

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

x_data = [4, 6, 8, 10] 
y_data = [0.86, 0.73, 0.53, 0.3] 

popt, pcov = curve_fit(sigmoid, x_data, y_data,(28.14,-0.25)) 

bitte erklären, wie würden Sie diese mit Python durchführen! Danke!

+0

wo 'curve_fit' kommen aus? – piRSquared

+0

@piRSquared Es ist 'scipy.optimize.curve_fit'. –

+0

Mögliches Duplikat von [Generierung der freilaufenden Liste der Stornorate und Ratenrate für die psychometrische Kurvenanpassung (Scipy)] (http://stackoverflow.com/questions/37044905/generation-of-free-running-list-of-lapse Raten-und-Rate-Rate-für-Psychometrie-Cu) –

Antwort

1

Wenn ich Ihren Code ausführen, erhalte ich eine Warnung, und popt ist das gleiche wie Ihre ursprüngliche Schätzung, (28.14, -0.25). Wenn Sie versuchen, diese Plotten werden Sie sehen, dass es im Wesentlichen eine gerade Linie bei y == 1, die Ihre Daten nicht gut überhaupt nicht passen:

from matplotlib import pyplot as plt 

x = np.linspace(4, 10, 1000) 
y = sigmoid(x, *popt) 

fig, ax = plt.subplots(1, 1) 
ax.hold(True) 
ax.scatter(x_data, y_data, s=50, zorder=20) 
ax.plot(x, y, '-k', lw=2) 

enter image description here

Das Problem ist, dass Sie mit einem sind Initialisierung negativer Wert für den Parameter b. Denken Sie daran, dass b negiert wird, so dass Sie tatsächlich potenzieren x mal eine positive Nummer, die Ihren Nenner sprengt. Stattdessen wollen Sie für b mit einem positiven Wert initialisieren, aber vielleicht ein negativer Wert für c (Sie Ihre negative Neigung geben):

popt2, pcov2 = curve_fit(sigmoid, x_data, y_data, (-0.5, 0.1)) 
y2 = sigmoid(x, *popt2) 

ax.plot(x, y2, '-r', lw=2) 

enter image description here


Um den Wert zu erhalten x bei y == 0.5 mit nichtlinearer Optimierung müssen Sie eine Zielfunktion definieren, die das Quadrat der Differenz zwischen 0.5 und sigmoid(x, b, c):

sein könnte
def objective(x, b, c): 
    return (0.5 - sigmoid(x, b, c)) ** 2 

können Sie dann scipy.optimize.minimize oder scipy.optimize.minimize_scalar, um den Wert von x zu finden, die die Zielfunktion minimiert:

from scipy.optimize import minimize_scalar 

res = minimize_scalar(objective, bracket=(4, 10), args=tuple(popt2)) 
ax.annotate("$y = 0.5$", (res.x, 0.5), (30, 30), textcoords='offset points', 
      arrowprops=dict(facecolor='black', shrink=0.05), fontsize='x-large') 

enter image description here