【问题标题】:what is the "random" or non-deterministic factor inside SVM prediction by probabilities in e1071 in R?R中e1071中的概率在SVM预测中的“随机”或非确定性因素是什么?
【发布时间】:2016-09-18 21:00:46
【问题描述】:

我是 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"))

然后我得到result1

         setosa versicolor virginica
150 0.009704854  0.1903696 0.7999255

result2 为:

        setosa versicolor virginica
150 0.01006306  0.1749947 0.8149423

结果每一轮都在变化。

这里我使用前 149 行作为训练集,最后一行作为测试。 result1result2 中每个类的概率并不完全相同。我猜在预测过程中有一些“随机”的过程。这是怎么回事?

我知道,如果我在每次通话前set.seed() 使用相同的号码,则可以修复预测的概率。我并不是“瞄准”一个固定的预测结果,只是好奇为什么会发生这种情况以及生成概率预测需要哪些步骤。

微小的差异对 iris 数据并没有真正的大影响,因为最后一个样本仍会被预测为“virginica”。但是当我的数据(有两个 A 和 B 类)不是那么“好”,并且预测未知样本两次成为 A 类的概率分别为 0.489 和 0.521 时,就会令人困惑。

谢谢!

【问题讨论】:

    标签: r svm probability


    【解决方案1】:

    SVM 在开发概率估计时使用交叉验证步骤。 source code for that step 开头为:

    // 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]);
        }
    

    您可以通过在调用之前设置随机种子来创建“可预测性”:

    > 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
    

    但我想起了爱默生的一句警句:“愚蠢的一致性是小人的妖精。”

    【讨论】:

    • 感谢您的回答!您能否更详细地解释来自 e1071 的 svm 如何通过交叉验证生成概率,从而产生随机过程?我没有找到你在源代码中发布的内容,我也没有完全理解你发布的代码。我知道我可以在通话之前设置种子以使其保持一致。我不想要一致的结果,但我只是想了解这是如何发生的。非常感谢!!
    • 在获得压缩包的源版本后,您可以展开并解压它。在那里你应该看到一个名为“src”的文件夹。我提取的代码在名为 svm.cpp 的文件中。使用文本编辑器应该很容易找到。我也不是 C++ 程序员,而且我认为要求我们都不太可能修改的代码的演练对于 SO 问题来说太大了。
    • 对不起,如果我的问题不恰当。但我并没有要求对代码进行演练。我只是想知道您是否可以给我一两句话解释“SVM 在开发概率估计时使用交叉验证步骤”,即如何完成这个交叉验证步骤来开发这里的概率。我不是程序员,也不熟悉编码,我很难通过阅读原始代码自己找到答案。如果您能在不阅读代码的情况下解释这一点,我将不胜感激。但如果占用了你的时间,我很抱歉。谢谢!
    • 也许阅读此 libSVM 的常见问题解答会有所帮助:csie.ntu.edu.tw/~cjlin/libsvm/faq.html#/…
    • 感谢您提供常见问题解答链接!它确实给了我更多我不知道的关于 SVM 的信息。它解释了生成概率而不是类的时间更长,因为它们包含一个交叉验证步骤来生成概率。我可以理解,如果涉及交叉验证,则需要更长的时间。但它是如何参与的?我还是不知道。对不起。我尝试从 e1071 包中读取原始代码 svm.R,但我还没有弄清楚。我不想打扰你走过那个。但如果有人知道答案,我很感激你的帮助。谢谢。
    猜你喜欢
    • 2017-04-13
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 2013-05-22
    • 2018-09-05
    • 2020-11-12
    • 2012-06-16
    相关资源
    最近更新 更多