caret train () predice muy diferente de lo que predice.glm()


Estoy tratando de estimar una regresión logística, utilizando la validación cruzada de 10 veces.

#import libraries
library(car); library(caret); library(e1071); library(verification)

#data import and preparation
data(Chile)              
chile        <- na.omit(Chile)  #remove "na's"
chile        <- chile[chile$vote == "Y" | chile$vote == "N" , ] #only "Y" and "N" required
chile$vote   <- factor(chile$vote)      #required to remove unwanted levels 
chile$income <- factor(chile$income)  # treat income as a factor

El objetivo es estimar un modelo glm que predice que el resultado del voto "Y" o "N" dependía de variables explicativas relevantes y, basado en el modelo final, calcular una matriz de confusión y una curva ROC para comprender el comportamiento de los modelos para diferentes niveles de umbral.

La selección del modelo conduce a:

res.chileIII <- glm(vote ~
                           sex       +
                           education +
                           statusquo ,
                           family = binomial(),
                           data = chile)
#prediction
chile.pred <- predict.glm(res.chileIII, type = "response")

Genera:

> head(chile.pred)
          1           2           3           4           5           6 
0.974317861 0.008376988 0.992720134 0.095014139 0.040348115 0.090947144 

Para comparar lo observado con estimación:

chile.v     <- ifelse(chile$vote == "Y", 1, 0)          #to compare the two arrays
chile.predt <- function(t) ifelse(chile.pred > t , 1,0) #t is the threshold for which the confusion matrix shall be computed

Matriz de confusión para t = 0.3:

confusionMatrix(chile.predt(0.3), chile.v)

> confusionMatrix(chile.predt(0.3), chile.v)
Confusion Matrix and Statistics

          Reference
Prediction   0   1
         0 773  44
         1  94 792

               Accuracy : 0.919          
                 95% CI : (0.905, 0.9315)
    No Information Rate : 0.5091         
    P-Value [Acc > NIR] : < 2.2e-16 

Y la curva Roc:

roc.plot(chile.v, chile.pred)

Que parece un modelo razonable.

Ahora en lugar de usar la predicción "normal".función glm () Quiero probar la diferencia de rendimiento a una estimación de validación cruzada de 10 veces.

tc <- trainControl("cv", 10, savePredictions=T)  #"cv" = cross-validation, 10-fold
fit <- train(chile$vote ~ chile$sex            +
                          chile$education      +
                          chile$statusquo      ,
                          data      = chile    ,
                          method    = "glm"    ,
                          family    = binomial ,
                          trControl = tc)

> summary(fit)$coef
                      Estimate Std. Error   z value      Pr(>|z|)
(Intercept)          1.0152702  0.1889646  5.372805  7.752101e-08
`chile$sexM`        -0.5742442  0.2022308 -2.839549  4.517738e-03
`chile$educationPS` -1.1074079  0.2914253 -3.799971  1.447128e-04
`chile$educationS`  -0.6827546  0.2217459 -3.078996  2.076993e-03
`chile$statusquo`    3.1689305  0.1447911 21.886224 3.514468e-106

Todos los parámetros significativos.

fitpred <- ifelse(fit$pred$pred == "Y", 1, 0) #to compare with chile.v

> confusionMatrix(fitpred,chile.v)
Confusion Matrix and Statistics

          Reference
Prediction   0   1
         0 445 429
         1 422 407

 Accuracy : 0.5003          
                 95% CI : (0.4763, 0.5243)
    No Information Rate : 0.5091          
    P-Value [Acc > NIR] : 0.7738

Que es obviamente muy diferente de la matriz de confusión anterior. Mi expectativa era que los resultados de validación cruzada no debe realizar mucho peor que el primer modelo. Sin embargo, los resultados muestran algo más.

Mi suposición es que hay un error con la configuración de los parámetros de train (), pero no puedo averiguar qué es.

Realmente agradecería un poco de ayuda, gracias de antemano.

Author: milos.ai, 2014-05-22

1 answers

Usted está tratando de tener una idea del ajuste de la muestra usando una matriz de confusión. Su primer acercamiento usando la función glm() está bien.

El problema con el segundo enfoque usando train() radica en el objeto devuelto. Está intentando extraer los valores ajustados de la muestra mediante fit$pred$pred. Sin embargo, fit$pred no contiene los valores ajustados que están alineados con chile.v o chile$vote. Contiene las observaciones y valores ajustados de los diferentes (10) pliegues:

> head(fit$pred)
  pred obs rowIndex parameter Resample
1    N   N        2      none   Fold01
2    Y   Y       20      none   Fold01
3    Y   Y       28      none   Fold01
4    N   N       38      none   Fold01
5    N   N       55      none   Fold01
6    N   N       66      none   Fold01
> tail(fit$pred)
     pred obs rowIndex parameter Resample
1698    Y   Y     1592      none   Fold10
1699    Y   N     1594      none   Fold10
1700    N   N     1621      none   Fold10
1701    N   N     1656      none   Fold10
1702    N   N     1671      none   Fold10
1703    Y   Y     1689      none   Fold10 

Entonces, debido a la aleatoriedad de los pliegues, y debido a que está prediciendo 0 o 1, se obtiene una precisión de aproximadamente 50%.

Los valores ajustados de la muestra que está buscando están en fit$finalModel$fitted.values. Usando esos:

fitpred <- fit$finalModel$fitted.values
fitpredt <- function(t) ifelse(fitpred > t , 1,0)
> confusionMatrix(fitpredt(0.3),chile.v)
Confusion Matrix and Statistics

          Reference
Prediction   0   1
         0 773  44
         1  94 792

               Accuracy : 0.919          
                 95% CI : (0.905, 0.9315)
    No Information Rate : 0.5091         
    P-Value [Acc > NIR] : < 2.2e-16      

                  Kappa : 0.8381         
 Mcnemar's Test P-Value : 3.031e-05      

            Sensitivity : 0.8916         
            Specificity : 0.9474         
         Pos Pred Value : 0.9461         
         Neg Pred Value : 0.8939         
             Prevalence : 0.5091         
         Detection Rate : 0.4539         
   Detection Prevalence : 0.4797         
      Balanced Accuracy : 0.9195         

       'Positive' Class : 0               

Ahora la precisión está alrededor del valor esperado. Establecer el umbral en 0.5 produce aproximadamente la misma precisión que la estimación de la validación cruzada de 10 veces:

> confusionMatrix(fitpredt(0.5),chile.v)
Confusion Matrix and Statistics

          Reference
Prediction   0   1
         0 809  64
         1  58 772

               Accuracy : 0.9284          
                 95% CI : (0.9151, 0.9402)
[rest of the output omitted]            

> fit
Generalized Linear Model 

1703 samples
   7 predictors
   2 classes: 'N', 'Y' 

No pre-processing
Resampling: Cross-Validated (10 fold) 

Summary of sample sizes: 1533, 1532, 1532, 1533, 1532, 1533, ... 

Resampling results

  Accuracy  Kappa  Accuracy SD  Kappa SD
  0.927     0.854  0.0134       0.0267  

Además, con respecto a su expectativa "de que los resultados validados cruzados no deben rendir mucho peor que el primer modelo," por favor, compruebe summary(res.chileIII) y summary(fit). Los modelos y coeficientes ajustados son exactamente los mismos, por lo que darán los mismos resultados.

P.D. Sé que mi respuesta a esta pregunta es tardía this es decir, esta es una pregunta bastante vieja. ¿Está bien responder a estas preguntas de todos modos? Soy nuevo aquí y no encontré nada sobre "respuestas tardías" en la ayuda.

 57
Author: thie1e,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-15 00:45:22