L'utilisation du package caret est-il possible d'obtenir des matrices de confusion pour des valeurs de seuil spécifiques?

13

J'ai obtenu un modèle de régression logistique (via train) pour une réponse binaire, et j'ai obtenu la matrice de confusion logistique via confusionMatrixin caret. Cela me donne la matrice de confusion du modèle logistique, même si je ne sais pas quel seuil est utilisé pour l'obtenir. Comment obtenir la matrice de confusion pour des valeurs de seuil spécifiques à l'aide de confusionMatrixin caret?

Lait noir
la source
Je n'ai pas de réponse, mais souvent des questions comme celle-ci sont répondues dans le fichier d'aide. Si cela échoue, vous pouvez consulter le code source lui-même. Vous pouvez imprimer la source sur la console en tapant confusionmatrix, sans parenthèses.
shadowtalker
On ne sait pas exactement ce que vous avez fait exactement. Avez-vous appelé la glmfonction à partir du statspackage et transmis son résultat à confusionMatrix? Je ne savais pas qu'on pouvait faire ça, et en lisant le manuel, il n'est pas clair qu'on puisse le faire du tout. Ou avez-vous predictquelque chose? Un court exemple serait utile.
Calimo
1
@Calimo J'ai utilisé la trainfonction caretpour ajuster le modèle, ce qui me permet de le spécifier comme un glm avec une famille binomiale. J'ai ensuite utilisé la predictfonction sur l'objet généré via train.
Black Milk

Réponses:

11

La plupart des modèles de classification dans R produisent à la fois une prédiction de classe et les probabilités pour chaque classe. Pour les données binaires, dans presque tous les cas, la prédiction de classe est basée sur un seuil de probabilité de 50%.

glmest le même. Avec caret, using predict(object, newdata)vous donne la classe prédite et predict(object, new data, type = "prob")vous donnera des probabilités spécifiques à la classe (lorsqu'elle objectest générée par train).

Vous pouvez faire les choses différemment en définissant votre propre modèle et en appliquant le seuil que vous souhaitez. Le caret site Web contient également un exemple qui utilise le rééchantillonnage pour optimiser la coupure de probabilité.

tl; dr

confusionMatrix utilise les classes prévues et donc un seuil de probabilité de 50%

Max

topepo
la source
14

Il existe un moyen assez simple, en supposant 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)

Évidemment, vous pouvez définir le seuil à tout ce que vous voulez essayer ou choisir le "meilleur", où le meilleur signifie la spécificité et la sensibilité combinées les plus élevées:

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

Après avoir regardé l'exemple publié par Max, je ne suis pas sûr qu'il y ait des nuances statistiques rendant mon approche moins souhaitée.

efh0888
la source
Dans le graphique rocCurve en sortie, que signifient les trois valeurs? par exemple, sur mes données, il indique 0,289 (0,853, 0,831). Le 0,289 représente-t-il le meilleur seuil à utiliser pour délimiter le résultat binaire? c'est-à-dire que chaque cas avec une probabilité prédite> 0,289 serait codé "1" et chaque cas avec une probabilité prédite <0,289 serait codé "0", plutôt que le seuil par défaut de 0,5 du caretpackage?
coip
2
oui c'est exactement ça, et les 2 autres valeurs entre parenthèses sont la sensibilité et la spécificité (honnêtement, cependant, j'oublie laquelle est laquelle)
efh0888
2
aussi, depuis lors, j'ai compris que vous pouvez l'extraire de la courbe roc en utilisant rocCurve$thresholds[which(rocCurve$sensitivities + rocCurve$specificities == max(rocCurve$sensitivities + rocCurve$specificities))]ce qui vous donne également la flexibilité de les pondérer différemment si vous le souhaitez ... une dernière chose à noter est que, de façon réaliste, vous voulez probablement régler le seuil (comme vous le feriez avec n'importe quel hyperparamètre de modèle) comme Max le décrit ici .
efh0888