如何在 Scikit-Learn 的随机森林分类器中设置子样本大小?特别是对于不平衡的数据

Posted

技术标签:

【中文标题】如何在 Scikit-Learn 的随机森林分类器中设置子样本大小?特别是对于不平衡的数据【英文标题】:How can I set sub-sample size in Random Forest Classifier in Scikit-Learn? Especially for imbalanced data 【发布时间】:2017-12-10 20:28:58 【问题描述】:

目前,我正在 Sklearn 中为我的不平衡数据实施 RandomForestClassifier。我不太清楚 RF 在 Sklearn 中的工作原理。以下是我的担忧:

    根据文档,似乎没有办法为每个树学习器设置子样本大小(即小于原始数据大小)。但实际上,在随机森林算法中,我们需要获取每棵树的样本子集和特征子集。我不确定我们能否通过 Sklearn 实现这一目标?如果是,如何?

Folwoing 是 Sklearn 中对 RandomForestClassifier 的描述。

“随机森林是一种元估计器,它在数据集的各种子样本上拟合多个决策树分类器,并使用平均来提高预测准确度和控制过拟合。子样本大小为始终与原始输入样本大小相同,但如果 bootstrap=True(默认),则使用替换绘制样本。”

在这里我发现了一个类似的问题。但这个问题的答案并不多。

How can SciKit-Learn Random Forest sub sample size may be equal to original training data size?

    对于不平衡的数据,如果我们可以通过 Sklearn 进行子样本提取(即解决上面的问题 #1),我们可以做平衡随机森林吗?即对于每个树学习器,它将从人口较少的类中提取一个子集,并从人口较多的类中提取相同数量的样本,以构成两个类均等分布的整个训练集。然后重复该过程一批时间(即树数)。

谢谢! 程

【问题讨论】:

对于第一个问题,您似乎无法为每棵树选择子样本的大小。至于数据不平衡的问题,这就是class_weight 参数的作用。 感谢您的回答。但根据我的理解,“class_weight”参数旨在调整预测错误,从而给错误预测的情况和人口较少的类带来更多的惩罚。但它不能为每个树学习器在两个类之间进行平衡采样。 您还可以调整fit 方法的sample_weight 参数。缺少这些和上述内容,您可能不得不求助于手动复制频率较低的类的样本。 【参考方案1】:

没有明显的方法,但是你可以在sklearn.ensemble.forest中破解采样方法。

(2021-04-23 更新,因为我发现 sklearn 重构了代码)

通过使用set_rf_samples(n),您可以强制树对n行进行子采样,并调用reset_rf_samples()对整个数据集进行采样。

对于版本

from sklearn.ensemble import forest

def set_rf_samples(n):
    """ Changes Scikit learn's random forests to give each tree a random sample of
    n random rows.
    """
    forest._generate_sample_indices = (lambda rs, n_samples:
        forest.check_random_state(rs).randint(0, n_samples, n))

def reset_rf_samples():
    """ Undoes the changes produced by set_rf_samples.
    """
    forest._generate_sample_indices = (lambda rs, n_samples:
        forest.check_random_state(rs).randint(0, n_samples, n_samples))
  

对于版本 >=0.22.0

现在有一个可用的参数https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html

max_samples: int or float, default=None

   If bootstrap is True, the number of samples to draw from X to train each base estimator.

   If None (default), then draw X.shape[0] samples.

   If int, then draw max_samples samples.

   If float, then draw max_samples * X.shape[0] samples. Thus, max_samples should be in the interval (0, 1).

参考:fast.ai 机器学习课程

【讨论】:

今天我尝试使用此方法,但在 scikit-learn 上不起作用>=0.22,因为“森林”模块现在已移至“_forest”,因此需要进行一些更改才能使其工作。

以上是关于如何在 Scikit-Learn 的随机森林分类器中设置子样本大小?特别是对于不平衡的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 scikit-learn 的随机森林的 graphviz-graph 中找到一个类?

关于决策树和随机森林分类器(scikit)的疑问

使用 scikit-learn 并行生成随机森林

有没有办法在 Python 中为具有多个分类的随机森林制作部分依赖图(使用 scikit-learn)?

火炉炼AI机器学习051-视觉词袋模型+极端随机森林建立图像分类器

scikit-learn随机森林调参小结