web-dev-qa-db-ja.com

キャレットtrain()は、predict.glm()と非常に異なる予測をします

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()パラメータの設定に間違いがあるということですが、それが何であるかを理解することはできません。

私はいくつかの助けを本当に感謝します、前もって感謝します。

30
Vincent

混同マトリックスを使用して、サンプル内の近似のアイデアを得ようとしています。 glm()関数を使用する最初のアプローチは問題ありません。

train()を使用する2番目のアプローチの問題は、返されるオブジェクトにあります。 _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)を確認してください。適合モデルと係数はまったく同じであるため、同じ結果が得られます。

追伸私はこの質問に対する私の答えが遅いことを知っています-つまりこれはかなり古い質問です。とにかくこれらの質問に答えても大丈夫ですか?私はここに新しく、ヘルプで「遅い答え」について何も見つけませんでした。

62
thie1e