isotonic_regression#
- scipy.optimize.isotonic_regression(y, *, weights=None, increasing=True)[Quelle]#
Nichtparametrische isotonische Regression.
Ein (nicht streng) monoton steigendes Array x mit der gleichen Länge wie y wird mit dem Pool-Adjacent-Violators-Algorithmus (PAVA) berechnet; siehe [1]. Weitere Details finden Sie im Abschnitt Hinweise.
- Parameter:
- y(N,) array_like
Antwortvariable.
- weights(N,) array_like oder None
Fallgewichte.
- increasingbool
Wenn True, wird eine monoton steigende, d.h. isotonische, Regression angepasst. Wenn False, wird eine monoton fallende, d.h. antitonische, Regression angepasst. Standard ist True.
- Rückgabe:
- resOptimizeResult
Das Optimierungsergebnis, dargestellt als ein
OptimizeResult-Objekt. Wichtige Attribute sindx: Die isotonische Regressionslösung, d.h. ein steigendes (oder fallendes) Array derselben Länge wie y, mit Elementen im Bereich von min(y) bis max(y).weights: Array mit der Summe der Fallgewichte für jeden Block (oder Pool) B.blocks: Array der Länge B+1 mit den Indizes der Startpositionen jedes Blocks (oder Pools) B. Der j-te Block ist gegeben durchx[blocks[j]:blocks[j+1]], für den alle Werte gleich sind.
Hinweise
Gegeben seien Daten \(y\) und Fallgewichte \(w\). Die isotonische Regression löst das folgende Optimierungsproblem:
\[\operatorname{argmin}_{x_i} \sum_i w_i (y_i - x_i)^2 \quad \text{unter der Bedingung } x_i \leq x_j \text{ wann immer } i \leq j \,.\]Für jeden Eingabewert \(y_i\) wird ein Wert \(x_i\) erzeugt, so dass \(x\) steigend (aber nicht streng steigend) ist, d.h. \(x_i \leq x_{i+1}\). Dies wird durch PAVA erreicht. Die Lösung besteht aus Pools oder Blöcken, d.h. benachbarten Elementen von \(x\), z.B. \(x_i\) und \(x_{i+1}\), die alle den gleichen Wert haben.
Am interessantesten ist, dass die Lösung gleich bleibt, wenn der quadratische Verlust durch die breite Klasse von Bregman-Funktionen ersetzt wird, welche die einzigartige Klasse streng konsistenter Scoring-Funktionen für den Mittelwert darstellt, siehe [2] und die dortigen Referenzen.
Die implementierte Version von PAVA gemäß [1] hat eine rechnerische Komplexität von O(N) bei Eingabegröße N.
Referenzen
[1] (1,2)Busing, F. M. T. A. (2022). Monotone Regression: A Simple and Fast O(n) PAVA Implementation. Journal of Statistical Software, Code Snippets, 102(1), 1-25. DOI:10.18637/jss.v102.c01
[2]Jordan, A.I., Mühlemann, A. & Ziegel, J.F. Characterizing the optimal solutions to the isotonic regression problem for identifiable functionals. Ann Inst Stat Math 74, 489-514 (2022). DOI:10.1007/s10463-021-00808-0
Beispiele
Dieses Beispiel zeigt, dass
isotonic_regressiontatsächlich ein eingeschränktes Optimierungsproblem löst.>>> import numpy as np >>> from scipy.optimize import isotonic_regression, minimize >>> y = [1.5, 1.0, 4.0, 6.0, 5.7, 5.0, 7.8, 9.0, 7.5, 9.5, 9.0] >>> def objective(yhat, y): ... return np.sum((yhat - y)**2) >>> def constraint(yhat, y): ... # This is for a monotonically increasing regression. ... return np.diff(yhat) >>> result = minimize(objective, x0=y, args=(y,), ... constraints=[{'type': 'ineq', ... 'fun': lambda x: constraint(x, y)}]) >>> result.x array([1.25 , 1.25 , 4. , 5.56666667, 5.56666667, 5.56666667, 7.8 , 8.25 , 8.25 , 9.25 , 9.25 ]) >>> result = isotonic_regression(y) >>> result.x array([1.25 , 1.25 , 4. , 5.56666667, 5.56666667, 5.56666667, 7.8 , 8.25 , 8.25 , 9.25 , 9.25 ])
Der große Vorteil von
isotonic_regressionim Vergleich zum Aufruf vonminimizeist, dass es benutzerfreundlicher ist, d.h. man muss keine Zielfunktionen und Nebenbedingungen definieren, und dass es um Größenordnungen schneller ist. Auf handelsüblicher Hardware (im Jahr 2023) dauert die Minimierung für normalverteilte Eingabe y der Länge 1000 etwa 4 Sekunden, währendisotonic_regressionetwa 200 Mikrosekunden benötigt.