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.
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.
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