\(R^2\) de McFadden

Os modelos de regressão logística são ajustados usando o método da máxima verossimilhança, ou seja, para estimar os parâmetros tem-se que maximizar a probabilidade dos dados observados. Sendo assim, o \(R^2\) de McFadden, ou Pseudo-\(R^2\), é uma medida utilizada para medir a qualidade do ajuste (goodness of fit) dos modelos estimados. O \(R^2_{MF}\) Definido como

\[R^2_{MF}=1-\frac{\log(L_{UR})}{\log(L_{R})}\],

onde o \(\log(L_{UR})\) é máximo da função de verossimilhança da regressão não restrita e \(\log(L_{R})\) é o máximo da função de verossimilhança da regressão restrita (modelo nulo) quando \(\beta_1=\beta_2=\beta_3=\cdots=\beta_k\).

Para assimilar a definição, suponha que as variáveis independentes no modelo atual não forneçam informações preditivas sobre o resultado. Se o modelo não tiver capacidade preditiva, embora o valor de probabilidade para o modelo atual seja maior que a probabilidade do modelo nulo, ele não será muito maior. Portanto, a relação das duas log-verossimilhanças será próxima de 1 e $R^2_{MF} $ será próxima de zero.

Curva de ROC

Pensando ainda no modelo logístico, quando a variável resposta é binária, faz-se necessário escolher escolher uma regra de predição, já que o valor estimado assume algo entre 0 e 1. Por exemplo, se o valor estimado for pequeno \(\hat y =0\) e \(\hat y=1\) se for grande. O problema está em saber o ponto de corte onde vai determinar se o valor estimado se aproxima mais do 0 ou do 1.

A curva de ROC (Receiver Operating Characteristic Curve) auxilia na determinação do ponto de corte, “plotando” o gráfico com \(P(\hat Y = 1 |Y = 1)\), chamado de sensibilidade vesus \(1-P(\hat Y = 1 |Y = 1)\) chamado de 1-especificidade para todos os possíveis pontos de corte entre 0 e 1.

Através da combinação ótima tanto da sensibilidade quanto da especificidade, escolhemos o ponto de corte. Classificando o indivíduo como evento dado que ele é não evento (falso positivo) e classificando o indivíduo como não evento dado que ele é evento (falso negativo). Escolhe-se o ponto de corte referente a combinação da sensibilidade e 1-especificidade que mais se aproxima do canto superior esquerdo do gráfico.

Matriz de confusão

Valor Observado (valor verdadeiro)
Valor Predito Y=0 Y=1
Y=0 VN (verdadeiro negativo) FN (falso negativo)
Y=1 FP (falso positivo) VP (verdadeiro positivo)

Acurácia

É a proporção de predições corretas. Definida como

\[ACC=\frac{(VN+VP)}{P+N},\] onde P é o número de eventos e N o número de não eventos.

Sensibilidade

É a proporção de verdadeiros positivos. Definida como

\[SENS=\frac{VP}{(VP+FN)},\]

Especificidade

É a proporção de verdadeiros negativos. Definida como

\[ESPEC=\frac{VN}{(VN+FP)},\]

Verdadeiro Preditivo Positivo

É a proporção de verdadeiros positivos em relação a todas as predições positivas. Definido como

\[VPP=\frac{VP}{(VP+FP)},\]

Verdadeiro Preditivo Negativo

É a proporção de verdadeiros negativos em relação a todas predições negativas. Definido como

\[VPN=\frac{VN}{(VN+FN)},\]

Exemplo no R:

Link do exemplo https://stats.idre.ucla.edu/r/dae/logit-regression/

dados <- read.csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
head(dados)
##   admit gre  gpa rank
## 1     0 380 3.61    3
## 2     1 660 3.67    3
## 3     1 800 4.00    1
## 4     1 640 3.19    4
## 5     0 520 2.93    4
## 6     1 760 3.00    2
#Transformando o rank em fator
dados$rank <- factor(dados$rank)
#Modelo com todas as covariáveis
modelo1 <- glm(admit ~ gre + gpa + rank, data = dados, family = "binomial")
summary(modelo1)
## 
## Call:
## glm(formula = admit ~ gre + gpa + rank, family = "binomial", 
##     data = dados)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.6268  -0.8662  -0.6388   1.1490   2.0790  
## 
## Coefficients:
##              Estimate Std. Error z value Pr(>|z|)    
## (Intercept) -3.989979   1.139951  -3.500 0.000465 ***
## gre          0.002264   0.001094   2.070 0.038465 *  
## gpa          0.804038   0.331819   2.423 0.015388 *  
## rank2       -0.675443   0.316490  -2.134 0.032829 *  
## rank3       -1.340204   0.345306  -3.881 0.000104 ***
## rank4       -1.551464   0.417832  -3.713 0.000205 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 499.98  on 399  degrees of freedom
## Residual deviance: 458.52  on 394  degrees of freedom
## AIC: 470.52
## 
## Number of Fisher Scoring iterations: 4
#Modelo nulo
modelo_nulo <- glm(admit~1, family = "binomial",data = dados)
summary(modelo_nulo)
## 
## Call:
## glm(formula = admit ~ 1, family = "binomial", data = dados)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -0.8741  -0.8741  -0.8741   1.5148   1.5148  
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  -0.7653     0.1074  -7.125 1.04e-12 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 499.98  on 399  degrees of freedom
## Residual deviance: 499.98  on 399  degrees of freedom
## AIC: 501.98
## 
## Number of Fisher Scoring iterations: 4
# R^2 de McFadden 
1-logLik(modelo1)/logLik(modelo_nulo)
## 'log Lik.' 0.08292194 (df=6)
# Pelo pacote DescTools (não precisa criar um modelo nulo)
require(DescTools)
## Loading required package: DescTools
PseudoR2(modelo1, which = NULL)
##   McFadden 
## 0.08292194

Como o valor foi muito baixo,0.082 , o modelo não tem um bom ajuste para a predição.

library(boot)
library(ROCR)
## Loading required package: gplots
## 
## Attaching package: 'gplots'
## The following object is masked from 'package:stats':
## 
##     lowess
rocplot=function(pred,truth, ...){
  predob=prediction(pred,truth)
  perf=performance(predob,"tpr","fpr")
  auc=performance(predob,"auc")@y.values
  plot(perf,main = auc)
  
}
pred=modelo1$fitted.values
rocplot(pred,dados$admit)

O valor de corte para o predição desse modelo será 0.6928, ou seja, os valores acima de 0.6928 será considerado como 1 e abaixo desse valor será considerado como 0.

Prob = predict(modelo1,type="response")
Pred = Prob > 0.6928

# Crinado a matrix de confusão
table(Pred,dados$admit)
##        
## Pred      0   1
##   FALSE 271 124
##   TRUE    2   3

Realmente o modelo não foi bem ajustado,pela matriz de confusão, apesar de indetificar corretamente falsos negativos, quase não indentificou-se verdadeiros positivos, gerando muitos falsos positivos.