【问题标题】:Poor performance of RandomForestClassifierRandomForestClassifier 性能不佳
【发布时间】: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] 

【问题讨论】:

    标签: python scikit-learn weka random-forest


    【解决方案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】:

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

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-01-03
        • 2019-06-15
        • 2013-06-11
        • 2010-12-31
        • 2012-01-25
        • 2021-12-15
        • 2011-02-13
        • 2011-01-14
        • 2016-12-24
        相关资源
        最近更新 更多