J'essaie d'estimer une régression logistique, en utilisant la validation croisée 10 fois.
#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
Le but est d'estimer un modèle glm qui prédit le résultat du vote "Y" ou "N" en fonction des variables explicatives pertinentes et, sur la base du modèle final, de calculer une matrice de confusion et une courbe ROC pour saisir le comportement des modèles pour différents niveaux de seuil .
La sélection du modèle conduit à:
res.chileIII <- glm(vote ~
sex +
education +
statusquo ,
family = binomial(),
data = chile)
#prediction
chile.pred <- predict.glm(res.chileIII, type = "response")
génère:
> head(chile.pred)
1 2 3 4 5 6
0.974317861 0.008376988 0.992720134 0.095014139 0.040348115 0.090947144
pour comparer l'observé avec l'estimation:
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
matrice de confusion pour 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
et la courbe Roc:
roc.plot(chile.v, chile.pred)
ce qui semble être un modèle raisonnable.
Maintenant, au lieu d'utiliser la fonction "normale" de Predict.glm (), je veux tester la différence de performances avec une estimation de validation croisée 10 fois.
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
tous les paramètres sont significatifs.
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
ce qui est évidemment très différent de la matrice de confusion précédente. Je m'attendais à ce que les résultats de la validation croisée ne soient pas beaucoup moins bons que le premier modèle. Cependant, les résultats montrent autre chose.
Mon hypothèse est qu'il y a une erreur avec les réglages des paramètres train () mais je ne peux pas comprendre ce que c'est.
J'apprécierais vraiment de l'aide, merci d'avance.
Vous essayez de vous faire une idée de l'ajustement dans l'échantillon à l'aide d'une matrice de confusion. Votre première approche utilisant la fonction glm()
est très bien.
Le problème avec la deuxième approche utilisant train()
réside dans l'objet renvoyé. Vous essayez d'en extraire les valeurs ajustées dans l'échantillon par fit$pred$pred
. Cependant, fit$pred
Ne contient pas les valeurs ajustées qui sont alignées sur chile.v
Ou chile$vote
. Il contient les observations et les valeurs ajustées des différents (10) plis:
> 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
Donc, en raison du caractère aléatoire des plis, et parce que vous prédisez 0 ou 1, vous obtenez une précision d'environ 50%.
Les valeurs ajustées dans l'échantillon que vous recherchez sont dans fit$finalModel$fitted.values
. En utilisant ceux-ci:
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
Maintenant, la précision se situe autour de la valeur attendue. La définition du seuil à 0,5 donne à peu près la même précision que l'estimation de la validation croisée multipliée par 10:
> 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
De plus, en ce qui concerne votre attente "que les résultats de la validation croisée ne fonctionnent pas bien moins bien que le premier modèle", veuillez vérifier summary(res.chileIII)
et summary(fit)
. Les modèles ajustés et les coefficients sont exactement les mêmes, ils donneront donc les mêmes résultats.
P.S. Je sais que ma réponse à cette question est tardive - c'est-à-dire. c'est une question assez ancienne. Est-il acceptable de répondre à ces questions de toute façon? Je suis nouveau ici et je n'ai rien trouvé sur les "réponses tardives" dans l'aide.