当我尝试使用支持向量机(SVM)提取预测概率时,遇到了以下问题。通常分类算法的概率截断值为0.5。但我需要分析SVM机器学习算法的准确性如何随着概率截断值的变化而变化。我使用了R中的caret包和留一交叉验证(LOOCV)。首先,我拟合了一个常规的svm模型,没有提取类概率。因此,它只会存储预测的类标签。数据来源:https://www.kaggle.com/uciml/pima-indians-diabetes-database。
为了提取预测概率,我需要在
当预测概率接近0.5时,
require(caret)
set.seed(123)
diabetes <- read.csv("C:/Users/Downloads/228_482_bundle_archive/diabetes.csv")
fitControl1 <- trainControl( method = "LOOCV",savePredictions = T,search = "random")
diabetes$Outcome=factor(diabetes$Outcome)
modelFitlassocvintm1 <- train((Outcome) ~ Pregnancies+BloodPressure+Glucose +
BMI+DiabetesPedigreeFunction +Age
, data=diabetes,
method = "svmRadialSigma",
trControl = fitControl1,
preProcess = c("center", "scale"),
tuneGrid=expand.grid(
.sigma=0.004930389,
.C=9.63979626))
为了提取预测概率,我需要在
trainControl
中指定classProbs = T
。set.seed(123)
fitControl2 <- trainControl( method = "LOOCV",savePredictions = T,classProbs = T)
diabetes$Outcome=factor(diabetes$Outcome)
modelFitlassocvintm2 <- train(make.names(Outcome) ~ Pregnancies+BloodPressure+Glucose +
BMI+DiabetesPedigreeFunction +Age
, data=diabetes,
method = "svmRadialSigma",
trControl = fitControl2,
preProcess = c("center", "scale"),
tuneGrid=expand.grid(
.sigma=0.004930389,
.C=9.63979626))
modelFitlassocvintm1
和modelFitlassocvintm2
唯一的区别是在trainControl
中包含了classProbs=T
。
如果我将modelFitlassocvintm1
和modelFitlassocvintm2
的预测类别进行比较,它们在0.5概率截断下应该是相同的。
但实际情况并非如此。
table(modelFitlassocvintm2$pred$X1 >0.5,modelFitlassocvintm1$pred$pred)
0 1
FALSE 560 0
TRUE 8 200
然后当我进一步调查这8个不同的值时,我得到了以下结果。
subs1=cbind(modelFitlassocvintm2$pred$X1,modelFitlassocvintm2$pred$pred,modelFitlassocvintm1$pred$pred)
subset(subs1,subs1[,2]!=subs1[,3])
[,1] [,2] [,3]
[1,] 0.5078631 2 1
[2,] 0.5056252 2 1
[3,] 0.5113336 2 1
[4,] 0.5048708 2 1
[5,] 0.5033003 2 1
[6,] 0.5014327 2 1
[7,] 0.5111975 2 1
[8,] 0.5136453 2 1
当预测概率接近0.5时,
modelFitlassocvintm1
和modelFitlassocvintm2
的预测类存在差异。我也在使用不同数据集时发现了svm
的类似差异。可能的原因是什么?我们不能信任svm
的预测概率吗?通常情况下,svm将主体分类为-1或1,具体取决于它相对于超平面的位置。因此,依赖于svm的预测概率并不是一个好主意。