Courbe ROC traversant la diagonale

12

J'utilise actuellement un classificateur binaire. Lorsque je trace la courbe ROC, j'obtiens une bonne portance au début, puis elle change de direction et traverse la diagonale, puis bien sûr en remontant, faisant de la courbe une forme inclinée en S.

Quelle peut être une interprétation / explication à cet effet?

Merci

Cagdas Ozgenc
la source
1
Qu'est-ce qui vous a fait vous soucier d'une courbe ROC? Qu'est-ce qui vous a poussé à choisir un classificateur au lieu d'un modèle de probabilité directe?
Frank Harrell

Réponses:

18

Vous obtenez un joli graphique ROC symétrique uniquement lorsque les écarts-types pour les deux résultats sont les mêmes. S'ils sont assez différents, vous obtiendrez peut-être exactement le résultat que vous décrivez.

Le code Mathematica suivant illustre cela. Nous supposons qu'une cible donne une distribution normale dans l'espace de réponse, et que le bruit donne également une distribution normale, mais déplacée. Les paramètres ROC sont déterminés par l'aire sous les courbes gaussiennes à gauche ou à droite d'un critère de décision. La variation de ce critère décrit la courbe 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"}]

C'est avec des écarts-types égaux: entrez la description de l'image ici

C'est avec des éléments assez distincts:

entrez la description de l'image ici

ou avec quelques autres paramètres pour jouer avec:

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

entrez la description de l'image ici

Sjoerd C. de Vries
la source
1

Le fait d'avoir une chaîne d'instances négatives dans la partie de la courbe avec un FPR élevé peut créer ce type de courbe. C'est correct tant que vous utilisez le bon algorithme pour générer la courbe ROC.

La condition où vous avez un ensemble de points de 2m dont la moitié sont positifs et la moitié sont négatifs-tous ayant exactement le même score pour votre modèle est délicate. Si, lors du tri des points en fonction du score (procédure standard de traçage du ROC), tous les exemples négatifs sont rencontrés en premier, votre courbe ROC restera plate et se déplacera vers la droite. :

Fawcett | Tracer des courbes ROC

wabbit
la source
1

(Les réponses de @Sjoerd C. de Vries et @Hrishekesh Ganu sont correctes. Je pensais que je pouvais néanmoins présenter les idées d'une autre manière, ce qui pourrait aider certaines personnes.)


Vous pouvez obtenir un ROC comme celui-ci si votre modèle est mal spécifié. Prenons l'exemple ci-dessous (codé en R), qui est adapté de ma réponse ici: Comment utiliser les boîtes à moustaches pour trouver le point où les valeurs sont plus susceptibles de provenir de différentes conditions?

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

entrez la description de l'image ici

Il est facile de voir que le modèle rouge ne contient pas la structure des données. Nous pouvons voir à quoi ressemblent les courbes ROC lorsqu'elles sont tracées ci-dessous:

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

entrez la description de l'image ici

Nous pouvons maintenant voir que, pour le modèle mal spécifié (rouge), lorsque le taux de faux positifs devient supérieur à , le taux de faux positifs augmente plus rapidement que le taux de vrais positifs. En regardant les modèles ci-dessus, nous voyons que ce point est l'endroit où les lignes rouges et bleues se croisent en bas à gauche. 80%

gung - Réintégrer Monica
la source