Visualizzazione della calibrazione della probabilità prevista di un modello


23

Supponiamo che io abbia un modello predittivo che produce, per ogni istanza, una probabilità per ogni classe. Ora riconosco che ci sono molti modi per valutare un tale modello se voglio usare quelle probabilità per la classificazione (precisione, richiamo, ecc.). Riconosco anche che una curva ROC e l'area sottostante possono essere utilizzate per determinare in che modo il modello differenzia tra le classi. Quelli non sono quello di cui sto chiedendo.

Sono interessato a valutare la calibrazione del modello. So che una regola di punteggio come il punteggio di Brier può essere utile per questo compito. Va bene, e probabilmente incorporerò qualcosa in tal senso, ma non sono sicuro di quanto siano intuitive queste metriche per il laico. Sto cercando qualcosa di più visivo. Voglio che la persona che interpreta i risultati sia in grado di vedere se il modello prevede una probabilità che accada qualcosa del 70% che accada effettivamente ~ 70% delle volte, ecc.

Ho sentito parlare (ma non ho mai usato) dei diagrammi QQ e all'inizio ho pensato che fosse quello che stavo cercando. Tuttavia, sembra che sia realmente pensato per confrontare due distribuzioni di probabilità . Questo non è direttamente quello che ho. Per un certo numero di casi, ho la mia probabilità prevista e quindi se l'evento si è effettivamente verificato:

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

Quindi una trama QQ è davvero quello che voglio o sto cercando qualcos'altro? Se un diagramma QQ è quello che dovrei usare, qual è il modo corretto di trasformare i miei dati in distribuzioni di probabilità?

Immagino di poter ordinare entrambe le colonne in base alla probabilità prevista e quindi creare alcuni bin. È questo il tipo di cosa che dovrei fare o sto pensando da qualche parte? Ho familiarità con varie tecniche di discretizzazione, ma esiste un modo specifico di discretizzare in bidoni che è standard per questo genere di cose?

Risposte:


19

Il tuo pensiero è buono.

John Tukey ha raccomandato di eseguire il binning per metà: suddividere i dati in metà superiore e inferiore, quindi dividere tali metà, quindi dividere le metà estreme in modo ricorsivo. Rispetto al binning di uguale larghezza, questo consente l'ispezione visiva del comportamento della coda senza dedicare troppi elementi grafici alla maggior parte dei dati (al centro).

Ecco un esempio (usando R) dell'approccio di Tukey. (Non è esattamente lo stesso: ha implementato in mlettermodo leggermente diverso.)

Innanzitutto, creiamo alcune previsioni e alcuni risultati conformi a tali previsioni:

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

La trama non è molto istruttiva, perché tutti i actualvalori sono, ovviamente, (non si sono verificati) o (si sono verificati). (Appare come sfondo di cerchi aperti grigi nella prima figura in basso.) Questo diagramma deve essere levigato. Per fare ciò, raccogliamo i dati. La funzione esegue la divisione per metà. Il suo primo argomento è un array di ranghi tra 1 e (il secondo argomento). Restituisce identificatori univoci (numerici) per ogni cestino:101mletterrn

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
}

Usando questo, raccogliamo sia le previsioni che i risultati e calcoliamo la media di ciascuno all'interno di ciascun cestino. Lungo la strada, calcoliamo le popolazioni di bin:

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

Per simboleggiare efficacemente la trama, dovremmo rendere le aree dei simboli proporzionali al conteggio dei contenitori. Può essere utile anche variare leggermente i colori dei simboli, da cui:

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

Con questi in mano, ora miglioriamo la trama precedente:

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

figura

Come esempio di una previsione scadente, cambiamo i dati:

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

La ripetizione dell'analisi produce questo diagramma in cui le deviazioni sono chiare:

figura 2

Questo modello tende ad essere troppo ottimista (i risultati medi per le previsioni nell'intervallo dal 50% al 90% sono troppo bassi). Nei pochi casi in cui la previsione è bassa (meno del 30%), il modello è troppo pessimista.


(+1) Molto bello, grazie. Penso che i colori potrebbero distrarre un po 'dallo scopo, ma il resto è stata una bella idea e una spiegazione molto bella.
Michael McGowan,

Michael, ho scoperto che era necessario un po 'di colore per aiutare a vedere i cerchi molto piccoli che compaiono alle due estremità. Un colore costante lo farebbe, ovviamente. Sostituisci semplicemente col=colorscon il colore che desideri, ad esempio col="Red".
whuber

+1, questo è molto carino. Tuttavia, non capisco bene perché la linea di riferimento sia una linea semplice, dritta di 45 gradi, invece della corretta linea di regressione logistica o un loess? Dovrei pensare che sarebbero riferimenti più appropriati rispetto ai quali giudicare la qualità delle previsioni.
gung - Ripristina Monica

pp±[0,1]×[0,1]
whuber

p(1-p)/npn

4

Un'altra opzione è la regressione isotonica. È simile alla risposta di Whuber, tranne per il fatto che i bin vengono generati in modo dinamico anziché mediante la suddivisione a metà, con il requisito che gli output siano in costante aumento.

Questo uso primario della regressione isotonica è di ricalibrare le tue probabilità se si dimostra che sono scarsamente calibrate, ma può anche essere usato per la visualizzazione. Fondamentalmente, se la linea di regressione isotonica segue approssimativamente la linea Y = X, le tue probabilità sono correttamente calibrate.

Regressione isotonica sulle probabilità

Questa è la regressione isotonica applicata al problema mostrato da Whuber.

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.