【问题标题】:Cross validation dataset folds for Random Forest feature importance随机森林特征重要性的交叉验证数据集折叠
【发布时间】:2019-01-18 18:42:42
【问题描述】:

我正在尝试使用交叉验证折叠生成随机森林的特征重要性图。当仅使用特征(X)和目标(y)数据时,实现很简单,例如:

rfc = RandomForestClassifier()
rfc.fit(X, y)
importances = pd.DataFrame({'FEATURE':data_x.columns,'IMPORTANCE':np.round(rfc.feature_importances_,3)})
importances = importances.sort_values('IMPORTANCE',ascending=False).set_index('FEATURE')

print(importances)
importances.plot.bar()
plt.show()

产生:

但是,我如何转换此代码以便为我将创建的每个交叉验证折叠 (k-fold) 创建一个类似的图?

我现在的代码是:

# Empty list storage to collect all results for displaying as plots
mylist = []

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import KFold
kf = KFold(n_splits=3)
for train, test in kf.split(X, y):
    train_data = np.array(X)[train]
    test_data = np.array(y)[test]
for rfc = RandomForestClassifier():
    rfc.fit(train_data, test_data)

例如,上面的代码使用交叉验证技术创建(3 个折叠),我的目标是为所有 3 个折叠创建特征重要性图,从而生成 3 个特征重要性图。目前,它给了我循环错误。

我不确定使用每个创建的(k-folds)分别通过随机森林为每个(k-folds)生成特征重要性图的最有效技术是什么。

【问题讨论】:

    标签: python scikit-learn random-forest


    【解决方案1】:

    错误的原因之一是此代码rfc.fit(train_data, test_data)。您应该将训练标签作为第二个参数,而不是测试数据。

    至于绘图,您可以尝试执行以下代码。我假设您知道在这种情况下,k-folds CV 仅用于选择不同的训练数据集。测试数据被忽略,因为没有做出预测:

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import KFold
    from sklearn.datasets import make_classification
    
    # dummy classification dataset
    X, y = make_classification(n_features=10)
    # dummy feature names
    feature_names = ['F{}'.format(i) for i in range(X.shape[1])]
    
    kf = KFold(n_splits=3)
    rfc = RandomForestClassifier()
    count = 1
    # test data is not needed for fitting
    for train, _ in kf.split(X, y):
        rfc.fit(X[train, :], y[train])
        # sort the feature index by importance score in descending order
        importances_index_desc = np.argsort(rfc.feature_importances_)[::-1]
        feature_labels = [feature_names[i] for i in importances_index_desc]
        # plot
        plt.figure()
        plt.bar(feature_labels, rfc.feature_importances_[importances_index_desc])
        plt.xticks(feature_labels, rotation='vertical')
        plt.ylabel('Importance')
        plt.xlabel('Features')
        plt.title('Fold {}'.format(count))
        count = count + 1
    plt.show()
    

    【讨论】:

    • @Dinesh 你不应该使用编辑建议来提问或提供反馈。您应该添加这样的评论和/或更新您的问题。至于您的问题,您应该能够从 pandas df 列feature_names = data_x.columns 中获取功能名称
    • 我尝试使用您提供的代码行引用列名,但是,我仍然无法生成具有各自特征名称的图。我正在观察相同的“F”格式图。你能告诉我我应该在之前的代码中放置这些区域吗?
    • 您只需要更改声明feature_names 的1 行。为其分配功能名称列表。假设您有一个数据框 data_x 以特征名称作为列,您应该将行替换为 feature_names = list(data_x)
    • 我现在已经能够解决 feature_names 问题,但是我收到了一个新错误:---> 20 feature_labels = [feature_names[i] for i in importants_index_desc] IndexError:列表索引超出范围。我想如果你能就我如何修复这条线提供一些帮助,这个情节肯定会奏效。
    • 我认为你真的需要在 python 基础上工作。此错误仅表明您在feature_names 中列出的大小与X(数据集)的特征/列数不同。如果您仍然无法使这个简单的事情起作用,我建议您在问题中发布您的完整代码和数据集,因为没有简单的方法来判断您引入了什么样的错误
    【解决方案2】:

    这是对我有用的代码:

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import KFold
    from sklearn.datasets import make_classification
    
    # classification dataset
    data_x, data_y = make_classification(n_features=9)
    
    # feature names must be declared outside the function
    # feature_names = list(data_x.columns)
    
    kf = KFold(n_splits=10)
    rfc = RandomForestClassifier()
    count = 1
    # test data is not needed for fitting
    for train, _ in kf.split(data_x, data_y):
        rfc.fit(data_x[train, :], data_y[train])
        # sort the feature index by importance score in descending order
        importances_index_desc = np.argsort(rfc.feature_importances_)[::-1]
        feature_labels = [feature_names[-i] for i in importances_index_desc]
    
        # plot
        plt.figure()
        plt.bar(feature_labels, rfc.feature_importances_[importances_index_desc])
        plt.xticks(feature_labels, rotation='vertical')
        plt.ylabel('Importance')
        plt.xlabel('Features')
        plt.title('Fold {}'.format(count))
        count = count + 1
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2021-05-09
      • 1970-01-01
      • 2021-06-05
      • 2018-09-03
      • 2021-08-29
      • 2014-04-16
      • 2021-06-17
      • 2019-09-15
      • 2015-10-16
      相关资源
      最近更新 更多