【问题标题】:Same data, different results on discriminant analysis with MASS and caret相同的数据,使用 MASS 和插入符号进行判别分析的不同结果
【发布时间】:2018-09-19 00:14:25
【问题描述】:

关于 R 中预测分析的一个非常简短的问题。 为什么使用MASS 包线性判别分析获得的交叉验证结果与使用caret 获得的结果如此不同?

#simulate data
set.seed(4321)

training_data = as.data.frame(matrix(rnorm(10000, sd = 12), 100, 10))
training_data$V1 = as.factor(sample(c(1,0), size = 100, replace = T))
names(training_data)[1] = 'outcome'

#MASS LDA
fit.lda_cv_MASS = lda(outcome~.
            , training_data
            , CV=T)
pred = fit.lda_cv_MASS$class
caret::confusionMatrix(pred, training_data$outcome)

这给出了 ~0.53 的准确度

#caret interface LDA
lg.fit_cv_CARET = train(outcome ~ .
               , data=training_data
               , method="lda"
               , trControl = trainControl(method = "LOOCV")
              )
pred = predict(lg.fit_cv_CARET, training_data)
caret::confusionMatrix(pred, training_data$outcome)

现在这导致了 ~0.63 的准确度。

我会假设它们是相同的,因为两者都使用留一法交叉验证。

它们为什么不同?

【问题讨论】:

    标签: r machine-learning cross-validation r-caret


    【解决方案1】:

    这里有两点,第一是你的错误,第二是细微的差别。

    第 1 点。

    当您在插入符号训练对象上调用预测时,您实际上是在适合所有训练数据的模型上调用预测,因此您获得的准确度不是LOOCV,而是训练准确度。要获得重新采样的准确性,您只需调用:

    lg.fit_cv_CARET$results
    #output:
      parameter Accuracy       Kappa
    1      none     0.48 -0.04208417
    

    而不是 0.63,这只是您在火车数据上调用 predict 时获得的火车准确度。

    然而这仍然与 LDA 获得的 0.53 不匹配。要了解原因:

    第2点,在拟合模型时,lda也使用了参数prior

    类成员的先验概率。如果未指定,则类 使用训练集的比例。如果存在,则 概率应按因子水平的顺序指定

    所以ldaCV = TRUE 使用与完整训练集相同的先验。而caret::train 使用由重新采样确定的prior。对于 LOOCV,这应该无关紧要,因为先验变化只是一点点,但是您的数据的类别分离度非常低,因此先验对后验概率的影响比通常情况要大一些。为了证明这一点,对这两种方法使用相同的先验:

    fit.lda_cv_MASS <- lda(outcome~.,
                          training_data,
                          CV=T,
                          prior = c(0.5, 0.5))
    pred = fit.lda_cv_MASS$class
    
    lg.fit_cv_CARET <- train(outcome ~ .,
                             data=training_data,
                             method="lda",
                             trControl = trainControl(method = "LOOCV"),
                             prior = c(0.5, 0.5)
    )
    
    all.equal(lg.fit_cv_CARET$pred$pred, fit.lda_cv_MASS$class)
    #output
    TRUE
    
    caret::confusionMatrix(pred, training_data$outcome)
    #output
    Confusion Matrix and Statistics
    
              Reference
    Prediction  0  1
             0 27 25
             1 24 24
    
                   Accuracy : 0.51           
                     95% CI : (0.408, 0.6114)
        No Information Rate : 0.51           
        P-Value [Acc > NIR] : 0.5401         
    
                      Kappa : 0.0192         
     Mcnemar's Test P-Value : 1.0000         
    
                Sensitivity : 0.5294         
                Specificity : 0.4898         
             Pos Pred Value : 0.5192         
             Neg Pred Value : 0.5000         
                 Prevalence : 0.5100         
             Detection Rate : 0.2700         
       Detection Prevalence : 0.5200         
          Balanced Accuracy : 0.5096         
    
           'Positive' Class : 0 
    
    lg.fit_cv_CARET$results
    #output
      parameter Accuracy      Kappa
    1      none     0.51 0.01921537
    

    【讨论】:

    • 好点(+1)。我建议您明确说明您在 confusionMatrix 中使用的 pred,因为它在 OP 中定义了 2 次。
    猜你喜欢
    • 2019-04-26
    • 1970-01-01
    • 2013-09-25
    • 2021-11-19
    • 1970-01-01
    • 2018-03-27
    • 2015-01-01
    • 1970-01-01
    • 2014-04-07
    相关资源
    最近更新 更多