我正在尝试使用10倍交叉验证来估计逻辑回归。
#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
目标是估计一个glm模型,该模型预测投票结果“Y”或“N”取决于相关的解释变量,并根据最终模型计算混淆矩阵和ROC曲线以掌握模型行为不同的阈值水平。
模型选择导致:
res.chileIII <- glm(vote ~
sex +
education +
statusquo ,
family = binomial(),
data = chile)
#prediction
chile.pred <- predict.glm(res.chileIII, type = "response")
产生
> head(chile.pred)
1 2 3 4 5 6
0.974317861 0.008376988 0.992720134 0.095014139 0.040348115 0.090947144
比较观察到的估计值:
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
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
和Roc曲线:
roc.plot(chile.v, chile.pred)
这似乎是一个合理的模型。
现在我没有使用“普通”的predict.glm()函数,而是想测试10倍交叉验证估算的性能差异。
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
所有参数都很重要。
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
显然与之前的混淆矩阵非常不同。我的期望是交叉验证的结果不应该比第一个模型差得多。然而,结果显示了别的东西。
我的假设是train()参数的设置有误,但我无法弄清楚它是什么。
我真的很感激一些帮助,谢谢你。
答案 0 :(得分:59)
您正在尝试使用混淆矩阵来了解样本内拟合。您使用glm()
函数的第一种方法很好。
使用train()
的第二种方法的问题在于返回的对象。您正试图通过fit$pred$pred
从中提取样本中的拟合值。但是,fit$pred
不包含与chile.v
或chile$vote
对齐的拟合值。它包含不同(10)折叠的观察值和拟合值:
> 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
因此,由于折叠的随机性,并且因为您预测0或1,您的准确度大约为50%。
您要查找的样本内拟合值位于fit$finalModel$fitted.values
。使用那些:
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
现在准确度大约是预期值。将阈值设置为0.5会产生与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
此外,关于您的期望“交叉验证结果的效果不应比第一个模型差得多”,请检查summary(res.chileIII)
和summary(fit)
。拟合的模型和系数完全相同,因此它们将给出相同的结果。
P.S。我知道我对这个问题的回答是迟到的 - 即。这是一个很老的问题。无论如何都可以回答这些问题吗?我是新来的,在帮助中找不到任何关于“迟到的答案”的内容。