在RandomForestClassifier feature_importances是如何确定的?

2019-08-19 11:56发布

我有一个时间序列作为数据输入,其中,每个属性(N = 23)表示在特定时间点进行分类的任务。 除了绝对的分类结果,我想搞清楚,哪些属性/日期有助于结果到什么程度。 所以我只是用feature_importances_ ,这对我来说效果很好。

不过,我想知道他们是如何得到计算和测量/算法。 不幸的是我无法找到关于这个主题的文档。

Answer 1:

确实有几种方式来获得功能“重要度”。 由于经常,有什么这个词意味着没有严格一致。

在scikit学习,我们实施的重要性,在[1]中描述的(经常被引用,但遗憾的是很少看...)。 它有时被称为“基尼重要性”或“的意思是减小杂质”,且定义为在节点杂质总数减少(由到达该节点(由到达该节点)的样品的比例近似的概率加权)平均超过所有乐团的树木。

在文献中,或在一些其他的包,你还可以找到如“平均降低精确度”已实现的功能重要性有关。 基本上,这个想法是测量在OOB数据精度的降低,当你随意置换的值该功能。 如果下降的幅度低,那么该功能并不重要,反之亦然。

(注意,这两个算法在随机森林ř封装。)

[1]:Breiman,弗里德曼, “分类与回归树”,1984年。



Answer 2:

计算一棵树的特征重要性值的常用方法如下:

  1. 你初始化数组feature_importances大小为全零的n_features

  2. 你遍历树:对于上的功能将每个内部节点i你计算该节点乘以该被路由到节点并添加此数量的样本的数目的误差减少feature_importances[i]

误差减少取决于您使用(如基尼系数,熵,MSE,...)杂质标准。 其设定的例子是被路由到内部节点减去由拆分创建的两个分区的杂质总和的杂质。

其重要的是,这些值是相对于一个特定的数据集(包括错误减少以及样品的数量是特定的数据集),因此这些值不能在不同的数据集之间进行比较。

据我所知,还有其他方法来计算决策树功能重要性值。 上述方法的简要描述可以在“统计学习的元素”由Trevor Hastie的,罗伯特·蒂希雷尼,和Jerome弗里德曼找到。



Answer 3:

这是路由到涉及任何合奏过样品的训练集中总数的树木该功能决策节点的样本数量之间的比例。

所涉及的决策树的顶级节点的功能往往会看到更多的样本,因此可能有更多的重视。

编辑 :这说明只是部分正确:吉尔斯和彼得的答案是正确的答案。



Answer 4:

正如@GillesLouppe上文指出,scikit学习目前实现了功能重要性有关“平均减少杂质”度量。 我个人觉得第二度量的更有趣,在这里你随机置换价值为您的每一个功能一个接一个,看你的了球袋性能差多少的。

既然你以后与功能的重要性是每个功能有多大贡献您的整体模型的预测效果,第二个指标,其实是给予你的这个直接测量,而“平均降低杂质”仅仅是一个很好的代表。

如果你有兴趣,我写了一个小封装,实现了置换重要性度量,可用于从scikit学习随机森林类的实例计算值:

https://github.com/pjh2011/rf_perm_feat_import

编辑:这适用于Python 2.7版,而不是3



Answer 5:

让我试着回答这个问题。 码:

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)))

我们得到feature_importance:np.array([0,1.332,6.418,92.30])。
归一化后,我们可以得到阵列([0,0.01331334,0.06414793,0.92253873]),这是相同clf.feature_importances_
要小心,所有的类都应该有一个重量。



Answer 6:

对于那些寻找关于这一主题或由@GillesLouppe参考答案的scikit学习的文档的参考:

在RandomForestClassifier, estimators_属性是DecisionTreeClassifier的列表(如在所提到的文档 )。 为了计算feature_importances_为RandomForestClassifier,在scikit学习的源代码 ,它的平均值在所有估计的(所有DecisionTreeClassifer的) feature_importances_在合奏属性。

在DecisionTreeClassifer的文档 ,应提到的是“一个特征的重要性被计算为通过该特征所带来的判据的(归一化)的总的减少。这也被称为基尼重要性[1]”。

这里是直接链接,可变和基尼重要性的详细信息,如通过提供scikit学习的参考下文。

[1] L. Breiman,和A.卡特勒,“随机森林”, http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm



文章来源: How are feature_importances in RandomForestClassifier determined?