我有一个分类任务,其数据输入为时间序列,其中每个属性(n = 23)表示特定的时间点。除了绝对的分类结果外,我想要找出哪些属性/日期对结果产生了何种程度的贡献。因此,我只是使用了feature_importances_
,这对我来说效果不错。
然而,我想知道它们是如何计算的,以及使用了哪种度量/算法。不幸的是,我没有找到任何关于这个主题的文档。
我有一个分类任务,其数据输入为时间序列,其中每个属性(n = 23)表示特定的时间点。除了绝对的分类结果外,我想要找出哪些属性/日期对结果产生了何种程度的贡献。因此,我只是使用了feature_importances_
,这对我来说效果不错。
然而,我想知道它们是如何计算的,以及使用了哪种度量/算法。不幸的是,我没有找到任何关于这个主题的文档。
确实有几种方法可以获得特征的“重要性”。通常情况下,对于这个词的含义并没有严格一致的共识。
在scikit-learn中,我们实现了在[1]中描述的重要性(经常被引用,但不幸的是很少被阅读...)。它有时被称为“基尼重要性”或“平均减少不纯度”,定义为整个集成树的节点不纯度减少总量(加权节点到达的概率(由到达该节点的样本比例近似))的平均值。
在文献或其他软件包中,您还可以找到将特征重要性实现为“平均减少准确性”的方法。基本上,这个想法是当您随机置换该特征的值时,在OOB数据上测量准确性降低的程度。如果减少程度较低,则该特征不重要,反之亦然。
(注意,这两个算法都在randomForest R软件包中可用。)
[1]: Breiman, Friedman,“分类和回归树”,1984年。
tree_.compute_feature_importances(normalize=False)
来避免这种情况。 - Gilles Louppe初始化一个大小为n_features
的全零数组feature_importances
。
遍历树:对于每个在特征i
上分裂的内部节点,计算该节点的错误减少量乘以被路由到该节点的样本数,并将此数量添加到feature_importances[i]
中。
错误减少量取决于使用的不纯度标准(例如Gini、熵、MSE等)。它是被路由到内部节点的示例集合的不纯度减去拆分创建的两个分区的不纯度之和。
这些值与特定数据集相关(错误减少量和样本数都是数据集特定的),因此这些值不能在不同数据集之间进行比较。
据我所知,有其他方法可以计算决策树中的特征重要性值。以上方法的简要说明可在Trevor Hastie、Robert Tibshirani和Jerome Friedman的《统计学习基础》一书中找到。
这是集成树中涉及该特征的决策节点样本数与训练集中总样本数之比。
出现在决策树顶层节点的特征通常会看到更多样本,因此可能具有更重要的作用。
编辑: 这个描述只有部分正确:Gilles和Peter的答案才是正确的。
https://github.com/pjh2011/rf_perm_feat_import
编辑:这适用于Python 2.7,不适用于3
代码:
iris = datasets.load_iris()
X = iris.data
y = iris.target
clf = DecisionTreeClassifier()
clf.fit(X, y)
决策树图:
在此输入图片描述
我们得到:
compute_feature_importance:[0. ,0.01333333,0.06405596,0.92261071]
检查源代码:
cpdef compute_feature_importances(self, normalize=True):
"""Computes the importance of each feature (aka variable)."""
cdef Node* left
cdef Node* right
cdef Node* nodes = self.nodes
cdef Node* node = nodes
cdef Node* end_node = node + self.node_count
cdef double normalizer = 0.
cdef np.ndarray[np.float64_t, ndim=1] importances
importances = np.zeros((self.n_features,))
cdef DOUBLE_t* importance_data = <DOUBLE_t*>importances.data
with nogil:
while node != end_node:
if node.left_child != _TREE_LEAF:
# ... and node.right_child != _TREE_LEAF:
left = &nodes[node.left_child]
right = &nodes[node.right_child]
importance_data[node.feature] += (
node.weighted_n_node_samples * node.impurity -
left.weighted_n_node_samples * left.impurity -
right.weighted_n_node_samples * right.impurity)
node += 1
importances /= nodes[0].weighted_n_node_samples
if normalize:
normalizer = np.sum(importances)
if normalizer > 0.0:
# Avoid dividing by zero (e.g., when root is pure)
importances /= normalizer
return importances
尝试计算特征重要性:
print("sepal length (cm)",0)
print("sepal width (cm)",(3*0.444-(0+0)))
print("petal length (cm)",(54* 0.168 - (48*0.041+6*0.444)) +(46*0.043 -(0+3*0.444)) + (3*0.444-(0+0)))
print("petal width (cm)",(150* 0.667 - (0+100*0.5)) +(100*0.5-(54*0.168+46*0.043))+(6*0.444 -(0+3*0.444)) + (48*0.041-(0+0)))
np.array([0,1.332,6.418,92.30])
。array ([0., 0.01331334, 0.06414793, 0.92253873])
,这与clf.feature_importances_
相同。对于那些寻找关于此主题的scikit-learn文档或@GillesLouppe答案的参考资料:
在RandomForestClassifier中,estimators_
属性是DecisionTreeClassifier的列表(如文档中所述)。为了计算RandomForestClassifier的feature_importances_
,在scikit-learn源代码中,它对集成中所有估计器(所有DecisionTreeClassifer)的feature_importances_
属性进行平均。
在DecisionTreeClassifer的文档中,提到:“特征的重要性被计算为该特征带来的标准总减少量的(归一化)值。它也被称为基尼重要性[1]。”
这里提供了关于变量和Gini重要性的更多信息的直接链接,该链接由下面scikit-learn的参考提供。
[1] L. Breiman和A. Cutler,“随机森林”,http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm