Answers:
实际上,有几种获取功能“重要性”的方法。通常,对该词的含义没有严格的共识。
在scikit-learn中,我们实现了[1]中描述的重要性(经常被引用,但不幸的是很少阅读...)。有时称为“基尼重要性”或“平均减少杂质”,定义为所有节点平均的节点杂质的总减少量(由到达该节点的概率加权(由到达该节点的样本比例近似)合奏的树木。
在文献或其他软件包中,您还可以找到实现为“平均降低精度”的功能重要性。基本上,该想法是测量当您随机排列该功能的值时,OOB数据的准确性下降的情况。如果降低幅度很小,则该功能并不重要,反之亦然。
(请注意,randomForest R软件包中都提供了这两种算法。)
[1]:Breiman,Friedman,“分类和回归树”,1984年。
tree_.compute_feature_importances(normalize=False)
。
计算单个树的特征重要性值的常用方法如下:
您可以feature_importances
使用size 初始化一个全零的数组n_features
。
您遍历了该树:对于每个在要素上进行了拆分的内部节点,i
您需要计算该节点的错误减少率乘以路由到该节点的样本数量,然后将此数量加到feature_importances[i]
。
减少误差取决于您使用的杂质标准(例如,Gini,熵,MSE等)。它被路由到内部节点的示例集中的杂质减去拆分产生的两个分区的杂质之和。
重要的是这些值是相对于特定数据集的(减少误差和样本数量都是特定于数据集的),因此不能在不同数据集之间比较这些值。
据我所知,还有其他方法可以计算决策树中的特征重要性值。可以在Trevor Hastie,Robert Tibshirani和Jerome Friedman的“统计学习要素”中找到上述方法的简要说明。
它是路由到集合中任何树中涉及该功能的决策节点的样本数与训练集中样本总数之间的比率。
决策树的顶级节点中涉及的功能往往会看到更多的样本,因此可能具有更大的重要性。
编辑:此描述仅部分正确:Gilles和Peter的答案是正确的答案。
正如@GillesLouppe上文指出的那样,scikit-learn当前为实现功能重要性而实施了“平均减少杂质”度量。我个人觉得第二个指标更有趣,您可以将每个功能的值随机地一次一个地排列,并查看您的袋装性能有多糟糕。
由于您所追求的功能重要性是每个功能对整体模型的预测性能有多大的贡献,因此第二个指标实际上可以直接衡量您这一点,而“平均减少杂质”只是一个很好的替代。
如果您有兴趣,我写了一个小包来实现置换重要性指标,该包可用于从scikit-learn随机森林类的实例计算值:
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)
Decision_tree 图:
在此处输入图像描述
我们可以获得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)))
我们得到feature_importance:np.array([0,1.332,6.418,92.30])。
归一化后,我们可以得到数组([0.,0.01331334,0.06414793,0.92253873]),这与相同clf.feature_importances_
。
请注意,所有班级都应具有一等分量。
对于那些希望参考此主题的scikit-learn文档或@GillesLouppe的答案的参考文献:
在RandomForestClassifier中,estimators_
attribute是DecisionTreeClassifier的列表(如文档中所述)。为了计算feature_importances_
RandomForestClassifier的,在scikit-learn的源代码中,它对feature_importances_
集合中所有估算器(所有DecisionTreeClassifer)属性进行平均。
在DecisionTreeClassifer的文档中,提到“要素的重要性是作为该要素带来的条件的(归一化)总缩减而计算的。这也被称为基尼重要性[1]”。
这是直接链接,以获取有关变量和基尼重要性的更多信息,如下面scikit-learn的参考所提供。
[1] L. Breiman和A. Cutler,“随机森林”,http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm