RandomForestClassifier 性能不佳

Posted

技术标签:

【中文标题】RandomForestClassifier 性能不佳【英文标题】:Poor performance of RandomForestClassifier 【发布时间】:2016-11-06 20:06:54 【问题描述】:

我编写了以下 Python 代码,用于在来自 UCI ML 存储库的 Forest CoverType 数据集上运行 RandomForestClassifier(使用默认参数设置)。然而,结果非常差,准确率约为 60%,而这种技术应该能够达到 90% 以上(使用例如 Weka)。我已经尝试将 n_estimators 增加到 100,但这并没有带来太大的改进。

有什么想法可以让我在 scikit-learn 中使用这种技术获得更好的结果,或者性能不佳的原因是什么?

    from sklearn.datasets import fetch_covtype
    from sklearn.ensemble import RandomForestClassifier
    from sklearn import cross_validation


    covtype = fetch_covtype()
    clf = RandomForestClassifier()
    scores = cross_validation.cross_val_score(clf, covtype.data, covtype.target)
    print scores

[ 0.5483831   0.58210057  0.61055001] 

【问题讨论】:

【参考方案1】:

通过使用GridSearchCV,我设法对您的模型进行了很好的改进

from sklearn.datasets import fetch_covtype
from sklearn.ensemble import RandomForestClassifier
from sklearn import cross_validation
from sklearn import grid_search
import numpy as np


covtype = fetch_covtype()
clf = RandomForestClassifier()

X_train, X_test, y_train, y_test = cross_validation.train_test_split(covtype.data,
                                                                     covtype.target,
                                                                     test_size=0.33,
                                                                     random_state=42)
params = 'n_estimators':[30, 50, 100],
          'max_features':['sqrt', 'log2', 10]
gsv = grid_search.GridSearchCV(clf, params, cv=3,
                               n_jobs=-1, scoring='f1')
gsv.fit(X_train, y_train)

print metrics.classification_report(y_train, gsv.best_estimator_.predict(X_train))

print metrics.classification_report(y_test, gsv.best_estimator_.predict(X_test))

输出:

         precision    recall  f1-score   support

          1       1.00      1.00      1.00    141862
          2       1.00      1.00      1.00    189778
          3       1.00      1.00      1.00     24058
          4       1.00      1.00      1.00      1872
          5       1.00      1.00      1.00      6268
          6       1.00      1.00      1.00     11605
          7       1.00      1.00      1.00     13835

avg / total       1.00      1.00      1.00    389278

             precision    recall  f1-score   support

          1       0.97      0.95      0.96     69978
          2       0.95      0.97      0.96     93523
          3       0.95      0.96      0.95     11696
          4       0.92      0.86      0.89       875
          5       0.94      0.78      0.86      3225
          6       0.94      0.90      0.92      5762
          7       0.97      0.95      0.96      6675

avg / total       0.96      0.96      0.96    191734

这与Kaggle leaderboard 的分数相差不远(请注意,Kaggle 比赛使用了更具挑战性的数据拆分!)

如果您想看到更多改进,那么您将不得不考虑不均匀的类以及如何最好地选择您的训练数据。

注意

为了节省时间,我使用的估计器数量少于通常所需的数量,但是该模型在训练集上表现良好,因此您可能不必考虑这一点。

我使用了少量的max_features,因为这通常会减少模型训练中的偏差。虽然这并不总是正确的。

我使用f1 评分是因为我不太了解数据集,而f1 在分类问题上往往效果很好。

【讨论】:

我尝试了您的代码并打印了最佳参数 (best_params_),给出了 n_estimators=100 和 max_features=10。然后,我调整了我的代码以使用这些参数,并且还添加了参数 score='f1_weighted'。不幸的是,我仍然得到同样糟糕的结果。有任何想法吗? clf = RandomForestClassifier(n_estimators=100, max_features=10) 分数 = cross_validation.cross_val_score(clf, covtype.data,covtype.target,scoring='f1_weighted')【参考方案2】:

您是否使用相同的数据集和相同的估算器获得了 90% 的结果?因为数据集是分开的

用于训练数据子集的前 11,340 条记录

接下来的 3,780 条记录用于验证数据子集

用于测试数据子集的最后 565,892 条记录

并且文档声称具有以下性能,这使您的未经调整的随机森林变得不那么糟糕:

70% 神经网络(反向传播)

58% 线性判别分析

至于n_estimators 等于 100,您可以增加到 500、1.000 甚至更多。检查每个的结果,并在分数开始稳定时保持数字。

与 Scikit-Learn 相比,问题可能来自 Weka 的默认超参数。您可以调整其中一些以改善您的结果:

max_features 在每个树节点上拆分的特征数。 max_depth 模型可能会因为太深而过度拟合您的训练数据 min_samples_splitmin_samples_leafmin_weight_fraction_leafmax_leaf_nodes 处理样本在叶子之间的重新分配 - 何时保留它们。

您也可以尝试通过组合它们来处理您的特征,或者通过减小维度。

你应该看看 kaggle 脚本,例如 here,它们是否描述了如何使用 ExtraTreesClassifier 获得 78%(但是,训练集包含 11.340 + 3780 个记录 - 他们似乎使用了更多数量的 @ 987654330@虽然

【讨论】:

【参考方案3】:

您可以尝试以下方法来提高您的分数:-

    根据您可用的所有属性训练您的模型。它会过度训练,但它会让你知道你可以在训练集上达到多少准确度。

    接下来使用 clf.feature_importances_ 删除最不重要的特征

    使用 Grid Search CV 调整模型的超参数。使用交叉验证和 oob_score(out of bag score)来获得更好的泛化估计。

【讨论】:

以上是关于RandomForestClassifier 性能不佳的主要内容,如果未能解决你的问题,请参考以下文章

RandomForestClassifier 导入

如何将 RandomForestClassifier 与字符串数据一起使用

ValueError:未知标签类型:RandomForestClassifier 中的“未知”

多标签问题中的 RandomForestClassifier - 它是如何工作的?

拟合模型时更改默认 RandomForestClassifier 的“分数”功能?

RandomForestClassifier参数