关于R语言中的预测分析的一个非常简短的问题。为什么使用MASS
包进行线性判别分析得到的交叉验证结果与使用caret
包得到的结果如此不同?
#模拟数据集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 LDAfit.lda_cv_MASS = lda(outcome~. , training_data , CV=T)pred = fit.lda_cv_MASS$classcaret::confusionMatrix(pred, training_data$outcome)
这给出了大约0.53的准确率
#caret接口LDAfit.fit_cv_CARET = train(outcome ~ . , data=training_data , method="lda" , trControl = trainControl(method = "LOOCV") )pred = predict(fit.fit_cv_CARET, training_data)caret::confusionMatrix(pred, training_data$outcome)
现在这结果显示大约0.63的准确率。
我原本以为它们应该是相同的,因为两者都使用了留一法交叉验证。
为什么它们不同?
回答:
这里有两个要点,第一个是你的错误,第二个是一个细微的差异。
要点1.
当你在caret的train对象上调用predict时,实际上是在所有训练数据上拟合的模型上调用predict,因此你得到的准确率不是LOOCV
的准确率,而是训练准确率。要得到重抽样准确率,你只需调用:
fit.fit_cv_CARET$results#output: parameter Accuracy Kappa1 none 0.48 -0.04208417
而不是0.63,这是你对训练数据调用predict时得到的训练准确率。
然而,这仍然与LDA得到的0.53不匹配。为了理解原因:
要点2. 在拟合模型时,lda
也使用了参数prior
:
类成员的先验概率。如果未指定,则使用训练集的类比例。如果已给出,概率应按因子级别的顺序指定
所以lda
在CV = TRUE
时使用与完整训练集相同的先验概率。而caret::train
使用由重抽样确定的prior
。对于留一法交叉验证,这应该影响不大,因为先验概率只变化了一点点,但是你的数据类别分离度非常低,所以先验概率对后验概率的影响比平时更大一些。为了证明这一点,使用相同的先验概率进行两种方法:
fit.lda_cv_MASS <- lda(outcome~., training_data, CV=T, prior = c(0.5, 0.5))pred = fit.lda_cv_MASS$classfit.fit_cv_CARET <- train(outcome ~ ., data=training_data, method="lda", trControl = trainControl(method = "LOOCV"), prior = c(0.5, 0.5))all.equal(fit.fit_cv_CARET$pred$pred, fit.lda_cv_MASS$class)#outputTRUEcaret::confusionMatrix(pred, training_data$outcome)#outputConfusion Matrix and Statistics ReferencePrediction 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 fit.fit_cv_CARET$results#output parameter Accuracy Kappa1 none 0.51 0.01921537