我正在尝试使用 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()参数的设置有错误,但我不知道它是什么。
我真的很感激一些帮助,提前谢谢你。
您正在尝试使用混淆矩阵来了解样本内拟合。您使用
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)
。拟合的模型和系数完全相同,因此它们会给出相同的结果。