scipy.optimize.

curve_fit#

scipy.optimize.curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=None, bounds=(-inf, inf), method=None, jac=None, *, full_output=False, nan_policy=None, **kwargs)[Quelle]#

Verwendet nichtlineare kleinste Quadrate, um eine Funktion f an Daten anzupassen.

Nimmt an, dass ydata = f(xdata, *params) + eps.

Parameter:
faufrufbar

Die Modellfunktion, f(x, …). Sie muss die unabhängige Variable als erstes Argument und die anzupassenden Parameter als separate verbleibende Argumente enthalten.

xdataarray_like

Die unabhängige Variable, an der die Daten gemessen werden. Sollte normalerweise eine Sequenz der Länge M sein oder ein Array der Form (k,M) für Funktionen mit k Prädiktoren, und jedes Element sollte float-konvertierbar sein, wenn es sich um ein Array-ähnliches Objekt handelt.

ydataarray_like

Die abhängigen Daten, ein Array der Länge M – nominell f(xdata, ...).

p0array_like, optional

Anfangsschätzung für die Parameter (Länge N). Wenn None, dann sind die Anfangswerte alle 1 (wenn die Anzahl der Parameter für die Funktion durch Introspektion bestimmt werden kann, andernfalls wird ein ValueError ausgelöst).

sigmaNone oder Skalar oder Sequenz der Länge M oder MxM-Array, optional

Bestimmt die Unsicherheit in ydata. Wenn wir Residuen als r = ydata - f(xdata, *popt) definieren, dann hängt die Interpretation von sigma von seiner Dimensionalität ab

  • Ein Skalar oder 1D sigma sollte Werte der Standardabweichungen von Fehlern in ydata enthalten. In diesem Fall ist die optimierte Funktion chisq = sum((r / sigma) ** 2).

  • Ein 2D sigma sollte die Kovarianzmatrix der Fehler in ydata enthalten. In diesem Fall ist die optimierte Funktion chisq = r.T @ inv(sigma) @ r.

    Hinzugefügt in Version 0.19.

None (Standard) ist äquivalent zu 1D sigma, gefüllt mit Einsen.

absolute_sigmabool, optional

Wenn True, wird sigma absolut verwendet und die geschätzte Parameterkovarianz pcov spiegelt diese absoluten Werte wider.

Wenn False (Standard), sind nur die relativen Größen der sigma-Werte relevant. Die zurückgegebene Parameterkovarianzmatrix pcov basiert auf der Skalierung von sigma um einen konstanten Faktor. Diese Konstante wird so bestimmt, dass die reduzierte chisq für die optimalen Parameter popt bei Verwendung des *skalierten* sigma gleich eins ist. Anders ausgedrückt, sigma wird skaliert, um die Stichprobenvarianz der Residuen nach der Anpassung anzupassen. Standard ist False. Mathematisch gilt pcov(absolute_sigma=False) = pcov(absolute_sigma=True) * chisq(popt)/(M-N)

check_finitebool, optional

Wenn True, wird überprüft, ob die Eingabearrays keine NaNs oder Inf-Werte enthalten, und ein ValueError ausgelöst, falls dies der Fall ist. Das Setzen dieses Parameters auf False kann stillschweigend unsinnige Ergebnisse liefern, wenn die Eingabearrays NaNs enthalten. Standard ist True, wenn nan_policy nicht explizit angegeben ist, und andernfalls False.

bounds2-Tupel aus array_like oder Bounds, optional

Untere und obere Schranken für die Parameter. Standard ist keine Schranken. Es gibt zwei Möglichkeiten, die Schranken anzugeben

  • Instanz der Klasse Bounds.

  • 2-Tupel aus array_like: Jedes Element des Tupels muss entweder ein Array mit der Länge gleich der Anzahl der Parameter sein oder ein Skalar (in diesem Fall wird die Schranke für alle Parameter gleich angenommen). Verwenden Sie np.inf mit dem entsprechenden Vorzeichen, um Schranken für alle oder einige Parameter zu deaktivieren.

method{‘lm’, ‘trf’, ‘dogbox’}, optional

Zu verwendende Methode für die Optimierung. Weitere Details finden Sie unter least_squares. Standard ist ‘lm’ für unbeschränkte Probleme und ‘trf’, wenn bounds angegeben sind. Die Methode ‘lm’ funktioniert nicht, wenn die Anzahl der Beobachtungen kleiner ist als die Anzahl der Variablen, verwenden Sie in diesem Fall ‘trf’ oder ‘dogbox’.

Hinzugefügt in Version 0.17.

jaccallable, string oder None, optional

Funktion mit der Signatur jac(x, ...), die die Jacobi-Matrix der Modellfunktion in Bezug auf die Parameter als dichtes Array-ähnliches Gebilde berechnet. Sie wird gemäß dem bereitgestellten sigma skaliert. Wenn None (Standard), wird die Jacobi-Matrix numerisch geschätzt. String-Schlüsselwörter für die Methoden ‘trf’ und ‘dogbox’ können verwendet werden, um ein Schema für endliche Differenzen auszuwählen, siehe least_squares.

Hinzugefügt in Version 0.18.

full_outputboolean, optional

Wenn True, gibt diese Funktion zusätzliche Informationen zurück: infodict, mesg und ier.

Hinzugefügt in Version 1.9.

nan_policy{‘raise’, ‘omit’, None}, optional

Definiert, wie mit NaNs in den Eingaben umgegangen wird. Die folgenden Optionen sind verfügbar (Standard ist None)

  • ‘raise’: löst einen Fehler aus

  • ‘omit’: führt die Berechnungen unter Ignorierung von NaN-Werten durch

  • None: es wird keine spezielle Behandlung von NaNs durchgeführt (außer dem, was von check_finite getan wird); das Verhalten bei Vorhandensein von NaNs ist implementierungsabhängig und kann sich ändern.

Beachten Sie, dass, wenn dieser Wert explizit angegeben wird (nicht None), check_finite auf False gesetzt wird.

Hinzugefügt in Version 1.11.

**kwargs

Schlüsselwortargumente, die an leastsq für method='lm' oder ansonsten an least_squares übergeben werden.

Rückgabe:
poptarray

Optimale Werte für die Parameter, so dass die Summe der quadrierten Residuen von f(xdata, *popt) - ydata minimiert wird.

pcov2-D-Array

Die geschätzte approximative Kovarianz von popt. Die Diagonalen geben die Varianz der Parameterschätzung an. Um Fehler mit einer Standardabweichung auf die Parameter zu berechnen, verwenden Sie perr = np.sqrt(np.diag(pcov)). Beachten Sie, dass die Beziehung zwischen cov und den Schätzungen der Parameterunsicherheit auf einer linearen Annäherung der Modellfunktion um das Optimum basiert [1]. Wenn diese Annäherung ungenau wird, liefert cov möglicherweise keine genaue Unsicherheitsmessung.

Wie der sigma-Parameter die geschätzte Kovarianz beeinflusst, hängt vom Argument absolute_sigma ab, wie oben beschrieben.

Wenn die Jacobi-Matrix am Lösungsort keinen vollen Rang hat, gibt die Methode ‘lm’ eine Matrix zurück, die mit np.inf gefüllt ist. Andererseits verwenden die Methoden ‘trf’ und ‘dogbox’ die Moore-Penrose-Pseudoinverse, um die Kovarianzmatrix zu berechnen. Kovarianzmatrizen mit großen Konditionszahlen (z.B. berechnet mit numpy.linalg.cond) können darauf hindeuten, dass die Ergebnisse unzuverlässig sind.

infodictdict (nur zurückgegeben, wenn full_output True ist)

ein Dictionary optionaler Ausgaben mit den Schlüsseln

nfev

Die Anzahl der Funktionsaufrufe. Die Methoden ‘trf’ und ‘dogbox’ zählen keine Funktionsaufrufe für die numerische Jacobi-Approximation, im Gegensatz zur Methode ‘lm’.

fvec

Die Residuenwerte, die an der Lösung ausgewertet wurden; für ein 1D- sigma ist dies (f(x, *popt) - ydata)/sigma.

fjac

Eine Permutation der R-Matrix einer QR-Zerlegung der endgültigen approximierten Jacobi-Matrix, spaltenweise gespeichert. Zusammen mit ipvt kann die Kovarianz der Schätzung approximiert werden. Methode ‘lm’ liefert nur diese Informationen.

ipvt

Ein Integer-Array der Länge N, das eine Permutationsmatrix p definiert, so dass fjac*p = q*r, wobei r obere Dreiecksmatrix mit Diagonalelementen abnehmender Größe ist. Spalte j von p ist Spalte ipvt(j) der Identitätsmatrix. Methode ‘lm’ liefert nur diese Informationen.

qtf

Der Vektor (transpose(q) * fvec). Methode ‘lm’ liefert nur diese Informationen.

Hinzugefügt in Version 1.9.

mesgstr (nur zurückgegeben, wenn full_output True ist)

Eine Meldung, die Informationen über die Lösung liefert.

Hinzugefügt in Version 1.9.

ierint (nur zurückgegeben, wenn full_output True ist)

Ein Integer-Flag. Wenn es gleich 1, 2, 3 oder 4 ist, wurde die Lösung gefunden. Andernfalls wurde die Lösung nicht gefunden. In beiden Fällen liefert die optionale Ausgabevariable mesg weitere Informationen.

Hinzugefügt in Version 1.9.

Löst aus:
ValueError

wenn entweder ydata oder xdata NaNs enthalten oder wenn inkompatible Optionen verwendet werden.

RuntimeError

wenn die Minimierung der kleinsten Quadrate fehlschlägt.

OptimizeWarning

wenn die Kovarianz der Parameter nicht geschätzt werden kann.

Siehe auch

least_squares

Minimiert die Summe der Quadrate nichtlinearer Funktionen.

scipy.stats.linregress

Berechnet eine lineare Regression nach der Methode der kleinsten Quadrate für zwei Datensätze.

Hinweise

Benutzer sollten sicherstellen, dass die Eingaben xdata, ydata und die Ausgabe von f vom Typ float64 sind, da sonst die Optimierung falsche Ergebnisse liefern kann.

Mit method='lm' verwendet der Algorithmus den Levenberg-Marquardt-Algorithmus über leastsq. Beachten Sie, dass dieser Algorithmus nur unbeschränkte Probleme behandeln kann.

Box-Beschränkungen können mit den Methoden ‘trf’ und ‘dogbox’ behandelt werden. Weitere Informationen finden Sie im Docstring von least_squares.

Parameter, die angepasst werden sollen, müssen eine ähnliche Skalierung aufweisen. Unterschiede von mehreren Größenordnungen können zu falschen Ergebnissen führen. Für die Methoden ‘trf’ und ‘dogbox’ kann das Schlüsselwortargument x_scale zur Skalierung der Parameter verwendet werden.

curve_fit dient der lokalen Optimierung von Parametern zur Minimierung der Summe der quadrierten Residuen. Für globale Optimierung, andere Wahlmöglichkeiten der Zielfunktion und andere fortgeschrittene Funktionen sollten Sie die Globalen Optimierungswerkzeuge von SciPy oder das Paket LMFIT in Betracht ziehen.

Referenzen

[1]

K. Vugrin et al. Confidence region estimation techniques for nonlinear regression in groundwater flow: Three case studies. Water Resources Research, Vol. 43, W03423, DOI:10.1029/2005WR004804

Beispiele

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy.optimize import curve_fit
>>> def func(x, a, b, c):
...     return a * np.exp(-b * x) + c

Definieren Sie die Daten, die mit etwas Rauschen angepasst werden sollen

>>> xdata = np.linspace(0, 4, 50)
>>> y = func(xdata, 2.5, 1.3, 0.5)
>>> rng = np.random.default_rng()
>>> y_noise = 0.2 * rng.normal(size=xdata.size)
>>> ydata = y + y_noise
>>> plt.plot(xdata, ydata, 'b-', label='data')

Passen Sie die Parameter a, b, c der Funktion func an

>>> popt, pcov = curve_fit(func, xdata, ydata)
>>> popt
array([2.56274217, 1.37268521, 0.47427475])
>>> plt.plot(xdata, func(xdata, *popt), 'r-',
...          label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))

Beschränken Sie die Optimierung auf den Bereich von 0 <= a <= 3, 0 <= b <= 1 und 0 <= c <= 0.5

>>> popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 1., 0.5]))
>>> popt
array([2.43736712, 1.        , 0.34463856])
>>> plt.plot(xdata, func(xdata, *popt), 'g--',
...          label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt))
>>> plt.xlabel('x')
>>> plt.ylabel('y')
>>> plt.legend()
>>> plt.show()
../../_images/scipy-optimize-curve_fit-1_00_00.png

Für zuverlässige Ergebnisse sollte das Modell func nicht überparametrisiert sein; redundante Parameter können zu unzuverlässigen Kovarianzmatrizen und in einigen Fällen zu schlechteren Anpassungsergebnissen führen. Als schnelle Überprüfung, ob das Modell überparametrisiert sein könnte, berechnen Sie die Konditionszahl der Kovarianzmatrix

>>> np.linalg.cond(pcov)
34.571092161547405  # may vary

Der Wert ist klein, daher gibt er wenig Anlass zur Sorge. Wenn wir jedoch einen vierten Parameter d zu func hinzufügen würden, mit der gleichen Auswirkung wie a

>>> def func2(x, a, b, c, d):
...     return a * d * np.exp(-b * x) + c  # a and d are redundant
>>> popt, pcov = curve_fit(func2, xdata, ydata)
>>> np.linalg.cond(pcov)
1.13250718925596e+32  # may vary

Ein solch großer Wert ist Anlass zur Sorge. Die Diagonalelemente der Kovarianzmatrix, die mit der Unsicherheit der Anpassung zusammenhängen, geben mehr Aufschluss

>>> np.diag(pcov)
array([1.48814742e+29, 3.78596560e-02, 5.39253738e-03, 2.76417220e+28])  # may vary

Beachten Sie, dass das erste und letzte Glied viel größer sind als die anderen Elemente, was darauf hindeutet, dass die optimalen Werte dieser Parameter mehrdeutig sind und dass nur einer dieser Parameter im Modell benötigt wird.

Wenn die optimalen Parameter von f um mehrere Größenordnungen voneinander abweichen, kann die resultierende Anpassung ungenau sein. Manchmal schlägt curve_fit fehl, keine Ergebnisse zu finden

>>> ydata = func(xdata, 500000, 0.01, 15)
>>> try:
...     popt, pcov = curve_fit(func, xdata, ydata, method = 'trf')
... except RuntimeError as e:
...     print(e)
Optimal parameters not found: The maximum number of function evaluations is
exceeded.

Wenn die Parameterskalierung im Voraus ungefähr bekannt ist, kann sie im Argument x_scale angegeben werden

>>> popt, pcov = curve_fit(func, xdata, ydata, method = 'trf',
...                        x_scale = [1000, 1, 1])
>>> popt
array([5.00000000e+05, 1.00000000e-02, 1.49999999e+01])