sklearn 随机森林:.oob_score_ 太低?
Posted
技术标签:
【中文标题】sklearn 随机森林:.oob_score_ 太低?【英文标题】:sklearn random forest: .oob_score_ too low? 【发布时间】:2014-09-04 09:57:38 【问题描述】:我在搜索随机森林的应用,在Kaggle上发现了以下知识竞赛:
https://www.kaggle.com/c/forest-cover-type-prediction.
遵循建议
https://www.kaggle.com/c/forest-cover-type-prediction/forums/t/8182/first-try-with-random-forests-scikit-learn,
我使用 sklearn
构建了一个包含 500 棵树的随机森林。
.oob_score_
约为 2%,但坚持集的得分约为 75%。
只有七个类可以分类,所以 2% 真的很低。当我进行交叉验证时,我的分数也始终接近 75%。
谁能解释 .oob_score_
和坚持/交叉验证分数之间的差异?我希望它们是相似的。
这里有一个类似的问题:
https://stats.stackexchange.com/questions/95818/what-is-a-good-oob-score-for-random-forests
编辑:我认为这也可能是一个错误。
代码由我发布的第二个链接中的原始海报给出。唯一的变化是您必须在构建随机森林时设置 oob_score = True
。
我没有保存我所做的交叉验证测试,但如果人们需要查看它,我可以重做。
【问题讨论】:
这个问题似乎是题外话,因为它是关于统计,而不是编程。 嗯,这听起来像是一个错误:-/。你能把你的代码贴在某个地方吗? 【参考方案1】:问:谁能解释这个差异...
答: sklearn.ensemble.RandomForestClassifier
对象和观察到的 .oob_score_
属性值不是与错误相关的问题。
首先,基于 RandomForest
的预测器 Classifier | Regressor
属于所谓的集成方法中相当具体的一角,因此请注意,典型强>方法,包括。 交叉验证,与其他 AI/ML 学习者的工作方式不同。
RandomForest "inner"-logic works heavily with RANDOM-PROCESS,由已知的样本(DataSET X
) y == labels
(用于分类器)| targets
(用于回归器)@987654330 @,在整个森林生成过程中被拆分,其中树被 引导 随机拆分 DataSET 成部分,树可以看到,而一部分,树将看不到(因此形成内部oob-subSET )。
除了对过度拟合等敏感度的其他影响之外,RandomForest 集成不需要进行交叉验证,因为它不会在设计上过度拟合。许多论文和 Breiman's(伯克利)经验证明都为这种说法提供了支持,因为他们提供了证据,即 CV-ed 预测器将具有相同的 .oob_score_
import sklearn.ensemble
aRF_PREDICTOR = sklearn.ensemble.RandomForestRegressor( n_estimators = 10, # The number of trees in the forest.
criterion = 'mse', # Regressor: 'mse' | Classifier: 'gini'
max_depth = None,
min_samples_split = 2,
min_samples_leaf = 1,
min_weight_fraction_leaf = 0.0,
max_features = 'auto',
max_leaf_nodes = None,
bootstrap = True,
oob_score = False, # SET True to get inner-CrossValidation-alike .oob_score_ attribute calculated right during Training-phase on the whole DataSET
n_jobs = 1, # 1 | n-cores | -1 == all-cores
random_state = None,
verbose = 0,
warm_start = False
)
aRF_PREDICTOR.estimators_ # aList of <DecisionTreeRegressor> The collection of fitted sub-estimators.
aRF_PREDICTOR.feature_importances_ # array of shape = [n_features] The feature importances (the higher, the more important the feature).
aRF_PREDICTOR.oob_score_ # float Score of the training dataset obtained using an out-of-bag estimate.
aRF_PREDICTOR.oob_prediction_ # array of shape = [n_samples] Prediction computed with out-of-bag estimate on the training set.
aRF_PREDICTOR.apply( X ) # Apply trees in the forest to X, return leaf indices.
aRF_PREDICTOR.fit( X, y[, sample_weight] ) # Build a forest of trees from the training set (X, y).
aRF_PREDICTOR.fit_transform( X[, y] ) # Fit to data, then transform it.
aRF_PREDICTOR.get_params( [deep] ) # Get parameters for this estimator.
aRF_PREDICTOR.predict( X ) # Predict regression target for X.
aRF_PREDICTOR.score( X, y[, sample_weight] ) # Returns the coefficient of determination R^2 of the prediction.
aRF_PREDICTOR.set_params( **params ) # Set the parameters of this estimator.
aRF_PREDICTOR.transform( X[, threshold] ) # Reduce X to its most important features.
还应告知,默认值不是最好的,在任何情况下都不是很好。在进一步移动之前,应注意问题域,以便提出一组合理的 ensemble
参数化。
问:什么是好的 .oob_score_ ?
答:.oob_score_ 是随机的! . . . . . . .....是的,它必须(随机)
虽然这听起来是一个挑衅的尾声,但不要放弃你的希望。
RandomForest ensemble 是一个很棒的工具。特征中的分类值可能会带来一些问题(DataSET X
),但是一旦您不需要与偏见或过度拟合作斗争,处理集成的成本仍然是足够的。 太好了,不是吗?
由于需要能够在随后的重新运行中重现相同的结果,推荐的做法是(重新)设置 numpy.random
和 .set_params( random_state = ... )
到 RANDOM-PROCESS 之前的已知状态(嵌入到 RandomForest 集成的每个引导程序中)。这样做,人们可能会观察到基于 RandomForest
的预测器向更好的 .oob_score_
方向“去噪”进展,而不是因为 真正 改进的 由更多集成成员 (n_estimators
) 引入的预测能力,较少约束的树构造 (max_depth
, max_leaf_nodes
等) 而不是在如何拆分数据集的随机过程中只是随机地通过“更好的运气”......
更接近更好的解决方案通常需要更多的树进入集成(RandomForest 决策基于多数票,因此 10 个估计器并不是在高度复杂的 DataSET 上做出良好决策的重要基础)。 2000 以上的数字并不少见。一个人可能会迭代一系列尺寸(RANDOM-PROCESS 保持在状态完全控制之下)以展示整体“改进”。
如果 .oob_score_
的初始值落在大约 0.51 - 0.53 左右,那么你的集合比 RANDOM-GUESS 好 1% - 3%
只有在您使基于集成的预测器变得更好之后,您才能进入特征工程等方面的一些额外技巧。
aRF_PREDICTOR.oob_score_ Out[79]: 0.638801 # n_estimators = 10
aRF_PREDICTOR.oob_score_ Out[89]: 0.789612 # n_estimators = 100
【讨论】:
谢谢。我的观点是 oob_score 相对于 CV 或坚持分数非常低。无论如何,我无法再重现该问题。现在所有分数都相似。 顺便说一句,您使用的是哪个scikit-learn
版本? Pre-0.15
有相当不同的内部运作。对于最近的0.16.1-stable
(希望也有0.17.0-wet-ink
),您的.oob_score_
对拥有数百棵树的森林的调用应该是合理的。
我不记得我发帖时使用的是哪个版本。我可能接近当时的最新版本。我使用 0.16.1 重新运行了测试。
好的。很高兴知道。您在 DataSET 中有多少示例?在 RandomForest 学习者中有一个相当大的例外,即他们的 .oob_score_ for CV 限制为整个 DataSET 的 .oob_score_。这使得将整个 DataSET 合并到训练阶段变得可行,并且内部机制直接通过用于生成树的 DataSET 的随机拆分来处理 OOB 样本。更多关于学术论文和 Scikit-learn 文档的信息。仍在试验树的深度和参数的最大数量,正如 Kaggle 上所说的保持树的“多样性”很高
“如果 .oob_score_ ~0.51 - 0.53 你的集合比随机猜测好 1% - 3% 那不正确,他说这是一个七类分类问题。随机猜测约为 0.14。oob_score 为 0.02 远比随机猜测差。以上是关于sklearn 随机森林:.oob_score_ 太低?的主要内容,如果未能解决你的问题,请参考以下文章
Scikit-learn 参数 oob_score, oob_score_, oob_prediction_