相同的数据,使用 MASS 和 caret 进行判别分析的不同结果
Same data, different results on discriminant analysis with MASS and caret
关于 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。
我会假设它们是相同的,因为它们都使用留一法交叉验证。
为什么不同?
这里有两点,一是你的错误,二是细微的差别。
第 1 点。
当您对插入符号火车对象调用预测时,您实际上是在对适合所有训练数据的模型调用预测,因此您获得的准确度不是 LOOCV
,而是训练准确度。要获得 re-sample 的准确度,您只需调用:
lg.fit_cv_CARET$results
#output:
parameter Accuracy Kappa
1 none 0.48 -0.04208417
而不是 0.63,它只是在对训练数据调用 predict 时获得的训练准确度。
然而这仍然不符合LDA获得的0.53。了解原因:
要点2.在拟合模型时,lda
也使用参数prior
:
the prior probabilities of class membership. If unspecified, the class
proportions for the training set are used. If present, the
probabilities should be specified in the order of the factor levels
so lda
和 CV = TRUE
使用与完整训练集相同的先验。而 caret::train
使用由 re-sample 确定的 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
关于 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。
我会假设它们是相同的,因为它们都使用留一法交叉验证。
为什么不同?
这里有两点,一是你的错误,二是细微的差别。
第 1 点。
当您对插入符号火车对象调用预测时,您实际上是在对适合所有训练数据的模型调用预测,因此您获得的准确度不是 LOOCV
,而是训练准确度。要获得 re-sample 的准确度,您只需调用:
lg.fit_cv_CARET$results
#output:
parameter Accuracy Kappa
1 none 0.48 -0.04208417
而不是 0.63,它只是在对训练数据调用 predict 时获得的训练准确度。
然而这仍然不符合LDA获得的0.53。了解原因:
要点2.在拟合模型时,lda
也使用参数prior
:
the prior probabilities of class membership. If unspecified, the class proportions for the training set are used. If present, the probabilities should be specified in the order of the factor levels
so lda
和 CV = TRUE
使用与完整训练集相同的先验。而 caret::train
使用由 re-sample 确定的 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