Usando el paquete caret, ¿es posible obtener matrices de confusión para valores umbral específicos?

13

Obtuve un modelo de regresión logística (vía train) para una respuesta binaria, y obtuve la matriz de confusión logística a través de confusionMatrixin caret. Me da la matriz de confusión del modelo logístico, aunque no estoy seguro de qué umbral se está utilizando para obtenerlo. ¿Cómo obtengo la matriz de confusión para valores de umbral específicos usando confusionMatrixin caret?

Leche negra
fuente
No tengo una respuesta, pero a menudo preguntas como esta se responden en el archivo de ayuda. Si eso falla, puede mirar el código fuente en sí. Puede imprimir la fuente en la consola escribiendo confusionmatrix, sin paréntesis.
shadowtalker
No está muy claro lo que has hecho exactamente. ¿Llamaste a la glmfunción desde el statspaquete y le pasaste el resultado confusionMatrix? No sabía que se podía hacer eso, y al leer el manual no está claro que se pueda. ¿O hiciste predictalgo? Un breve ejemplo ayudaría.
Calimo
1
@Calimo He usado la trainfunción caretpara ajustar el modelo, lo que me permite especificarlo como un glm con la familia binomial. Luego usé la predictfunción en el objeto generado a través de train.
Black Milk

Respuestas:

10

La mayoría de los modelos de clasificación en R producen tanto una predicción de clase como las probabilidades para cada clase. Para datos binarios, en casi todos los casos, la predicción de clase se basa en un límite de probabilidad del 50%.

glmes el mismo. Con caret, el uso predict(object, newdata)le da la clase predicha y predict(object, new data, type = "prob")le dará probabilidades específicas de la clase (cuando objectes generada por train).

Puede hacer las cosas de manera diferente definiendo su propio modelo y aplicando el límite que desee. El caret sitio web también tiene un ejemplo que usa remuestreo para optimizar el corte de probabilidad.

tl; dr

confusionMatrix usa las clases predichas y, por lo tanto, un límite de probabilidad del 50%

Max

topepo
fuente
14

Hay una manera bastante fácil, suponiendo tune <- train(...):

probsTest <- predict(tune, test, type = "prob")
threshold <- 0.5
pred      <- factor( ifelse(probsTest[, "yes"] > threshold, "yes", "no") )
pred      <- relevel(pred, "yes")   # you may or may not need this; I did
confusionMatrix(pred, test$response)

Obviamente, puede establecer el umbral a lo que quiera probar o elegir el "mejor", donde mejor significa la mayor especificidad y sensibilidad combinadas:

library(pROC)
probsTrain <- predict(tune, train, type = "prob")
rocCurve   <- roc(response = train$response,
                      predictor = probsTrain[, "yes"],
                      levels = rev(levels(train$response)))
plot(rocCurve, print.thres = "best")

Después de mirar el ejemplo que publicó Max, no estoy seguro de si hay algunos matices estadísticos que hacen que mi enfoque sea menos deseado.

efh0888
fuente
En la gráfica de salida de rocCurve, ¿qué significan los tres valores? Por ejemplo, en mis datos dice 0.289 (0.853, 0.831). ¿El 0.289 significa el mejor umbral que uno debería usar para demarcar el resultado binario? es decir, cada caso con una probabilidad pronosticada> 0.289 se codificaría "1" y cada caso con una probabilidad pronosticada <0.289 se codificaría "0", en lugar del umbral predeterminado de 0.5 del caretpaquete.
coip
2
sí, eso es exactamente correcto, y los otros 2 valores entre paréntesis son sensibilidad y especificidad (honestamente, sin embargo, olvido cuál es cuál)
efh0888
2
Además, desde entonces descubrí que puedes extraerlo de la curva de roc usando lo rocCurve$thresholds[which(rocCurve$sensitivities + rocCurve$specificities == max(rocCurve$sensitivities + rocCurve$specificities))]que también te da la flexibilidad para ponderarlos de manera diferente si lo deseas ... una última cosa a tener en cuenta es que, de manera realista, es probable que desees ajustar el umbral (como lo haría con cualquier hiperparámetro modelo) como describe Max aquí .
efh0888