2014-03-12 917 views
5

我已经在sklearn中使用RandomForestClassifier来确定我的数据集中的重要特征。我如何能够返回实际的功能名称(我的变量被标记为x1,x2,x3等)而不是它们的相对名称(它告诉我重要的功能是'12','22'等)。以下是我目前用来返回重要功能的代码。如何sklearn随机森林指数feature_importances_

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 


然后进行分割数据集和目标类数据集进入测试和t下雨的部分。

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] 


这似乎是其并没有看出任何变化longer.Additionally,当我移动相同的变量到第5列的原始数据集的输出是这样的:

[1,22, 51, 66, 73, 75, 76, 106, 112, 125, 142, 150, 187, 191, 199, 250, 259, 309, 317] 


这看起来像它再次承认它。最后一件事,在我通过你的建议返回变量名后,它给了我一个7个变量的列表。当我使用最初的代码返回重要变量时,它给了我一个更长的重要变量列表。为什么是这样?再次感谢您的帮助。对此,我真的非常感激!

回答

9

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

如果您将要素名称存储为numpy数组并确保其与传递给模型的要素保持一致,则可以利用numpy索引来执行此操作。

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

感谢您的快速响应。我已经将feature_names存储在一个numpy数组中,并且将编辑我的注释以包含代码,如果在方便时可以看一看。 –

2

获取变量解释:

regressor.score(X, y) 

获取变量的重要性:

importances = regressor.feature_importances_ 
print(importances) 
+0

也是一个很好的建议。谢谢! –

2

这是我用来打印和打印功能的重要性,包括姓名,而不仅仅是值

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()