问题描述
当我尝试使用支持向量机(SVM
)提取预测概率时,出现了以下问题。通常,分类算法的概率截止值为0.5。但是我需要分析SVM
机器学习算法的准确性随概率截止的变化。
我在caret
中使用了R
程序包,并保留了一个交叉验证(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))
要提取预测概率,我需要在classprobs = T
内指定trainControl
。
set.seed(123)
fitControl2 <- trainControl( method = "LOOCV",classprobs = T)
diabetes$Outcome=factor(diabetes$Outcome)
modelFitlassocvintm2 <- train(make.names(Outcome) ~ Pregnancies+BloodPressure+glucose +
BMI+DiabetesPedigreeFunction +Age,trControl = fitControl2,.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的预测概率不是一件好事吗?
解决方法
正如desertnaut的评论中所述,SVM不是概率分类器;它是概率分类器。他们实际上并没有产生概率。
创建概率的一种方法是直接使用logit链接函数和规则化的最大似然评分来训练内核分类器。但是,以最大似然分数进行训练将产生非稀疏内核机器。取而代之的是,在训练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,则构建用于计算类的模型 概率或回归的情况下,计算比例 残差拟合的拉普拉斯分布的参数。 拟合完成通过执行三折创建的输出数据 对训练数据进行交叉验证。有关详细信息,请参见参考。 (默认:FALSE)
参考的详细信息:
在分类中,当prob.model为TRUE时,三折交叉验证为 在数据上执行S型功能 最终的决策值f。
很明显,当需要后验概率时,分类模型会发生非常特定的事情。与仅输出决策值相比,这是不同的。
由此可以得出,取决于S形函数,一些
决策值可能与不运行kernlab::ksvm
(prob.model
)时运行[prob.model = FALSE
]的情况有所不同,这就是您在发布的示例中所观察到的。
如果有两个以上的类,事情将变得更加复杂。
进一步阅读:
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?