sklearn随机森林如何计算feature_importances_属性?

7

我已经使用了sklearn中的RandomForestClassifier来确定数据集中重要的特征。我该如何返回实际的特征名称(我的变量标记为x1,x2,x3等),而不是它们的相对名称(它告诉我重要的特征是“12”,“22”等)。以下是我目前用来返回重要特征的代码。

important_features = []
for x,i in enumerate(rf.feature_importances_):
    if i>np.average(rf.feature_importances_):
        important_features.append(str(x))
print important_features

此外,为了理解索引,我能够找到重要的特征“12”实际上是什么(它是变量x14)。当我将变量x14移动到训练数据集的0索引位置并再次运行代码时,它应该告诉我特征“0”很重要,但它没有这样做,就好像它不能再看到那个特征了,而第一个列出的特征实际上是第一次运行代码时列出的第二个特征(特征'22')。
我想也许feature_importances_实际上在使用第一列(我放置x14的地方)作为其余训练数据集的ID,因此在选择重要特征时忽略它。有人可以解释一下这两个问题吗?提前感谢您的任何帮助。
编辑 以下是我如何存储特征名称:
tgmc_reader = csv.reader(csvfile)
row = tgmc_reader.next()    #Header contains feature names
feature_names = np.array(row)

然后我加载了数据集和目标类。
tgmc_x, tgmc_y = [], []
for row in tgmc_reader:
    tgmc_x.append(row[3:])    #This says predictors start at the 4th column, columns 2 and 3 are just considered ID variables.
    tgmc_y.append(row[0])     #Target column is the first in the dataset

然后将数据集分成测试和训练部分。
from sklearn.cross_validation import train_test_split

x_train, x_test, y_train, y_test = train_test_split(tgmc_x, tgmc_y, test_size=.10, random_state=33)

然后适配模型。
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_estimators=1, criterion='entropy', max_features=2, max_depth=5, bootstrap=True, oob_score=True, n_jobs=2, random_state=33)
rf = rf.fit(x_train, y_train)

然后返回重要的功能特性。
important_features = []
for x,i in enumerate(rf.feature_importances_):
    if i>np.average(rf.feature_importances_):
        important_features.append((x))


我采纳了你的建议,它起到了作用(非常感谢!)

important_names = feature_names[important_features > np.mean(important_features)]
print important_names

它确实返回了变量名。
['x9' 'x10' 'x11' 'x12' 'x13' 'x15' 'x16']

所以你肯定解决了我问题的一部分,这太棒了。但是当我回来打印我的重要特性结果时...
print important_features

它将返回以下输出:
[12, 22, 51, 67, 73, 75, 87, 91, 92, 106, 125, 150, 199, 206, 255, 256, 275, 309, 314, 317]

我理解为它认为第12、22、51等变量是重要的变量。因此,这将是我在代码开始处告诉它索引观察时的第12个变量:
tgmc_x.append(row[3:])

这个解释正确吗?如果正确,当我将原始数据集中的第12个变量移动到第4列(这是我刚刚引用的代码开始读取预测变量值的位置)并再次运行代码时,我会得到以下输出:
[22, 51, 66, 73, 75, 76, 106, 112, 125, 142, 150, 187, 191, 199, 250, 259, 309, 317]

这似乎不再识别该变量。此外,当我将同一变量移至原始数据集中的第5列时,输出如下所示:
[1,22, 51, 66, 73, 75, 76, 106, 112, 125, 142, 150, 187, 191, 199, 250, 259, 309, 317]


看起来它又识别出来了。最后一件事,在我按照你的建议返回变量名之后,它给了我一个包含7个变量的列表。当我只使用我最初的代码返回重要变量时,它给了我一个更长的重要变量列表。为什么会这样呢?再次感谢您的帮助,非常感激!

3个回答

12

要素重要性返回一个数组,其中每个索引对应于该特征在训练集中的估计特征重要性。内部没有进行排序,它与训练时给定的特征一一对应。

如果您将特征名称存储为numpy数组并确保它与传递给模型的特征一致,则可以利用numpy索引来完成此操作。

importances = rf.feature_importances_
important_names = feature_names[importances > np.mean(importances)]
print important_names

谢谢你的快速回复。我已经将feature_names存储在一个numpy数组中,如果方便的话,我会编辑我的评论并包括代码,希望你能帮我看一下。 - Jason Wolosonovich
重要性如何解释?假设您有两个具有重要性[0.8,0.2]的特征,这是否意味着第一个特征占预测的80%(口语上说)或者...? - CutePoison

4

以下是我用来打印和绘制特征重要性的方法,包括名称和值

importances = pd.DataFrame({'feature':X_train.columns,'importance':np.round(clf.feature_importances_,3)})
importances = importances.sort_values('importance',ascending=False).set_index('feature')
print importances
importances.plot.bar()

完整示例

from sklearn.ensemble import RandomForestClassifier
from sklearn.cross_validation import train_test_split
import numpy as np
import pandas as pd

# set vars
predictors = ['x1','x2']
response = 'y'

X = df[predictors]
y = df[response]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)

# run model
clf = RandomForestClassifier(max_features=5)
clf.fit(X_train.values, y_train.values)

#show to plot importances
importances = pd.DataFrame({'feature':X_train.columns,'importance':np.round(clf.feature_importances_,3)})
importances = importances.sort_values('importance',ascending=False).set_index('feature')
print importances
importances.plot.bar()

3

解析变量:

regressor.score(X, y)

获取变量的重要性:

importances = regressor.feature_importances_
print(importances)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接