当 classProbs=TRUE 时,在 R 中使用插入符号的 SVM 的不同结果

Posted

技术标签:

【中文标题】当 classProbs=TRUE 时,在 R 中使用插入符号的 SVM 的不同结果【英文标题】:Different results for SVM using Caret in R when classProbs=TRUE 【发布时间】:2020-12-24 04:54:09 【问题描述】:

当我尝试使用支持向量机 (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 的唯一区别是 classProbs = T 包含在 trainControl 中。

如果我比较 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 的预测概率不是一件好事吗?

【问题讨论】:

SVM 不是概率分类器;它们实际上并不产生概率。 @desertnaut 那么从 svm 生成的 ROC 曲线怎么样?我们能相信他们吗?我看到一些著名的机器学习书籍,如 ISLR,包含从 svm 生成的 roc 曲线。 不太清楚,必须检查一下 我不确定。但我认为你的论点也适用于此。 Roc 曲线是不同临界值的敏感性与 1-特异性的图。我正在探索的是不同截止值的准确性 【参考方案1】:

正如desertnaut 在 cmets 中所指出的,SVM 不是概率分类器;它们实际上并不产生概率。

创建概率的一种方法是使用 logit 链接函数和正则化最大似然分数直接训练内核分类器。但是,具有最大似然分数的训练将产生非稀疏内核机器。相反,在训练 SVM 之后,训练额外的 sigmoid 函数的参数以将 SVM 输出映射到概率。参考论文:Probabilistic Outputs for Support Vector Machines and Comparisons to Regularized Likelihood Methods

插入符号 method = "svmRadialSigma" 在内部使用 kernlab::ksvm 和参数 kernel = "rbfdot"。为了让这个函数创建概率,需要参数prob.model = TRUE。借助此功能:

prob.model 如果设置为 TRUE,则构建一个用于计算类的模型 概率或在回归的情况下,计算缩放 拟合残差的拉普拉斯分布参数。 对通过执行 3 折创建的输出数据进行拟合 对训练数据进行交叉验证。有关详细信息,请参阅参考资料。 (默认:假)

裁判详情:

在 prob.model 为 TRUE 时的分类中,3 折交叉验证是 对数据执行,并在 结果决策值 f。

很明显,当需要后验概率时,分类模型会发生一些非常具体的事情。这与仅输出决策值不同。

由此可以得出,根据 sigmoid 函数拟合一些 与在没有prob.model (prob.model = FALSE) 的情况下运行 [kernlab::ksvm] 时相比,决策值可能会有所不同,这就是您在发布的示例中观察到的情况。

如果有两个以上的类,事情会变得更加复杂。

进一步阅读:

Including class probabilities might skew a model in caret?

Isn't caret SVM classification wrong when class probabilities are included?

Why are probabilities and response in ksvm in R not consistent?

[R] Inconsistent results between caret+kernlab versions

【讨论】:

以上是关于当 classProbs=TRUE 时,在 R 中使用插入符号的 SVM 的不同结果的主要内容,如果未能解决你的问题,请参考以下文章

当 index.return=TRUE 时,R 中的排序函数

R闪亮:当multiple = TRUE时selectInput()不反映变量选择

R:同时重定向到标准输出和动态文件

java nio 方面的,我不明白while(true)表示啥?

插入符号中训练数据的 ROC 曲线

在 R 中使用 SVM 且 scale=TRUE(默认)时,是不是可以重命名本地转换中的派生字段名称