Usando o pacote de interpolação é possível obter matrizes de confusão para valores-limite específicos?

13

Eu obtive um modelo de regressão logística (via train) para uma resposta binária e a matriz de confusão logística via confusionMatrixin caret. Isso me fornece a matriz de confusão do modelo logístico, embora não tenha certeza de qual limite está sendo usado para obtê-lo. Como obtenho a matriz de confusão para valores-limite específicos usando confusionMatrixin caret?

Leite preto
fonte
Não tenho uma resposta, mas geralmente perguntas como essa são respondidas no arquivo de ajuda. Se isso falhar, você pode olhar para o próprio código-fonte. Você pode imprimir a fonte no console digitando confusionmatrix, sem parênteses.
shadowtalker
Não está claro o que você fez exatamente. Você chamou a glmfunção do statspacote e passou seu resultado para confusionMatrix? Eu não sabia que alguém poderia fazer isso e, lendo o manual, não está claro se é possível. Ou você fez predictalguma coisa? Um pequeno exemplo ajudaria.
Calimo
1
@Calimo Eu usei a trainfunção caretpara ajustar o modelo, o que me permite especificá-lo como um glm com a família binomial. Eu então usei a predictfunção no objeto gerado via train.
Black Milk

Respostas:

10

A maioria dos modelos de classificação em R produz uma previsão de classe e as probabilidades para cada classe. Para dados binários, em quase todos os casos, a previsão de classe é baseada em um corte de probabilidade de 50%.

glmé o mesmo. Com caret, using predict(object, newdata)fornece a classe prevista e predict(object, new data, type = "prob")fornece probabilidades específicas da classe (quando objecté gerada por train).

Você pode fazer as coisas de maneira diferente, definindo seu próprio modelo e aplicando o ponto de corte que desejar. O caret site também possui um exemplo que utiliza reamostragem para otimizar o corte de probabilidade.

tl; dr

confusionMatrix usa as classes previstas e, portanto, um corte de probabilidade de 50%

Máx.

topepo
fonte
14

Existe uma maneira bastante fácil, assumindo 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, você pode definir o limiar para o que quiser tentar ou escolher o "melhor", onde melhor significa maior especificidade e sensibilidade 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")

Depois de analisar o exemplo que Max postou, não tenho certeza se existem algumas nuances estatísticas que tornam minha abordagem menos desejada.

efh0888
fonte
No gráfico rocCurve emitido, o que os três valores significam? por exemplo, nos meus dados, diz 0,289 (0,853, 0,831). O 0,289 significa o melhor limite que se deve usar na demarcação do resultado binário? ou seja, todo caso com uma probabilidade prevista> 0,289 seria codificado como "1" e todo caso com uma probabilidade prevista <0,289 seria codificado como "0", em vez do limite padrão de 0,5 do caretpacote?
153818 copip em 15/02
2
Sim isso é exatamente correto, e os outros 2 valores entre parênteses são sensibilidade e especificidade (honestamente, porém, não me lembro qual é qual)
efh0888
2
Além disso, desde então, eu descobri que você pode extraí-lo da curva roc usando o rocCurve$thresholds[which(rocCurve$sensitivities + rocCurve$specificities == max(rocCurve$sensitivities + rocCurve$specificities))]que também oferece a flexibilidade de ponderá-los de forma diferente, se você quiser ... uma última coisa a ser observada é que, realisticamente, você provavelmente deseja ajustar o limiar (como você faria com qualquer hiperparâmetro de modelo), como Max descreve aqui .
Efh0888