Visualisierung der Kalibrierung der vorhergesagten Wahrscheinlichkeit eines Modells

23

Angenommen, ich habe ein Vorhersagemodell, das für jede Klasse eine Wahrscheinlichkeit ergibt. Jetzt erkenne ich, dass es viele Möglichkeiten gibt, ein solches Modell zu bewerten, wenn ich diese Wahrscheinlichkeiten für die Klassifizierung verwenden möchte (Genauigkeit, Erinnerung usw.). Ich erkenne auch, dass eine ROC-Kurve und die Fläche darunter verwendet werden können, um zu bestimmen, wie gut das Modell zwischen Klassen unterscheidet. Das ist nicht das, wonach ich frage.

Ich bin daran interessiert, die Kalibrierung des Modells zu bewerten . Ich weiß, dass eine Bewertungsregel wie die Brier-Bewertung für diese Aufgabe nützlich sein kann. Das ist in Ordnung, und ich werde wahrscheinlich etwas in diese Richtung integrieren, aber ich bin nicht sicher, wie intuitiv solche Metriken für den Laien sein werden. Ich suche etwas visuelleres. Ich möchte, dass die Person, die die Ergebnisse interpretiert, in der Lage ist, zu sehen, ob oder ob nicht, wenn das Modell voraussagt, dass mit einer Wahrscheinlichkeit von 70% tatsächlich etwas passiert.

Ich habe von QQ-Plots gehört (aber noch nie verwendet) , und zuerst dachte ich, dass dies das ist, wonach ich gesucht habe. Es scheint jedoch, dass dies wirklich für den Vergleich zweier Wahrscheinlichkeitsverteilungen gedacht ist . Das habe ich nicht direkt. Ich habe für eine Reihe von Fällen meine vorhergesagte Wahrscheinlichkeit und dann, ob das Ereignis tatsächlich eingetreten ist:

Index    P(Heads)    Actual Result
    1          .4            Heads
    2          .3            Tails
    3          .7            Heads
    4         .65            Tails
  ...         ...              ...

Also ist ein QQ-Plot wirklich das, was ich will, oder suche ich etwas anderes? Wenn ich einen QQ-Plot verwenden sollte, wie können meine Daten dann korrekt in Wahrscheinlichkeitsverteilungen umgewandelt werden?

Ich stelle mir vor, ich könnte beide Spalten nach vorhergesagter Wahrscheinlichkeit sortieren und dann einige Fächer erstellen. Ist das die Art von Sache, die ich tun sollte, oder bin ich irgendwo in meinen Gedanken verirrt? Ich bin mit verschiedenen Diskretisierungstechniken vertraut, aber gibt es eine bestimmte Art der Diskretisierung in Behälter, die für diese Art von Dingen Standard ist?

Michael McGowan
quelle

Antworten:

19

Dein Denken ist gut.

John Tukey empfahl die Unterteilung nach Hälften: Teilen Sie die Daten in eine obere und eine untere Hälfte auf, teilen Sie diese Hälften und teilen Sie die extremen Hälften rekursiv auf. Verglichen mit der Binning-Methode mit gleicher Breite ermöglicht dies die visuelle Überprüfung des Tail-Verhaltens, ohne dass der Datenmenge (in der Mitte) zu viele grafische Elemente zugewiesen werden.

Hier ist ein Beispiel (unter Verwendung von R) von Tukeys Ansatz. (Es ist nicht genau das Gleiche: Er hat mletteretwas anders implementiert .)

Lassen Sie uns zunächst einige Vorhersagen und Ergebnisse erstellen, die diesen Vorhersagen entsprechen:

set.seed(17)
prediction <- rbeta(500, 3/2, 5/2)
actual <- rbinom(length(prediction), 1, prediction)
plot(prediction, actual, col="Gray", cex=0.8)

actual01 (aufgetreten) sind. (Es wird in der ersten Abbildung unten als Hintergrund grauer offener Kreise angezeigt.) Dieses Diagramm muss geglättet werden. Dazu werden die Daten zwischengespeichert. Die Funktion mletterübernimmt das halbierte Teilen. Das erste Argument rist eine Reihe von Rängen zwischen 1 und n(das zweite Argument). Es werden eindeutige (numerische) Bezeichner für jeden Bin zurückgegeben:

mletter <- function(r,n) {
    lower <-  2 + floor(log(r/(n+1))/log(2))
    upper <- -1 - floor(log((n+1-r)/(n+1))/log(2))
    i <- 2*r > n
    lower[i] <- upper[i]
    lower
}

Auf diese Weise werden sowohl die Vorhersagen als auch die Ergebnisse und der Durchschnitt in jedem Bin zusammengefasst. Unterwegs berechnen wir die Bin-Populationen:

classes <- mletter(rank(prediction), length(prediction))
pgroups <- split(prediction, classes)
agroups <- split(actual, classes)
bincounts <- unlist(lapply(pgroups, length)) # Bin populations
x <- unlist(lapply(pgroups, mean))           # Mean predicted values by bin
y <- unlist(lapply(agroups, mean))           # Mean outcome by bin

Um das Grundstück zu symbolisieren effektiv sollten wir das Symbol machen Bereiche proportional zu Bin zählt. Es kann hilfreich sein, die Symbolfarben auch ein wenig zu variieren, woher:

binprop <- bincounts / max(bincounts)
colors <- -log(binprop)/log(2)
colors <- colors - min(colors)
colors <- hsv(colors / (max(colors)+1))

Mit diesen in der Hand erweitern wir jetzt den vorhergehenden Plot:

abline(0,1, lty=1, col="Gray")                           # Reference curve
points(x,y, pch=19, cex = 3 * sqrt(binprop), col=colors) # Solid colored circles
points(x,y, pch=1, cex = 3 * sqrt(binprop))              # Circle outlines

Zahl

Als Beispiel für eine schlechte Vorhersage ändern wir die Daten:

set.seed(17)
prediction <- rbeta(500, 5/2, 1)
actual <- rbinom(length(prediction), 1, 1/2 + 4*(prediction-1/2)^3)

Durch Wiederholen der Analyse wird dieses Diagramm erstellt, in dem die Abweichungen deutlich sind:

Figur 2

Dieses Modell ist tendenziell überoptimistisch (durchschnittliche Ergebnisse für Vorhersagen im Bereich von 50% bis 90% sind zu niedrig). In den wenigen Fällen, in denen die Vorhersage niedrig ist (weniger als 30%), ist das Modell zu pessimistisch.

whuber
quelle
(+1) Sehr schön, danke. Ich denke, die Farben könnten etwas vom Zweck ablenken, aber der Rest war eine nette Idee und eine sehr nette Erklärung.
Michael McGowan
Michael, ich fand, dass etwas Farbe notwendig war, um die sehr kleinen Kreise zu erkennen, die an beiden Enden erscheinen. Eine konstante Farbe würde dies natürlich erreichen. Ersetzen col=colorsSie einfach durch die gewünschte Farbe, z col="Red".
Whuber
+1, das ist sehr schön. Allerdings weiß ich nicht recht, warum die Referenzlinie eine einfache, gerade 45-Grad-Linie anstelle der richtigen logistischen Regressionslinie oder eine Lösslinie ist? Ich denke, das wären angemessenere Referenzen, anhand derer die Qualität der Vorhersagen beurteilt werden kann.
gung - Reinstate Monica
pp±[0,1]×[0,1]
whuber
p(1-p)/npn
4

Eine andere Option ist die isotonische Regression. Dies ähnelt der Antwort von whuber, mit der Ausnahme, dass die Bins dynamisch generiert werden und nicht durch Teilen in zwei Hälften, wobei die Ausgabe unbedingt erhöht werden muss.

Diese primäre Verwendung der isotonischen Regression dient der Neukalibrierung Ihrer Wahrscheinlichkeiten, wenn sich herausstellt, dass sie schlecht kalibriert sind. Sie kann jedoch auch zur Visualisierung verwendet werden. Wenn die isotonische Regressionslinie ungefähr der Y = X-Linie folgt, sind Ihre Wahrscheinlichkeiten im Grunde richtig kalibriert.

Isotonische Regression auf Wahrscheinlichkeiten

Dies ist die isotonische Regression, die auf das von Whuber gezeigte Problem angewendet wird.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.isotonic import IsotonicRegression

prediction = np.random.beta(3.0/2.0, 5.0/2.0, size=500)
actual = np.random.binomial(1,prediction, len(prediction))
plt.scatter(prediction, actual,  facecolors='none', edgecolors=[0.3,0.3,0.3], label='Data')

ir = IsotonicRegression()
isotonic = ir.fit_transform(prediction, actual)
plt.plot(prediction, isotonic,'ok', label='Isotonic Fit')

plt.xlabel('Prediction')
plt.ylabel('Actual')
plt.plot([0,1],[0,1], '--k', label='y=x line')
plt.legend(loc = 'center left')

http://fa.bianp.net/blog/2013/isotonic-regression/

http://stat.wikia.com/wiki/Isotonic_regression

Bscan
quelle