我在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个变量的列表。当我使用最初的代码返回重要变量时,它会给我一个更长的重要变量列表。为什么会这样?再次感谢你的帮助。我真的很感激!
Feature Importances返回一个数组,其中每个索引对应于训练集中该特征的估计特征重要性。内部没有排序,它与训练时给出的特征是一对一的对应关系。
如果您将特征名称存储为numpy数组,并确保它与传递给模型的特征一致,则可以利用numpy索引来实现。
importances = rf.feature_importances_
important_names = feature_names[importances > np.mean(importances)]
print important_names
这是我用来打印和绘制重要特征的方法,包括名称,而不仅仅是值
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()
获取变量解释:
regressor.score(X, y)
获取变量的重要性:
importances = regressor.feature_importances_
print(importances)