ROC-Kurve, welche die Diagonale kreuzt

12

Im Moment führe ich einen binären Klassifikator aus. Wenn ich die ROC-Kurve zeichne, bekomme ich am Anfang einen guten Auftrieb, dann ändert sich die Richtung und kreuzt die Diagonale, dann natürlich wieder nach oben, wodurch die Kurve eine geneigte S-Form erhält.

Was kann eine Interpretation / Erklärung für diesen Effekt sein?

Vielen Dank

Cagdas Ozgenc
quelle
1
Was hat Sie an einer ROC-Kurve interessiert? Warum haben Sie einen Klassifikator anstelle eines direkten Wahrscheinlichkeitsmodells gewählt?
Frank Harrell

Antworten:

18

Sie erhalten eine schöne symmetrische ROC-Darstellung nur, wenn die Standardabweichungen für beide Ergebnisse gleich sind. Wenn sie ziemlich unterschiedlich sind, erhalten Sie möglicherweise genau das Ergebnis, das Sie beschreiben.

Der folgende Mathematica-Code demonstriert dies. Wir nehmen an, dass ein Ziel eine Normalverteilung im Antwortraum ergibt und dass Rauschen ebenfalls eine Normalverteilung ergibt, jedoch eine verschobene. Die ROC-Parameter werden durch den Bereich unterhalb der Gaußschen Kurven links oder rechts von einem Entscheidungskriterium bestimmt. Das Variieren dieses Kriteriums beschreibt die ROC-Kurve.

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"}]

Dies ist mit gleichen Standardabweichungen: Bildbeschreibung hier eingeben

Dies ist mit ziemlich unterschiedlichen:

Bildbeschreibung hier eingeben

oder mit ein paar weiteren Parametern zum Spielen:

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"}]

Bildbeschreibung hier eingeben

Sjoerd C. de Vries
quelle
1

Wenn im Teil der Kurve eine Reihe negativer Instanzen mit hoher FPR vorhanden ist, kann diese Art von Kurve erstellt werden. Dies ist in Ordnung, solange Sie den richtigen Algorithmus zum Erzeugen der ROC-Kurve verwenden.

Die Bedingung, dass Sie einen Satz von 2 m Punkten haben, von denen die Hälfte positiv und die andere Hälfte negativ ist - alle haben genau die gleiche Punktzahl für Ihr Modell -, ist schwierig. Wenn beim Sortieren der Punkte nach der Punktzahl (Standardverfahren beim Zeichnen des ROC) zuerst alle negativen Beispiele gefunden werden, bleibt die ROC-Kurve flach und verschiebt sich nach rechts. In diesem Artikel wird erläutert, wie solche Probleme behoben werden können :

Fawcett | Zeichnen von ROC-Kurven

Wabbit
quelle
1

(Die Antworten von @Sjoerd C. de Vries und @Hrishekesh Ganu sind richtig. Ich dachte, ich könnte die Ideen trotzdem auf eine andere Art und Weise präsentieren, was einigen Menschen helfen könnte.)


Sie können einen solchen ROC erhalten, wenn Ihr Modell falsch spezifiziert ist. Betrachten Sie das nachstehende Beispiel (in codiert R), das aus meiner Antwort hier übernommen wurde: Wie können Boxplots verwendet werden, um den Punkt zu ermitteln, an dem Werte mit höherer Wahrscheinlichkeit aus unterschiedlichen Bedingungen stammen?

## 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"))

Bildbeschreibung hier eingeben

Es ist leicht zu erkennen, dass dem roten Modell die Struktur der Daten fehlt. Wir können sehen, wie die ROC-Kurven aussehen, wenn wir sie unten zeichnen:

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"))

Bildbeschreibung hier eingeben

80%

gung - Wiedereinsetzung von Monica
quelle