¿Qué es la curva ROC?

| Última modificación: 18 de abril de 2024 | Tiempo de Lectura: 3 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

La curva ROC se comenzó a usar durante la segunda guerra mundial para el análisis de las señales de radar. Después del ataque a Pearl Harbor en 1941, la armada de EEUU comenzó un programa de investigación para aumentar la predicción de los radares a la hora de detectar aviones japoneses. Para ello, midieron la habilidad de un radar de detectar esas señales y a esa medida la llamaron Receiver Operating Characteristic o curva ROC.

La curva ROC se utiliza para ver la calidad de un detector, un clasificador binario capaz de detectar un elemento. Se hace un barrido por todos los umbrales y se mide el valor de positivo verdadero en función de falso positivo.

Ejercicio curva ROC

En artículos anteriores hemos visto algunos ejercicios acerca de cómo identificar de una serie de datos entrantes, cuáles eran ruido y cuáles eran aviones. Entre otros, hicimos la matriz de confusión de dicho ejercicio y le aplicamos las medidas de calidad respectivas.

En este artículo, realizaremos la curva ROC de esa matriz de confusión. Para ello, pintaremos la probabilidad de true positive y false positive.

In [46] : <- 4
radar_pred <- predict (model, radar.test)

df_preds <- data.frame (pred = radar_pred,
tipo_pred = factor (ifelse (radar_pred < umbral, 0, 1), labels = c ("ruido", "avión")),
tipo_real = radar.test$tipo)
df_preds <- df_preds [order (df_oreds$pred, decreasing = FALSE) , ]

M <- table (df_preds$tipo_real, df_preds$tipo_pred)
#table (real = radar.test$tipo, elegimos = y_est)

#Recall, Exhaustividad, Tasa Verdadero positivo
truePositive <- M [2, 2] / (M [2, 2] + M [2, 1])

#Tasa Falso positivo
falsePositive <- M [1, 2] / (M [1, 2] + M [1, 1])
paste ("tp:", truePositive, "fp:", falsePositive)
M

df_preds

‘tp: 0.363636363636364 fp: 0’

predtipo_predtpo_real
<dbl><fct><fct>
14-12.998054ruidoavión
49-12.212471ruidoavión
5-10.568399ruidoavión
52-8.774266ruidoavión
4-5.860805ruidoavión
421.181265ruidoavión
301.605634ruidoavión
101.763440ruidoavión
222.499537ruidoavión
72.604227ruidoavión
273.117978ruidoavión
283.730055ruidoavión
243.975999ruidoavión
513.984776ruidoavión
254.711617ruidoavión
606.052678ruidoavión
357.213312ruidoavión
319.375621ruidoavión
In [47] : calctp_fp <- function (y_predict, y_real, th) {
y_est <- ifelse (y_predict < th, 0, 1)

M <- table (y_real, y_est)
#print (M)
if (ncol (M) == 2 & nrow (M) == 2) {
truePositive <- M [2, 2] / (M [2, 2] + M [2, 1])
falsePositive <- M [1, 2] / (M [1, 2] + M [1, 1]) 
c (tp = truePositive, fp = falsePositive)
} else {
c (tp = NA, fp = NA)
    }
}
In [48] : calctp_fp (df_preds$pred, df_preds$tipo_real, th = -1)

tp

1

tp

0.285714285714286

In [49] : dfROC <- data.frame (th =unique (df_preds$pred), tp = NA, fp= NA, model = "model1")

#for (th in seq (min (df_preds$pred), max (df_preds$pred), lenght.out = 10)) {
#calctp_fp (df_preds$pred, df_preds$tipo_real, th = th)
# }
for (i in 1 : nrow (dfROC)) {
v <- calctp_fp (df_preds$pred, df_preds$tipo_real, th = dfROC$th [i])
dfROC$tp [i] <- v ["tp"]
dfROC$tp [i] <- v ["fp"]
}
ggplot (data = dfROC, aes (x = fp, y = tp)) + geom_path ()

Warning message:

“Removed 1 row (s) containing missing values (geom_path).”

curva ROC imprecisa

La curva ROC sale tan escalonada porque tenemos pocas muestras. Vamos a probar con un dataset más grande:

curva ROC precisa

En función de qué clasificador quisiéramos con la curva ROC, nos interesaría más o menos estar por el área señalada en el recuadro rojo.

In [53] : library (ROCR)

#p <- predict (model_radar1, radar_big.test, type = "response")
p <- predict (mode_radar1, radar_big.test)

pr <- prediction (p, radar_big.tests$tipo, label.ordering = c ("ruido", "avion"))
prf <- performance (pr, measure = "tpr", x.measure = "fpr")
plot (prf, colorize = TRUE)
gráfica
In [62] : pauc2 <- performance (pr2, measure = "auc", label.ordering = c ("ruido", "avión"))
[email protected] [[1]]

0.953170694166538

In (63): #library(pROC)
rocobjl <- PROC::roc(
radar_big.test$tipo,
predict (model_radar1, radar_big.test))

rocobj2 <- PROC::roc (
radar_big.test$tipo,
predict (model_radar2, radar_big.test),
levels = c ("ruido", "avion"), direction = "<")

#plot (rocobjl, print.auc = TRUE, col = "blue")
#plot(rocob)2, print.auc = TRUE, col = "green", print.auc.y = .4, add = TRUE)

pROC :: ggroc (list (model1 = rocobj1, model2 = rocob12), alpha = 0.5, size = 2) + xlab ("1 ~ FPR") + ylab ("TPR") + geom_abline (slope = 1, intercept = 1, alpha = 0.5)+
scale_colour_manual (values = c ("red", "#0000FF"), name = "Modelo", labels = c (paste0 ("Modelo1, AUC: " , PROC :: auc (rocobj1)),
paste0 ("Modelo2, AUC, PROC :: auc (rocobj2))))

Setting Levels: control = ruido, case = avion

Setting direction: controls < cases

gráfica 2

Ya hemos visto qué es la curva ROC, cuál es su origen y cómo funciona, ¿ahora qué te parece si seguimos aprendiendo sobre estadística, Big Data y data mining? Para ello, desde Keepcoding te ofrecemos nuestro Big Data, Inteligencia Artificial & Machine Learning Full Stack Bootcamp, con el cual en muy poco tiempo dominarás todos los conocimientos necesarios para convertirte en un gran científico de datos y acceder a las mejores ofertas laborales del mercado. ¡Anímate a impulsar tu carrera y solicita más información!

Sandra Navarro

Business Intelligence & Big Data Advisor & Coordinadora del Bootcamp en Data Science, Big Data & Machine Learning.

Posts más leídos

¡CONVOCATORIA ABIERTA!

Big Data, IA & Machine Learning

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado