class: center, middle, title-slide .title[ # Curva ROC e AUC ] .subtitle[ ## Avaliando classificadores ] .author[ ### Jaime Utria ] .institute[ ### Departamento de EstatÃstica - UFF ] --- <!-- macro comandos matemáticos Latex --> <script type="text/x-mathjax-config"> MathJax.Hub.Config({ TeX: { Macros: { vet: ["{\\mathbf #1}",1], prodint: ["\\langle #1, #2 \\rangle",2], posto: ["{\\mathrm{posto} (#1)}",1], tr: ["{\\mathrm{tr} (#1)}",1] } } }); </script> ## Matriz de confusão: Duas classes .center[ |Real |Predito |Estado | |:--------|:--------|:------| |Positiva |Positiva |VP | |Positiva |Negativa |FN | |Negativa |Positiva |FP | |Negativa |Negativa |VN | ] --- ## Métricas na curva ROC - Taxa de verdadeiros positivos: `$$\mathrm{Sensibilidade = \frac{VP}{VP + FN} = TVP}$$` - Taxa de verdadeiros negativos: `$$\mathrm{Especificidade = \frac{VN}{VN + FP} = TVN}$$` - Taxa de falsos positivos `$$\mathrm{TFP = 1- TVN = \frac{FP}{VN + FP}}$$` --- ## Compensação (*trade-off*) entre TVP e TFP - O classificador ideal seria aquele que produza `\(\mathrm{TVP = 1}\)` e `\(\mathrm{TFP = 0}\)`. - Uma maneira trivial de atingir `\(\mathrm{TVP = 1}\)` é classificando todas as amostras como da classe positiva, logo `\(\mathrm{FN = 0}\)` e `\(\mathrm{VN = 0}\)`. `$$\mathrm{TVP = \frac{VP}{VP + 0}} = 1,$$` `$$\mathrm{TFP = \frac{FP}{FP + 0}} = 1,$$` ou seja, ao aumentarmos a capacidade do classificador de classificar a classe positiva corretamente, diminumos sua capacidade de classificar corretamente a classe negativa. --- - Da mesma maneira para atingir `\(\mathrm{TFP = 0}\)` basta classificar todas as amostras como da classe negativa, logo `\(\mathrm{FP} = 0\)` e `\(\mathrm{VP} = 0\)`. `$$\mathrm{TFP = 1 - \frac{VN}{VN + 0}} = 0,$$` `$$\mathrm{TVP = \frac{0}{0 + FN}} = 0$$` ou seja, ao aumentarmos a capacidade do classificador de classificar a classe negativa corretamente, diminumos sua capacidade de classificar corretamente a classe positiva. **Moral**: A resposta **ideal** está no "meio". **OBS**. A métrica que captura essa compensação entre TVP e TFP é a curva ROC. --- ## Curva ROC - A curva ROC plota a TVP (eixo `\(y\)`) contra a TFP (1-Especificidade (eixo `\(x\)`)), conforme o "corte" é mudado para classificar uma amostra. .center[ <!-- --> ``` ## threshold specificity sensitivity ## 1 0.4938399 0.8068966 0.8545455 ``` ] --- ## AUC - AUC é a área sob a curva ROC. - AUC resume o desempenho global de um classificador binário, conforme mudamos o ponto de "corte" de classificação. - Implicações Práticas: - AUC = 1: Classificador Perfeito (TVP = 1, TFP = 0). - AUC = 0,5: Classificador aleatório (não é melhor que jogar uma moeda honesta). - AUC < 0,5: Pior que aleatório. - 0,5 < AUC < 1: Classificador "realista" - AUC pode ser usado para comparaçaõ de modelos, lida com classes desbalanceadas, não depende de um ponto de corte especifÃco. --- ## Diabetes ``` r library(caret) library(dplyr) ``` ``` r diabetes <- readRDS("diabetes.rds") diabetes <- diabetes[,-1] diabetes$Outcome <- as.factor(diabetes$Outcome) diabetes$Outcome <- factor(diabetes$Outcome, levels = c("0","1"), labels = c("normal", "diabetes")) set.seed(12345) train_index <- createDataPartition(y = diabetes$Outcome, p = 0.8, list = F) training <- diabetes[train_index,] testing <- diabetes[-train_index,] ``` --- ## ``` r ctrl <- trainControl(method = "cv", number = 10, classProbs = TRUE, summaryFunction = twoClassSummary ) grid <- expand.grid(interaction.depth=c(3, 6, 9), n.trees = c(100,200,500), shrinkage = c(0.1,0.05), n.minobsinnode = 10) ``` --- ## Maximizando AUC ``` r # escolhe o modelo (best-hyperparameters) que maximizam AUC model_gbm <- train(Outcome ~., data = training, method = "gbm", trControl = ctrl, metric = "ROC", tuneGrid = grid, verbose = F) # fazemos as predições predictions <- predict(model_gbm, testing) ``` --- <div class="small-output"> ``` r confusionMatrix(predictions, testing$Outcome, positive = "diabetes") ``` ``` ## Confusion Matrix and Statistics ## ## Reference ## Prediction normal diabetes ## normal 65 16 ## diabetes 6 19 ## ## Accuracy : 0.7925 ## 95% CI : (0.7028, 0.8651) ## No Information Rate : 0.6698 ## P-Value [Acc > NIR] : 0.003808 ## ## Kappa : 0.4941 ## ## Mcnemar's Test P-Value : 0.055009 ## ## Sensitivity : 0.5429 ## Specificity : 0.9155 ## Pos Pred Value : 0.7600 ## Neg Pred Value : 0.8025 ## Prevalence : 0.3302 ## Detection Rate : 0.1792 ## Detection Prevalence : 0.2358 ## Balanced Accuracy : 0.7292 ## ## 'Positive' Class : diabetes ## ``` --- ## Classificação multiclasse: Penguins ``` r library(caret) library(MLeval) library(MLmetrics) library(dplyr) library(palmerpenguins) data(penguins) penguins$species <- as.factor(penguins$species) penguins <- na.omit(penguins) colnames(penguins) ``` ``` ## [1] "species" "island" "bill_length_mm" ## [4] "bill_depth_mm" "flipper_length_mm" "body_mass_g" ## [7] "sex" "year" ``` --- ``` r # Remover sex e island das preditoras penguins <- penguins[,c('species', 'bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g')] ``` ``` r # Separar os dados em treino e teste set.seed(12345) index_train <- createDataPartition(y = penguins$species, p = 0.7, list = FALSE) training <- penguins[index_train, ] testing <- penguins[-index_train, ] ``` --- ``` r ctrl <- trainControl( method = "cv", number = 5, classProbs = TRUE, # IMPORTANTE: para obter probabilidades de classe summaryFunction = multiClassSummary # Para métricas multiclasse ) # grid de hiperparâmetros grid <- expand.grid( n.trees = c(50, 100), interaction.depth = c(1, 2), shrinkage = c(0.1, 0.05), n.minobsinnode = 10 ) ``` --- ``` r model_gbm_multi <- train( species ~ ., data = training, method = "gbm", trControl = ctrl, metric = "AUC", # Otimiza AUC média tuneGrid = grid, verbose = FALSE # Evita mensagens durante o treinamento ) ``` ``` r predictions_multi <- predict(model_gbm_multi, testing) ``` --- <div class="small-output"> ``` ## Confusion Matrix and Statistics ## ## Reference ## Prediction Adelie Chinstrap Gentoo ## Adelie 41 1 0 ## Chinstrap 1 19 0 ## Gentoo 1 0 35 ## ## Overall Statistics ## ## Accuracy : 0.9694 ## 95% CI : (0.9131, 0.9936) ## No Information Rate : 0.4388 ## P-Value [Acc > NIR] : < 2.2e-16 ## ## Kappa : 0.9521 ## ## Mcnemar's Test P-Value : NA ## ## Statistics by Class: ## ## Class: Adelie Class: Chinstrap Class: Gentoo ## Sensitivity 0.9535 0.9500 1.0000 ## Specificity 0.9818 0.9872 0.9841 ## Pos Pred Value 0.9762 0.9500 0.9722 ## Neg Pred Value 0.9643 0.9872 1.0000 ## Prevalence 0.4388 0.2041 0.3571 ## Detection Rate 0.4184 0.1939 0.3571 ## Detection Prevalence 0.4286 0.2041 0.3673 ## Balanced Accuracy 0.9677 0.9686 0.9921 ```