如何在 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 中找到一个类?
有没有办法在 Python 中为具有多个分类的随机森林制作部分依赖图(使用 scikit-learn)?