当 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))
modelFitlassocvintm1
和 modelFitlassocvintm2
的唯一区别是 classProbs = T
包含在 trainControl
中。
如果我比较 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 的预测概率不是一件好事吗?
【问题讨论】:
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()不反映变量选择