Sklearn 中随机森林和额外树的单棵树的投票是如何计算的?

How are the votes of individual trees calculated for Random Forest and Extra Trees in Sklearn?

我一直在用 Rust 构建自己的 Extra Trees (XT) 分类器用于二元分类。为了验证我的分类器的正确性,我一直在将它与 XT 的 Sklearns 实现进行比较,但我不断得到不同的结果。起初我以为我的代码中一定有错误,但现在我意识到这不是错误,而是一种计算集合中不同树之间投票的不同方法。在我的代码中,每棵树都根据叶子数据子集中最频繁的分类进行投票。因此,例如,如果我们正在遍历一棵树,并发现自己位于具有 0 的 40 个分类和 1 的 60 个分类的叶节点处, 树将数据分类为 1.

查看 Sklearn 的 XT 文档 (As seen here),我阅读了以下关于 predict 方法

的行

The predicted class of an input sample is a vote by the trees in the forest, weighted by their probability estimates. That is, the predicted class is the one with highest mean probability estimate across the trees.

虽然这让我对个别树木如何投票有了一些了解,但我还有更多问题。或许关于如何计算这些权重的精确数学表达式会有所帮助,但我还没有在文档中找到它。

我将在接下来的段落中提供更多细节,但我想在这里简明扼要地提出我的问题。 这些权重是如何在高层次上计算的,背后的数学是什么?有没有办法改变单个 XT 树计算投票的方式?

----------------------------------------额外细节 - - - - - - - - - - - - - - - - - - - - - - - -

对于我当前的测试,这就是我构建分类器的方式

classifier = ExtraTreesClassifier(n_estimators=5, criterion='gini', 
              max_depth=1, max_features=5,random_state=0)

为了预测看不见的交易 X,我使用 classifier.predict(X)。翻阅predict(seen here, line 630-ish)的源代码,我看到这是执行二进制分类

的所有代码
proba = self.predict_proba(X)
if self.n_outputs_ == 1:
    return self.classes_.take(np.argmax(proba, axis=1), axis=0)

这段代码的作用对我来说比较明显。它只是通过取 proba 的 argmax 来确定最可能的交易分类。我不明白的是,这个 proba 值最初是如何产生的。我相信 predict_proba 方法 predict 使用的方法在 Line 650-ish 处定义。这是我认为相关的源代码

check_is_fitted(self)
# Check data
X = self._validate_X_predict(X)

# Assign chunk of trees to jobs
n_jobs, _, _ = _partition_estimators(self.n_estimators, self.n_jobs)

# avoid storing the output of every estimator by summing them here
all_proba = [np.zeros((X.shape[0], j), dtype=np.float64)
                 for j in np.atleast_1d(self.n_classes_)]
lock = threading.Lock()
Parallel(n_jobs=n_jobs, verbose=self.verbose,
         **_joblib_parallel_args(require="sharedmem"))(
    delayed(_accumulate_prediction)(e.predict_proba, X, all_proba,
                                    lock)
    for e in self.estimators_)

for proba in all_proba:
    proba /= len(self.estimators_)

if len(all_proba) == 1:
    return all_proba[0]
else:
    return all_proba

我不明白这里到底在计算什么。这是我的足迹有点冷,我感到困惑,发现自己需要帮助。

树可以根据每片叶子中的训练样本比例来预测概率估计。在您的示例中,class 0 的概率为 0.4,class 1.

的概率为 0.6

sklearn 中的随机森林和极其随机的树执行软投票:每棵树如上所述预测 class 概率,然后集成只是对跨树的概率进行平均。这会为每个 class 产生一个概率,然后预测的 class 是概率最大的那个。

在代码中,相关位是_accumulate_predictions,它只是对概率估计求和,然后除以估计数。