为什么重要性参数会影响 R 中随机森林的性能?

Tin*_*inu 7 random r machine-learning random-forest random-seed

在使用随机森林时,R我遇到了以下情况:

library(randomForest)
set.seed(42)
data(iris)
rf_noImportance <- randomForest(Species~.,data=iris,ntree=100,importance=F)
print(table(predict(rf_noImportance),iris$Species))
Run Code Online (Sandbox Code Playgroud)

输出:

            setosa versicolor virginica
 setosa         50          0         0
 versicolor      0         47         3
 virginica       0          3        47
Run Code Online (Sandbox Code Playgroud)

library(randomForest)
set.seed(42)
data(iris)  
rf_importance <- randomForest(Species~.,data=iris,ntree=100,importance=T)
print(table(predict(rf_importance),iris$Species))
Run Code Online (Sandbox Code Playgroud)

输出:

            setosa versicolor virginica
 setosa         50          0         0
 versicolor      0         47         4
 virginica       0          3        46
Run Code Online (Sandbox Code Playgroud)

在我设置的第一个示例中importance = FALSE,在第二个示例中TRUE。根据我的理解,这不应该影响结果预测。文档中也没有关于这种行为的迹象。

根据交叉验证线程Do近度或重要性影响随机森林的预测吗?,重要性标志不应该影响预测,但在上面的例子中很明显。

那么为什么方法的重要性参数会randomForest影响模型的性能呢?

des*_*aut 7

这是证明可重复性极限的一个很好的例子;简而言之:

如果实验以不同的方式调用随机数生成器,则修复随机种子不会使结果具有可比性。

让我们看看为什么这里会这样......

所有再现性研究都基于一个强大的隐含假设:所有其他条件相同;如果两个实验之间的变化使这个假设无效,我们不能期望您在这里寻求的确定性意义上的再现性(我们当然可能仍然期望统计意义上的再现性,但这不是这里的问题)。

您在此处介绍的两种情况(计算特征重要性与否)之间的区别非常微妙;要了解为什么它实际上违反了上述原则,我们必须在文档和源代码中进行一些挖掘。

RF函数的文档importance已经提供了一个强有力的提示(重点是我的):

以下是变量重要性度量的定义。第一个度量是从排列OOB 数据 [...]计算的,然后在排列每个预测变量后进行相同的操作。

你可能已经开始怀疑了;这种数据排列通常在随机意义上执行,因此当我们使用 时importance=TRUE,可能会调用随机数生成器 (RNG) 进行一个额外的过程,而在这种importance=FALSE情况下不存在该过程。

换句话说:如果在这种importance=TRUE情况下 RNG 以一种不存在的方式参与importance=FALSE,那么从第一次在程序中发生这样的事情开始,这两种情况就不再具有确定性可比性,而不管公共随机种子如何。

在这一点上,这可能是一个强烈的暗示,但也只是一种猜测;毕竟,原则上,置换可以确定性地执行,即不涉及任何随机过程(因此不涉及 RNG)。吸烟枪在哪里?

事实证明,确凿的证据确实存在,埋藏在randomForestR 包使用的底层 C 源代码中;这是 C 函数的相关部分permuteOOB

/* Permute tp */
    last = nOOB;
    for (i = 0; i < nOOB; ++i) {
        k = (int) last * unif_rand();
        tmp = tp[last - 1];
        tp[last - 1] = tp[k];
        tp[k] = tmp;
        last--;
    }
Run Code Online (Sandbox Code Playgroud)

我们可以清楚地看到在unif_rand()代码片段的第 4 行(此处为源代码)调用的函数(即 RNG),仅在我们请求时调用的方法中importance=TRUE,而不是在相反的情况下。

可以说,并且鉴于 RF 是一种算法,其中随机性(因此使用 RNG)从太多点进入,这应该足以证明为什么您提出的两种情况确实不期望是相同的,因为不同的用途的 RNG 使实际结果发散。另一方面,150 个样本中一次错误分类的差异应该足以保证两个案例在统计上仍然相似。同样明显的是,这里微妙的实现问题(即 RNG 的参与)并没有违反两个结果在理论上应该相等的期望