scikit-learn随机森林的功能重要性显示出很高的标准偏差


13

我正在使用scikit-learn随机森林分类器,并且想要绘制功能重要性,例如在本示例中

但是,从某种意义上说,我的结果是完全不同的,在某种意义上,特征重要性标准差几乎总是大于特征重要性本身的(见附图)。

功能重要性

可能会有这种行为,或者我在绘制图形时犯了一些错误?

我的代码如下:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier()
clf.fit(predictors.values, outcome.values.ravel())

importance = clf.feature_importances_
importance = pd.DataFrame(importance, index=predictors.columns, 
                          columns=["Importance"])

importance["Std"] = np.std([tree.feature_importances_
                            for tree in clf.estimators_], axis=0)

x = range(importance.shape[0])
y = importance.ix[:, 0]
yerr = importance.ix[:, 1]

plt.bar(x, y, yerr=yerr, align="center")

plt.show()

IIUC,predictors返回一个numpy array您正在通过pandas Dataframe对象的列引用该对象的对象,该对象不正确,因为numpy arrays没有属性columns
Nickil Maveli '16

抱歉,这是代码上的错字。预测器和结果是pandas DataFrame形状m x n和两种m x 1。现在应该清楚了。
gc5

2
我前段时间也遇到过同样的发现。可能是由于许多特征很重要,但是由于决策树中的特征可能很高或很低(由于在进行拆分时仅提供随机子集),其重要性随树的高低而变化。树,导致较高的标准偏差。
Archie

很棒的帖子,正如您在图片中看到的,我遇到了相同的问题。有一个软件包tsfresh可以帮助我识别相关特征并将特征从600+减少到400左右。![我的前35个特征 ](i.stack.imgur.com/0MROZ.png)即使如此,该算法仍能很好地执行为了我。我有一个二进制分类,成功/失败。我几乎没有虚假的成功,但我确实错过了相当大的成功百分比。以上所有猜测似乎都是合理的。有可能需要更大的培训和测试集。我人数更少
超级英雄

Answers:


3

您在使用RandomForest时使用的默认树数为10。对于大约30个要素,这太少了。因此,标准偏差大。尝试至少100甚至1000棵树,例如

clf = RandomForestClassifier(n_estimators=1000)

为了进行更精细的分析,您还可以检查功能之间的相关程度。


抱歉,Lanenok的树数不是默认的树数。我放置了一个示例代码(对于所有参数都是如此,例如min_samples_split),因为我无法透露正在处理的数据。但是,是由于树的数量加上其他参数引起的,还是我在这里犯了一些错误?
gc5

2

您的结果不是那么奇怪。正如Lanenok所言,您应该首先增加树的数量,以确保获得有关功能重要性的“统计”结果。

然而,由于该由Genuer等。(2010)显示,实际上可以使用标准偏差来消除特征。引用:“ 我们可以看到,真正的变量的标准偏差比嘈杂的变量1(接近于零)大。


在此示例中使用标准偏差消除特征将消除所有特征。xD
豪尔赫·雷涛

哈哈,我不太确定,我认为您可以安全地放弃最右边的功能吗?无论如何,我要说明的要点是,高标准偏差并不是那么奇怪,您可以在策略中实际使用它们来消除特征。
阿奇

1

尝试clf = RandomForestClassifier(max_features=None)。的max_featuresPARAM默认为'auto'这相当于sqrt(n_features)max_features被描述为“寻找最佳分割时要考虑的功能数量”。仅在决策树的任何位置查看少量要素,就意味着单个要素的重要性可能会在许多树中变化很大。因此,不要看随机子集,而要看树的每个级别的所有特征。


1
请注意,这等效于普通袋装树。随机森林中的“随机”是指在每个分割处(通常是sqrt(n_features)或)考虑特征的随机子集log2(n_features)max_features=None不再考虑要素的随机子集。我不确定这是否会影响上述解决方案。一种可能性是,许多特征仅具有大量重要性,因此在整个树丛中变化很大。也许样本不足,因此在您打到一片叶子时,并不是每个功能都被考虑在内。
jamis

1

常见的原因是您提供(或默认设置)的参数RandomForestClassifier不适合您的数据集。

解决此问题的常用方法是使用以下命令搜索超参数空间GridSearchCV

from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score, make_scorer

param_grid = {'n_estimators': [10, 100, 1000], 'max_features': [5, 10, 20, 30]}
clf = GridSearchCV(RandomForestClassifier(), param_grid, cv=5, scoring=make_scorer(accuracy_score))

param_grid这是您要搜索的参数的排列,这make_scorer(accuracy_score)是您要优化的度量。

请注意,此选项accuracy_score适用于平衡集,但不适用于不平衡集。选择一个适合您特定目标的指标。


0

可能有多种原因。树的数量和深度可以改变结果。如果在选择参数后模型(交叉验证等)表现不佳,则可能是因为您的特征不是非常可预测的,因此几乎“随机地”选择了它们,从而导致树与树之间的标准差较高。但是还有其他可能性,例如也可能是您的功能高度相关。多一点信息会有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.