在 Scikit-Learn 中训练随机森林中的每棵树的样本列表

数据挖掘 scikit-学习 随机森林 自举 大车
2021-10-16 02:43:13

在 Scikit-learn 的随机森林中,您可以设置 bootstrap=True 并且每棵树都会选择一个样本子集进行训练。有没有办法查看每棵树中使用了哪些样本?

我浏览了有关树估计器的文档以及 Scikit-learn 提供的树的所有属性,但它们似乎都没有提供我正在寻找的东西。

2个回答

我认为不可能直接获得它,但我们可以利用随机种子。

random_stateint, RandomState instance or None, default=None
控制构建树时使用的样本的引导的随机性(如果 bootstrap=True)

这是来自 RF Github 代码

def _generate_sample_indices(random_state, n_samples, n_samples_bootstrap):
    """
    Private function used to _parallel_build_trees function."""

    random_instance = check_random_state(random_state)
    sample_indices = random_instance.randint(0, n_samples, n_samples_bootstrap)

    return sample_indices

因此,如果我们固定上面的种子,例如 2 树,我们可以使用自定义代码获得这些,

import pandas as pd, numpy as np
num = 20 # max index
np.random.seed(0) # Fix the seed

sample_1 = np.random.randint(0,num,(1,num))
oob_1 = [elem for elem in np.arange(num) if elem not in sample_1 ]
sample_2 = np.random.randint(0,num,(1,num))
oob_2 = [elem for elem in np.arange(num) if elem not in sample_2 ]

请使用自定义代码进行验证。我没有验证它。

实际上,这是可能的。答案与@10xAI 给出的答案并没有太大的不同,但它并没有试图隐式地利用随机种子的顺序,因为它会因并行训练而中断。所以上面的答案可能只适用于没有并行训练的树。但不确定。

实际工作的答案很简单,它在于使用存储在每个估计器中的随机生成器并使用它来重做随机采样。

因此,例如,假设rf您训练有素的随机森林,那么通过导入适当的函数并使用每个rf.estimators[0].random_state. 例如,要检索采样和非采样索引的列表:


import sklearn.ensemble._forest as forest_utils

n_samples = len(Y) # number of training samples

n_samples_bootstrap = forest_utils._get_n_samples_bootstrap(
    n_samples, rf.max_samples
)

unsampled_indices_trees = []
sampled_indices_trees = []

for estimator in rf.estimators_:
    unsampled_indices = forest_utils._generate_unsampled_indices(
        estimator.random_state, n_samples, n_samples_bootstrap)
    unsampled_indices_trees.append(unsampled_indices)

    sampled_indices = forest_utils._generate_sample_indices(
        estimator.random_state, n_samples, n_samples_bootstrap)
    sampled_indices_trees.append(sampled_indices)

estimator在这种情况下是决策树,因此可以使用所有方法来计算自定义oob_scores等。

希望这可以帮助!