Curva ROC che attraversa la diagonale


12

Al momento sto eseguendo un classificatore binario. Quando tracciamo la curva ROC ottengo un buon sollevamento all'inizio, quindi cambia direzione e attraversa la diagonale, quindi ovviamente torna indietro, rendendo la curva a forma di S inclinata.

Quale può essere un'interpretazione / spiegazione in tal senso?

Grazie


1
Cosa ti ha fatto preoccupare di una curva ROC? Cosa ti ha fatto scegliere un classificatore anziché un modello di probabilità diretto?
Frank Harrell,

Risposte:


18

Si ottiene un bel diagramma ROC simmetrico solo quando le deviazioni standard per entrambi i risultati sono uguali. Se sono piuttosto diversi, potresti ottenere esattamente il risultato che descrivi.

Il seguente codice Mathematica lo dimostra. Partiamo dal presupposto che un obiettivo produce una distribuzione normale nello spazio di risposta e che anche il rumore produce una distribuzione normale, ma spostata. I parametri ROC sono determinati dall'area sotto le curve gaussiane a sinistra o a destra di un criterio di decisione. Variando questo criterio viene descritta la curva ROC.

Manipulate[
 ParametricPlot[{CDF[NormalDistribution[4, \[Sigma]], c], 
                 CDF[NormalDistribution[0, 3], c]
                }, {c, -10, 10}, 
                Frame -> True, 
                Axes -> None, PlotRange -> {{0, 1}, {0, 1}}, 
                Epilog -> Line[{{0, 0}, {1, 1}}]], 
 {{\[Sigma], 3}, 0.1, 10, Appearance -> "Labeled"}]

Questo è con deviazioni standard uguali: inserisci qui la descrizione dell'immagine

Questo è con quelli piuttosto distinti:

inserisci qui la descrizione dell'immagine

o con qualche altro parametro con cui giocare:

Manipulate[
 ParametricPlot[{CDF[NormalDistribution[\[Mu]1, \[Sigma]1], c], 
   CDF[NormalDistribution[\[Mu]2, \[Sigma]2], c]}, {c, -100, 100}, 
  Frame -> True, Axes -> None, PlotRange -> {{0, 1}, {0, 1}}, 
  Epilog -> Line[{{0, 0}, {1, 1}}]], {{\[Mu]1, 0}, 0, 10, 
  Appearance -> "Labeled"},
 {{\[Sigma]1, 4}, 0.1, 20, Appearance -> "Labeled"},
 {{\[Mu]2, 5}, 0, 10, Appearance -> "Labeled"},
 {{\[Sigma]2, 4}, 0.1, 20, Appearance -> "Labeled"}]

inserisci qui la descrizione dell'immagine


1

Avere una stringa di istanze negative nella parte della curva con FPR elevato può creare questo tipo di curva. Questo va bene finché si utilizza l'algoritmo giusto per generare la curva ROC.

La condizione in cui hai un set di 2m punti, metà dei quali positivi e metà negativi, hanno tutti lo stesso punteggio per il tuo modello è difficile. Se durante l'ordinamento dei punti in base al punteggio (procedura standard nella stampa del ROC) vengono rilevati per primi tutti gli esempi negativi, ciò farà sì che la curva del ROC rimanga piatta e si sposti a destra. Questo documento spiega come occuparsi di tali problemi :

Fawcett | Tracciamento delle curve ROC


1

(Le risposte di @Sjoerd C. de Vries e @Hrishekesh Ganu sono corrette. Pensavo di poter comunque presentare le idee in un altro modo, il che potrebbe aiutare alcune persone.)


È possibile ottenere un ROC del genere se il modello non è specificato correttamente. Considera l'esempio di seguito (codificato R), che è adattato dalla mia risposta qui: Come utilizzare i grafici a scatole per trovare il punto in cui è più probabile che i valori provengano da condizioni diverse?

## data
Cond.1 = c(2.9, 3.0, 3.1, 3.1, 3.1, 3.3, 3.3, 3.4, 3.4, 3.4, 3.5, 3.5, 3.6, 3.7, 3.7,
           3.8, 3.8, 3.8, 3.8, 3.9, 4.0, 4.0, 4.1, 4.1, 4.2, 4.4, 4.5, 4.5, 4.5, 4.6,
           4.6, 4.6, 4.7, 4.8, 4.9, 4.9, 5.5, 5.5, 5.7)
Cond.2 = c(2.3, 2.4, 2.6, 3.1, 3.7, 3.7, 3.8, 4.0, 4.2, 4.8, 4.9, 5.5, 5.5, 5.5, 5.7,
           5.8, 5.9, 5.9, 6.0, 6.0, 6.1, 6.1, 6.3, 6.5, 6.7, 6.8, 6.9, 7.1, 7.1, 7.1,
           7.2, 7.2, 7.4, 7.5, 7.6, 7.6, 10, 10.1, 12.5)
dat    = stack(list(cond1=Cond.1, cond2=Cond.2))
ord    = order(dat$values)
dat    = dat[ord,]  # now the data are sorted

## logistic regression models
lr.model1 = glm(ind~values,             dat, family="binomial")  # w/o a squared term
lr.model2 = glm(ind~values+I(values^2), dat, family="binomial")  # w/  a squared term
lr.preds1 = predict(lr.model1, data.frame(values=seq(2.3,12.5,by=.1)), type="response")
lr.preds2 = predict(lr.model2, data.frame(values=seq(2.3,12.5,by=.1)), type="response")

## here I plot the data & the 2 models
windows()
  with(dat, plot(values, ifelse(ind=="cond2",1,0), 
                 ylab="predicted probability of condition2"))
  lines(seq(2.3,12.5,by=.1), lr.preds1, lwd=2, col="red")
  lines(seq(2.3,12.5,by=.1), lr.preds2, lwd=2, col="blue")
  legend("bottomright", legend=c("model 1", "model 2"), lwd=2, col=c("red", "blue"))

inserisci qui la descrizione dell'immagine

È facile vedere che al modello rosso manca la struttura dei dati. Possiamo vedere come appaiono le curve ROC quando tracciate di seguito:

library(ROCR)  # we'll use this package to make the ROC curve

## these are necessary to make the ROC curves
pred1 = with(dat, prediction(fitted(lr.model1), ind))
pred2 = with(dat, prediction(fitted(lr.model2), ind))
perf1 = performance(pred1, "tpr", "fpr")
perf2 = performance(pred2, "tpr", "fpr")

## here I plot the ROC curves
windows()
  plot(perf1, col="red",  lwd=2)
  plot(perf2, col="blue", lwd=2, add=T)
  abline(0,1, col="gray")
  legend("bottomright", legend=c("model 1", "model 2"), lwd=2, col=c("red", "blue"))

inserisci qui la descrizione dell'immagine

Ora possiamo vedere che, per il modello errato (rosso), quando il tasso di falsi positivi diventa maggiore , il tasso di falsi positivi aumenta più rapidamente del tasso positivo reale. Guardando i modelli sopra, vediamo che quel punto è dove le linee rosse e blu si incrociano in basso a sinistra. 80%

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.