当 classProbs=TRUE 时,在 R 中使用 Caret 的 SVM 的不同结果
Different results for SVM using Caret in R when classProbs=TRUE
当我尝试使用支持向量机 (SVM
) 提取预测概率时,我遇到了以下问题。通常 classification 算法的概率截止值为 0.5。但我需要分析 SVM
机器学习算法的准确度如何随概率截止值变化。
我在 R
中使用了 caret
包和留一法交叉验证 (LOOCV)
首先,我在不提取 class 概率的情况下拟合了常规 svm 模型。所以它只会存储预测的 class 标签。
数据来源: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
的唯一区别是在 trainControl
.
中包含了 classProbs = T
如果我比较 modelFitlassocvintm1
和 modelFitlassocvintm2
的预测 classes,它在 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
中预测的class似乎存在差异。我也看到 svm
使用不同的数据集也有类似的差异。
这可能是什么原因?我们不能相信 svm
的预测概率吗?通常,svm class 将主题定义为 -1 或 1 ,具体取决于它相对于超平面的一侧。所以依靠 svm 的预测概率不是一件好事吗?
正如 desertnaut 在评论中指出的那样,SVM 不是概率分类器;它们实际上并不产生概率。
创建概率的一种方法是直接使用 logit link 函数和正则化最大似然分数训练核分类器。但是,具有最大似然分数的训练将产生 non-sparse 核机器。相反,在训练 SVM 之后,训练一个额外的 S 型函数的参数以将 SVM 输出映射到概率。参考论文:Probabilistic Outputs for Support Vector Machines and Comparisons to Regularized Likelihood Methods
插入符 method = "svmRadialSigma"
在内部使用 kernlab::ksvm
和参数 kernel = "rbfdot"
。为了让这个函数创建概率,需要参数 prob.model = TRUE
。来自这个函数的帮助:
prob.model if set to TRUE builds a model for calculating class
probabilities or in case of regression, calculates the scaling
parameter of the Laplacian distribution fitted on the residuals.
Fitting is done on output data created by performing a 3-fold
cross-validation on the training data. For details see references.
(default: FALSE)
参考详情:
In classification when prob.model is TRUE a 3-fold cross validation is
performed on the data and a sigmoid function is fitted on the
resulting decision values f.
很明显,当需要后验概率时,分类模型正在发生一些非常具体的事情。这与仅输出决策值不同。
由此可以推导出,根据 sigmoid 函数拟合一些
与 运行 [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?
当我尝试使用支持向量机 (SVM
) 提取预测概率时,我遇到了以下问题。通常 classification 算法的概率截止值为 0.5。但我需要分析 SVM
机器学习算法的准确度如何随概率截止值变化。
我在 R
中使用了 caret
包和留一法交叉验证 (LOOCV)
首先,我在不提取 class 概率的情况下拟合了常规 svm 模型。所以它只会存储预测的 class 标签。
数据来源: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
的唯一区别是在 trainControl
.
classProbs = T
如果我比较 modelFitlassocvintm1
和 modelFitlassocvintm2
的预测 classes,它在 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
中预测的class似乎存在差异。我也看到 svm
使用不同的数据集也有类似的差异。
这可能是什么原因?我们不能相信 svm
的预测概率吗?通常,svm class 将主题定义为 -1 或 1 ,具体取决于它相对于超平面的一侧。所以依靠 svm 的预测概率不是一件好事吗?
正如 desertnaut 在评论中指出的那样,SVM 不是概率分类器;它们实际上并不产生概率。
创建概率的一种方法是直接使用 logit link 函数和正则化最大似然分数训练核分类器。但是,具有最大似然分数的训练将产生 non-sparse 核机器。相反,在训练 SVM 之后,训练一个额外的 S 型函数的参数以将 SVM 输出映射到概率。参考论文:Probabilistic Outputs for Support Vector Machines and Comparisons to Regularized Likelihood Methods
插入符 method = "svmRadialSigma"
在内部使用 kernlab::ksvm
和参数 kernel = "rbfdot"
。为了让这个函数创建概率,需要参数 prob.model = TRUE
。来自这个函数的帮助:
prob.model if set to TRUE builds a model for calculating class probabilities or in case of regression, calculates the scaling parameter of the Laplacian distribution fitted on the residuals. Fitting is done on output data created by performing a 3-fold cross-validation on the training data. For details see references. (default: FALSE)
参考详情:
In classification when prob.model is TRUE a 3-fold cross validation is performed on the data and a sigmoid function is fitted on the resulting decision values f.
很明显,当需要后验概率时,分类模型正在发生一些非常具体的事情。这与仅输出决策值不同。
由此可以推导出,根据 sigmoid 函数拟合一些
与 运行 [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?