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_ 太低?的主要内容,如果未能解决你的问题,请参考以下文章

随机森林算法OOB_SCORE最佳特征选择

Scikit-learn 参数 oob_score, oob_score_, oob_prediction_

sklearn 随机森林索引如何特征_importances_

腌制随机森林模型的混淆矩阵

随机森林 sklearn 变量重要性

scikit-learn 中的参数 oob_score_ 等于准确度还是错误?