python - 随机森林sklearn
问题描述
如果随机森林需要显式交叉验证,我会感到困惑吗?在随机森林中,我们有 Out of Bag 样本,这可用于计算测试准确度。是否需要显式交叉验证。在随机森林中显式使用 CV 有什么好处吗?我发现基于此代码理解随机森林中的 CV 如何工作令人困惑这是我的代码:
model = BaggingClassifier(base_estimator=cart, n_estimators=num_trees, random_state=seed)
results = cross_validation.cross_val_score(model, X, Y, cv=kfold)
print(results.mean())
解决方案
对于数据集中的每一行,OOB_score
仅使用随机森林中树的子集来计算。因此,它并不能真正反映完整随机森林模型在任何特定数据行上的表现。所以简短的回答是:您仍然需要一个明确的验证集,因为在该集上计算的模型分数(无论是 R2、均方误差等)是基于完整模型所做的预测。
我将用一个(过度简化的)示例进行说明:
假设我们正在为预测房屋销售价格进行回归。您有一个包含5 行的数据集(每行将包含特定房屋的特征,例如它的, YearBuilt
)和一个包含3 棵树的随机森林。LivingArea
NumberOfGarages
Tree 1 Tree 2 Tree 3
------ ------ ------
1 1
2 2
3 3
4
5 5
其中数字 1-5 表示用于训练树的数据集行号(通过引导选择)。然后例如,第 3 行和第 5 行不用于训练树 1,依此类推。OOB_score
无论您是否在 sklearn 的 RandomForest 中设置为true,到此为止的所有内容都已完成。
OOB
如果OOB_score
设置为 true:我们遍历数据集中的每一行,并执行以下操作。
- 第 1 行:只有树 2 没有将其用于拟合/训练。因此,我们仅使用树 2预测并获得第 1 行的分数。
- 第 2 行:只有 Tree 3 没有使用它进行训练。因此,我们仅使用树 3预测并获得第 2 行的分数。
- ...
- 第 4 行:树 2 和树 3 没有使用它进行训练。这所房子的预测销售价格将是树 2 和树 3 预测的平均值,而不是树 1。
这OOB_score
只是所有行的预测分数的平均值。
验证集
将此行为与您使用显式验证集进行比较。您将(例如)在您的验证数据集中有 5 个新行,并且对于每一行,您将通过森林中的所有3 棵树,获取它们各自的预测并将平均值报告为该行销售价格的最终预测.
然后,您可以通过取所有行的误差平均值来报告整个验证集的均方误差(或任何其他指标)。
概括
总结一下,
在计算 时
OOB_score
,每行仅在森林中的树子集上进行预测。而在显式验证集上报告的分数是预测森林中所有树木的每一行的结果,这更能代表测试集中实际发生的情况。所以,这个选项是你想要的。
平均而言,您会期望
OOB_score
比在显式验证集上做的稍微差一些,因为您使用较少的树来预测前者。
评论
也就是说,这两个分数(OOB 与验证)在实践中通常非常接近。如果您有一个小数据集并且买不起验证集,OOB 提供了一个不错的选择。
但是,如果您的数据集足够大,我建议您留出一个明确的验证集(或进行交叉验证)。在这种情况下,这OOB_score
只是一个额外的指标来判断你的模型,但你应该把验证分数放在更高的优先级上。努力提高这个分数。
第二个原因
还有另一种情况,显式验证集比使用 OOB 更合适:当涉及时间序列时。
一个例子是名为Corporación Favorita Grocery Sales Forecasting的 Kaggle 竞赛,您的目标是根据过去 4 年的给定数据预测未来 2 周内每家商店每件商品的杂货价格。
在这种情况下,您的模型(完成后)将预测测试集中的未来价格。因此,您希望在验证模型时尽可能地进行模拟。这意味着:
您希望构建尽可能近的验证集(例如,使用前 2 周的数据)。然后,您的训练数据集是从 4 年前到“今天”之前的 2 周。你在“未来”验证集上进行验证,从 2 周前到“今天”。
如果您使用OOB_score
: 它会随机生成伪验证集(自举的结果),则无法执行此操作,因此您从 OOB 获得的分数将不太有意义,因为您没有模拟上述“未来”效果。生成显式验证集将允许您自由选择您拥有的最新数据进行验证,而不是随机选择。
推荐阅读
- resilience4j - 将 Prometheus 指标与 CircuitBreakerConfigCustomizer 一起使用
- jmeter - 如何管理客户端证书的大型密钥库以使用 JMeter 加载测试 Mutual TLS
- python - 用python中的字符串替换列表中的多个字符串并获取替换字符串出现的计数
- javascript - Android反应原生接近传感器
- python - sqlalchemy 连接烧瓶
- javascript - 获取请求后重定向需要两次点击?
- objective-c - TVOS 上的 contentOverlayView 未显示
- assembly - 如何在 x86 程序集中将 16 位寄存器移动到 8 位寄存器?
- regex - Delphi中用于StringList中所有匹配行的正则表达式
- c++ - 我是否正确推理缓存性能?