插入符号()预测与predict.glm()非常不同

时间:2014-05-22 12:15:22

标签: r glm r-caret confusion-matrix

我正在尝试使用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()参数的设置有误,但我无法弄清楚它是什么。

我真的很感激一些帮助,谢谢你。

1 个答案:

答案 0 :(得分:59)

您正在尝试使用混淆矩阵来了解样本内拟合。您使用glm()函数的第一种方法很好。

使用train()的第二种方法的问题在于返回的对象。您正试图通过fit$pred$pred从中提取样本中的拟合值。但是,fit$pred不包含与chile.vchile$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。我知道我对这个问题的回答是迟到的 - 即。这是一个很老的问题。无论如何都可以回答这些问题吗?我是新来的,在帮助中找不到任何关于“迟到的答案”的内容。