Sklearn随机森林:.oob_score太低了



我正在搜索随机森林的应用程序,我在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%。

只有7个类要分类,所以2%真的很低。当我交叉验证时,我也一直得到接近75%的分数。

谁能解释一下 .oob_score_ 和坚持/交叉验证分数之间的差异?我希望它们是相似的。

这里有一个类似的问题:

https://stats.stackexchange.com/questions/95818/what-is-a-good-oob-score-for-random-forests

编辑:我想这可能也是一个bug。

代码由我发布的第二个链接中的原始海报给出。唯一的变化是,你必须设置 oob_score = True 当你建立随机森林。

我没有保存我所做的交叉验证测试,但如果人们需要看到它,我可以重做。

问:谁能解释一下……

A: sklearn.ensemble.RandomForestClassifier 对象和它被观察到的 .oob_score_ 属性值不是一个bug相关的问题。

首先,基于 RandomForest 的预测器 { Classifier | Regressor } 属于所谓的集成方法的相当特定的角落,因此要告知,典型的方法,包括交叉验证,与其他AI/ml学习器的工作方式不同

RandomForest "inner"逻辑工作严重与随机过程,由样本数据集( X )与已知 y == { labels(分类)| targets }(解释变量),被分割在整个森林,树木得到引导通过随机数据集分割成部分,这棵树可以看到一部分,树不会看到(形成一个inner-oob-subSET)。

除了对过拟合敏感性的其他影响等,RandomForest集合不需要进行交叉验证,因为它没有设计过拟合。许多论文和Breiman的 (Berkeley)的经验证明都为这种说法提供了支持,因为他们带来了证据,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_ ?

A: .oob_score_是随机的!. . . . . . .....是的,它必须(随机)

虽然这听起来像是一个挑衅性的结尾,但不要放弃你的希望。随机森林集合是一个很好的工具。特征中的分类值可能会出现一些问题(数据集X),然而,一旦你不需要与偏差和过拟合作斗争,处理集成的成本仍然足够。太棒了,不是吗?

由于需要能够在随后的重新运行中重现相同的结果,建议(重新)设置 numpy.random & .set_params( random_state = ... ) 在RANDOM-PROCESS(嵌入到RandomForest集合的每次引导中)之前达到已知状态。这样做,可以观察到"去噪"现象。基于 RandomForest 的预测器朝着更好的 .oob_score_ 方向发展,而不是由于真正地改进了预测能力,这是由更多的集合成员( n_estimators )、更少约束的树结构(max_depthmax_leaf_nodes等)引入的,而不仅仅是随机的"好运气"。在如何分割数据集的随机过程中…

更接近更好的解决方案通常涉及到集成中更多的树(RandomForest决策是基于多数投票的,所以10-estimators不是在高度复杂的数据集上做出好的决策的大基础)。2000以上的数字并不罕见。可以迭代一系列的大小(随机过程保持在状态完全控制下)来演示集成的"改进"。

如果 .oob_score_ 的初始值落在0.51 - 0.53左右,则集成比随机猜测

好1% - 3%。

只有在你把你的基于集成的预测器做得更好之后,你才可以在特征工程等方面进入一些额外的技巧。

aRF_PREDICTOR.oob_score_    Out[79]: 0.638801  # n_estimators =   10
aRF_PREDICTOR.oob_score_    Out[89]: 0.789612  # n_estimators =  100

相关内容

  • 没有找到相关文章

最新更新