在R中使用Caret进行支持向量机(SVM)模型训练时,当设置classProbs=TRUE时,会得到不同的结果。

3
当我尝试使用支持向量机(SVM)提取预测概率时,遇到了以下问题。通常分类算法的概率截断值为0.5。但我需要分析SVM机器学习算法的准确性如何随着概率截断值的变化而变化。我使用了R中的caret包和留一交叉验证(LOOCV)。首先,我拟合了一个常规的svm模型,没有提取类概率。因此,它只会存储预测的类标签。数据来源:https://www.kaggle.com/uciml/pima-indians-diabetes-database
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))

modelFitlassocvintm1modelFitlassocvintm2唯一的区别是在trainControl中包含了classProbs=T

如果我将modelFitlassocvintm1modelFitlassocvintm2的预测类别进行比较,它们在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时,modelFitlassocvintm1modelFitlassocvintm2的预测类存在差异。我也在使用不同数据集时发现了svm的类似差异。可能的原因是什么?我们不能信任svm的预测概率吗?通常情况下,svm将主体分类为-1或1,具体取决于它相对于超平面的位置。因此,依赖于svm的预测概率并不是一个好主意。

3
SVM并不是概率分类器,它们实际上并不产生概率值。 - desertnaut
@desertnaut,那么SVM生成的ROC曲线怎么样?我们能相信它们吗?我看到一些著名的机器学习书籍,比如ISLR,包括了由SVM生成的ROC曲线。 - student_R123
不太确定,必须检查一下。 - desertnaut
我不确定,但我认为你的论点也适用于那个。ROC曲线是敏感性与1-特异性在不同截止值下的绘图。我正在探索的是在不同截止值下的准确性。 - student_R123
1个回答

2
如评论中所指出的,SVM不是概率分类器;它们实际上不产生概率。
创建概率的一种方法是直接训练一个带有逻辑链接函数和正则化最大似然得分的核分类器。然而,使用最大似然得分进行训练会产生非稀疏核机器。相反,在训练完SVM之后,可以训练另一个sigmoid函数的参数,将SVM输出映射到概率中。参考文献:Probabilistic Outputs for Support Vector Machines and Comparisons to Regularized Likelihood Methods Caret method = "svmRadialSigma" 内部使用 kernlab::ksvm 参数为 kernel = "rbfdot"。为了使该函数产生概率,需要使用参数 prob.model = TRUE。从此函数的帮助文档中得知:
如果将prob.model设置为TRUE,则构建一个模型来计算类别概率,或者在回归的情况下,计算拟合于残差上的Laplacian分布的缩放参数。拟合是在对训练数据执行3倍交叉验证创建的输出数据上完成的。有关详细信息,请参见参考文献。(默认值:FALSE)
所引用的细节如下:
在分类中,当prob.model为TRUE时,在数据上执行3倍交叉验证,并在产生的决策值f上拟合Sigmoid函数。
很明显,当需要后验概率时,针对分类模型正在发生某些非常特定的事情。这与仅输出决策值不同。
由此可以推导出,根据Sigmoid函数拟合,一些决策值可能与运行[kernlab :: ksvm]而没有prob.model(prob.model = FALSE)时不同,这就是您在发布的示例中观察到的情况。
如果存在两个以上的类,则情况会变得更加复杂。
进一步阅读:

包括类概率可能会使caret模型偏移?

当包括类概率时,caret SVM分类是否错误?

为什么R中ksvm的概率和响应不一致?

[R] caret+kernlab版本之间的结果不一致


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接