如何将随机森林中的选定特征转换为新列表

Posted

技术标签:

【中文标题】如何将随机森林中的选定特征转换为新列表【英文标题】:How to turn selected features from Random Forest into a new list 【发布时间】:2020-01-15 19:00:23 【问题描述】:

我正在研究一个回归问题。对于我的模型,我使用随机森林分类器进行降维。输出是一个以空格分隔的布尔值字符串,将好的特征突出显示为“真”。这是它的样子:

[ True  True  True  True  True  True  True  True  True  True  True  True
  True  True  True False  True  True False  True  True  True False  True
  True  True  True  True  True  True  True False  True False False  True
  True False False False False False False False False False False  True
 False False  True False False False False False False  True False False
 False  True False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False  True False False  True False False
 False  True False  True False False False False False False False False
 False False False False False False False False False False False False
 False  True False False False False False False False False  True False
 False False False False False  True False False False  True  True False
 False False False False False False False False False False False False
 False False False False False False  True False False False False False
 False False  True False False  True False  True False  True False False
  True False False False False False False False False False False False
 False False False  True False  True False  True False False False False
 False False False False False  True  True False False False False False
 False False False False  True False  True  True False  True False False
 False False False  True  True  True False False False False False False
 False False False False False False False False False False False False
 False False False False False False  True False False False False False
 False False False False False False False False  True False False False
 False  True False]

所以我所做的就是把它变成一个逗号分隔的列表,如下所示:

[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, False, True, True, False, True, True, True, False, True, True, True, True, True, True, True, True, False, True, False, False, True, True, False, False, False, False, False, False, False, False, False, False, True, False, False, True, False, False, False, False, False, False, True, False, False, False, True, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, True, False, False, False, True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, True, False, False, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, True, False, False, True, False, True, False, True, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, True, False, True, False, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False, False, True, False, True, True, False, True, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False]

然后循环遍历每个元素并检索相应的测试列。这是这个过程的全部代码:

sel = SelectFromModel(RandomForestClassifier(n_estimators = 100), threshold = '1.25*mean')
sel.fit(x_train, y_train)

selected = sel.get_support()
selected_list = list(selected)
columns_list = []

for i in range(len(selected_list)):
    if(selected_list[i] == 'True'):
        columns_list.append(test[i])

print(columns_list)

但现在我得到了一个空列表,尽管我试图将它附加到我的columns_list。基本上,我的目标是在我的预测中使用降维的列。我正在使用线性回归来解决这个问题。

更新

当我将代码更改为以下建议时,我收到以下错误:

Traceback (most recent call last):
  File "/opt/anaconda/envs/lib/python3.7/site-packages/pandas/core/indexes/base.py", line 2890, in get_loc
    return self._engine.get_loc(key)
  File "pandas/_libs/index.pyx", line 107, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 131, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 1607, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 1614, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/onur/Documents/Boston-Kaggle/Model.py", line 100, in <module>
    columns_list.append(test[i])
  File "/opt/anaconda/envs/lib/python3.7/site-packages/pandas/core/frame.py", line 2975, in __getitem__
    indexer = self.columns.get_loc(key)
  File "/opt/anaconda/envs/lib/python3.7/site-packages/pandas/core/indexes/base.py", line 2892, in get_loc
    return self._engine.get_loc(self._maybe_cast_indexer(key))
  File "pandas/_libs/index.pyx", line 107, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 131, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 1607, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 1614, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 0

【问题讨论】:

【参考方案1】:

你的问题在这里:

if(selected_list[i] == 'True'):
    columns_list.append(test[i])

您将布尔值与字符串值 'True' 进行比较,而不是 True

一个紧凑且 Pythonic 的解决方案是:

 if selected_list[i]:
    columns_list.append(test[i])

对于您的第二个错误,这是因为您正在使用 [] 访问数据帧 test。你需要使用.iloc的方法

对于用法,这取决于测试包含什么:

test.iloc[0] # first row of data frame- Note a Series data type output.
test.iloc[1] # second row of data frame 
test.iloc[-1] # last row of data frame 
# Columns:
test.iloc[:,0] # first column of data frame 
test.iloc[:,1] # second column of data frame 
test.iloc[:,-1] # last column of data frame

编辑,更明确的解决方案:

columns_selected = test.iloc[:, [i for i in range(len(selected_list)) if selected_list[i]]]

【讨论】:

如果你不介意,你能演示一下.iloc吗?我应该如何修改代码? @OnurOzbek 这取决于您想从测试中选择什么。检查我的更新 我想选择每个为真的索引。 @OnurOzbek 是的,但列或行?我想是行,因为测试可能是一个矩阵,并且特征在列上 让我澄清一下:从测试数据集中,我想选择selected_list 为真的每一列。【参考方案2】:

我会这样做:

columns_list = list(x_train.columns[selected_list])
selected_test = test[columns_list]

这样,您从x_train 中检索选定列的名称,将它们放入column_list,然后在test 中搜索它们。即使训练和测试数据没有相同数量的列,这也应该有效;显然,如果测试数据没有选定的特征之一,它将无法工作。

【讨论】:

谢谢人。我刚刚赞成你的回答。如果您认为这是一个很好的问题,您能否也给我一个赞成票?

以上是关于如何将随机森林中的选定特征转换为新列表的主要内容,如果未能解决你的问题,请参考以下文章

随机森林如何评估特征重要性

如何调整随机森林模型中的特征权重?

字符串作为决策树/随机森林中的特征

特征筛选(随机森林)

获取随机森林回归器训练期间使用的特征列表

如何在 scikit-learn 中控制随机森林中的特征子集?