我是 SVM 和 e1071 的新手。我发现每次运行完全相同的代码时结果都不同。
例如:
data(iris)
library(e1071)
model <- svm(Species ~ ., data = iris[-150,], probability = TRUE)
pred <- predict(model, iris[150,-5], probability = TRUE)
result1 <- as.data.frame(attr(pred, "probabilities"))
model <- svm(Species ~ ., data = iris[-150,], probability = TRUE)
pred <- predict(model, iris[150,-5], probability = TRUE)
result2 <- as.data.frame(attr(pred, "probabilities"))
Run Code Online (Sandbox Code Playgroud)
然后我得到了result1:
setosa versicolor virginica
150 0.009704854 0.1903696 0.7999255
Run Code Online (Sandbox Code Playgroud)
并result2作为:
setosa versicolor virginica
150 0.01006306 0.1749947 0.8149423
Run Code Online (Sandbox Code Playgroud)
并且结果每轮都在变化。
在这里,我使用前 149 行作为训练集,最后一行作为测试。result1和result2中每个类的概率并不完全相同。我猜在预测过程中有一些“随机”的过程。这是怎么回事?
我知道如果我set.seed()在每次通话前使用相同的数字,预测的概率可以固定。我不是“瞄准”一个固定的预测结果,只是好奇为什么会发生这种情况以及生成概率预测需要采取哪些步骤。
微小的差异实际上对虹膜数据没有太大影响,因为最后一个样本仍会被预测为“维吉尼亚”。但是当我的数据(有 A 类和 B 类两个)不是那么“好”,并且预测未知样本两次成为 A 类的概率为 0.489 和 0.521 时,就会令人困惑。
谢谢!
SVM 在开发概率估计时使用交叉验证步骤。该步骤的源代码开头为:
// Cross-validation decision values for probability estimates
static void svm_binary_svc_probability(
const svm_problem *prob, const svm_parameter *param,
double Cp, double Cn, double& probA, double& probB)
{
int i;
int nr_fold = 5;
int *perm = Malloc(int,prob->l);
double *dec_values = Malloc(double,prob->l);
// random shuffle
GetRNGstate();
for(i=0;i<prob->l;i++) perm[i]=i;
for(i=0;i<prob->l;i++)
{
int j = i+((int) (unif_rand() * (prob->l-i))) % (prob->l-i);
swap(perm[i],perm[j]);
}
Run Code Online (Sandbox Code Playgroud)
您可以通过在调用之前设置随机种子来创建“可预测性”:
> data(iris)
> library(e1071)
> set.seed(123)
> model <- svm(Species ~ ., data = iris[-150,], probability = TRUE)
> pred <- predict(model, iris[150,-5], probability = TRUE)
> result1 <- as.data.frame(attr(pred, "probabilities"))
> set.seed(123)
> model <- svm(Species ~ ., data = iris[-150,], probability = TRUE)
> pred <- predict(model, iris[150,-5], probability = TRUE)
> result2 <- as.data.frame(attr(pred, "probabilities"))
> result1
setosa versicolor virginica
150 0.009114718 0.1734126 0.8174727
> result2
setosa versicolor virginica
150 0.009114718 0.1734126 0.8174727
Run Code Online (Sandbox Code Playgroud)
但我想起了爱默生的警句:“愚蠢的一致性是小头脑的怪物。”