Curva ROC cruzando la diagonal

12

Estoy ejecutando un clasificador binario en este momento. Cuando trazo la curva ROC obtengo una buena elevación al principio, luego cambia de dirección y cruza la diagonal y, por supuesto, retrocede, haciendo que la curva tenga una forma de S inclinada.

¿Qué puede ser una interpretación / explicación a este efecto?

Gracias

Cagdas Ozgenc
fuente
1
¿Qué te hizo preocuparte por una curva ROC? ¿Qué te hizo elegir un clasificador en lugar de un modelo de probabilidad directa?
Frank Harrell

Respuestas:

18

Obtiene una buena gráfica simétrica ROC solo cuando las desviaciones estándar para ambos resultados son las mismas. Si son bastante diferentes, entonces puede obtener exactamente el resultado que describe.

El siguiente código de Mathematica demuestra esto. Suponemos que un objetivo produce una distribución normal en el espacio de respuesta, y que el ruido también produce una distribución normal, pero desplazada. Los parámetros ROC están determinados por el área debajo de las curvas gaussianas a la izquierda o derecha de un criterio de decisión. Variando este criterio se describe 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"}]

Esto es con desviaciones estándar iguales: ingrese la descripción de la imagen aquí

Esto es con otros bastante distintos:

ingrese la descripción de la imagen aquí

o con algunos parámetros más para jugar:

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

ingrese la descripción de la imagen aquí

Sjoerd C. de Vries
fuente
1

Tener una serie de instancias negativas en la parte de la curva con un alto FPR puede crear este tipo de curva. Esto está bien siempre que esté utilizando el algoritmo correcto para generar la curva ROC.

La condición en la que tiene un conjunto de 2 millones de puntos, la mitad de los cuales son positivos y la otra mitad negativos, todos tienen exactamente el mismo puntaje para su modelo, es difícil. Si al ordenar los puntos en función de la puntuación (procedimiento estándar en el trazado de ROC) se encuentran primero todos los ejemplos negativos, esto hará que su curva ROC permanezca plana y se mueva hacia la derecha. Este documento habla sobre cómo solucionar estos problemas :

Fawcett | Trazado de curvas ROC

wabbit
fuente
1

(Las respuestas de @Sjoerd C. de Vries y @Hrishekesh Ganu son correctas. Sin embargo, pensé que podría presentar las ideas de otra manera, lo que puede ayudar a algunas personas).


Puede obtener un ROC como ese si su modelo está mal especificado. Considere el siguiente ejemplo (codificado R), que está adaptado de mi respuesta aquí: ¿Cómo usar los diagramas de caja para encontrar el punto donde los valores tienen más probabilidades de provenir de diferentes condiciones?

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

ingrese la descripción de la imagen aquí

Es fácil ver que al modelo rojo le falta la estructura de los datos. Podemos ver cómo se ven las curvas ROC cuando se trazan a continuación:

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

ingrese la descripción de la imagen aquí

80%

gung - Restablece a Monica
fuente