我有一个分类任务,时间序列作为数据输入,其中每个属性(n = 23)代表一个特定的时间点 . 除了绝对分类结果,我想知道,哪些属性/日期对结果的贡献程度如何 . 因此我只使用 feature_importances_ ,这对我很有用 .
feature_importances_
但是,我想知道如何计算它们以及使用哪种度量/算法 . 很遗憾,我找不到有关此主题的任何文档 .
计算单个树的特征重要性值的常用方法如下:
初始化一个大小为 n_features 的所有零的数组 feature_importances .
n_features
feature_importances
遍历树:对于在功能 i 上拆分的每个内部节点,您计算该节点的误差减少乘以路由到节点的样本数并将此数量添加到 feature_importances[i] .
i
feature_importances[i]
误差减少取决于您使用的杂质标准(例如Gini,Entropy,MSE,......) . 它是路由到内部节点的一组示例中的杂质减去由分割产生的两个分区的杂质之和 .
重要的是这些值与特定数据集相关(误差减少和样本数量都是特定于数据集)因此不能在不同数据集之间比较这些值 .
据我所知,还有其他方法可以在决策树中计算特征重要性值 . 上述方法的简要描述可以在Trevor Hastie,Robert Tibshirani和Jerome Friedman的“Elements of Statistical Learning”中找到 .
让我试着回答这个问题 . 码:
iris = datasets.load_iris() X = iris.data y = iris.target clf = DecisionTreeClassifier() clf.fit(X, y)
decision_tree情节:enter image description here我们可以得到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_ 相同 .小心所有课程都应该有一个重量 .
clf.feature_importances_
它是在集合的任何树中路由到涉及该特征的决策节点的样本数量与训练集中的样本总数之间的比率 .
决策树的顶级节点中涉及的特征倾向于看到更多样本,因此可能具有更多重要性 .
Edit :这种描述只是部分正确:吉尔斯和彼得的答案是正确的答案 .
对于那些寻找有关此主题的scikit-learn文档的参考或@GillesLouppe对答案的引用:
在RandomForestClassifier中, estimators_ 属性是DecisionTreeClassifier的列表(如documentation中所述) . 为了计算RandomForestClassifier的 feature_importances_ ,在[scikit-learn's source code](http://(https://github.com/scikit-learn/scikit-learn/blob/f0ab589f/sklearn/ensemble/forest.py#L360)中,它对整体中的所有估计器's (all DecisionTreeClassifer' s) feature_importances_ 属性求平均值 .
estimators_
在DecisionTreeClassifer的documentation中,提到"The importance of a feature is computed as the (normalized) total reduction of the criterion brought by that feature. It is also known as the Gini importance [1]."
Here是有关变量和基尼重要性的更多信息的直接链接,如下面scikit-learn的参考文献所提供的 .
[1] L. Breiman和A. Cutler,“随机森林”,http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm
确实有几种方法可以获得“重要性”功能 . 通常,对于这个词的含义没有严格的共识 .
在scikit-learn中,我们实现了[1]中描述的重要性(经常被引用,但遗憾的是很少阅读......) . 它有时被称为“基尼重要性”或“平均减少杂质”,并被定义为节点杂质的总减少量(通过到达该节点的概率加权(通过到达该节点的样本的比例近似))平均所有合奏的树木 .
在文献或其他一些软件包中,您还可以找到以“平均降低精度”实现的特征重要性 . 基本上,当您随机置换该功能的值时,我们的想法是测量OOB数据的准确性降低 . 如果降低量较低,则该特征不重要,反之亦然 .
(请注意,这两种算法都可以在randomForest R包中找到 . )
[1]:Breiman,Friedman,“分类和回归树”,1984 .
正如@GillesLouppe上面指出的那样,scikit-learn目前实现了特征重要性的“平均减少杂质”度量 . 我个人觉得第二个指标更有趣,你可以逐个随机地对每个功能的值进行置换,看看你的包外性能有多差 .
由于你所追求的特征重要性是每个特征对整体模型预测性能的贡献程度,第二个指标实际上可以直接衡量这一点,而“平均减少杂质”只是一个很好的代理 .
如果你有兴趣,我写了一个实现Permutation Importance指标的小包,可以用于计算scikit-learn随机森林类的实例中的值:
https://github.com/pjh2011/rf_perm_feat_import
Edit: This works for Python 2.7, not 3
6 回答
计算单个树的特征重要性值的常用方法如下:
初始化一个大小为
n_features
的所有零的数组feature_importances
.遍历树:对于在功能
i
上拆分的每个内部节点,您计算该节点的误差减少乘以路由到节点的样本数并将此数量添加到feature_importances[i]
.误差减少取决于您使用的杂质标准(例如Gini,Entropy,MSE,......) . 它是路由到内部节点的一组示例中的杂质减去由分割产生的两个分区的杂质之和 .
重要的是这些值与特定数据集相关(误差减少和样本数量都是特定于数据集)因此不能在不同数据集之间比较这些值 .
据我所知,还有其他方法可以在决策树中计算特征重要性值 . 上述方法的简要描述可以在Trevor Hastie,Robert Tibshirani和Jerome Friedman的“Elements of Statistical Learning”中找到 .
让我试着回答这个问题 . 码:
decision_tree情节:
enter image description here
我们可以得到compute_feature_importance:[0 . ,0.01333333,0.06405596,0.92261071]
检查源代码:
尝试计算要素重要性:
我们得到feature_importance:np.array([0,1.332,6.418,92.30]) .
归一化后,我们可以得到数组([0,0.01331334,0.06414793,0.92253873]),这与
clf.feature_importances_
相同 .小心所有课程都应该有一个重量 .
它是在集合的任何树中路由到涉及该特征的决策节点的样本数量与训练集中的样本总数之间的比率 .
决策树的顶级节点中涉及的特征倾向于看到更多样本,因此可能具有更多重要性 .
Edit :这种描述只是部分正确:吉尔斯和彼得的答案是正确的答案 .
对于那些寻找有关此主题的scikit-learn文档的参考或@GillesLouppe对答案的引用:
在RandomForestClassifier中,
estimators_
属性是DecisionTreeClassifier的列表(如documentation中所述) . 为了计算RandomForestClassifier的feature_importances_
,在[scikit-learn's source code](http://(https://github.com/scikit-learn/scikit-learn/blob/f0ab589f/sklearn/ensemble/forest.py#L360)中,它对整体中的所有估计器's (all DecisionTreeClassifer' s)feature_importances_
属性求平均值 .在DecisionTreeClassifer的documentation中,提到"The importance of a feature is computed as the (normalized) total reduction of the criterion brought by that feature. It is also known as the Gini importance [1]."
Here是有关变量和基尼重要性的更多信息的直接链接,如下面scikit-learn的参考文献所提供的 .
[1] L. Breiman和A. Cutler,“随机森林”,http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm
确实有几种方法可以获得“重要性”功能 . 通常,对于这个词的含义没有严格的共识 .
在scikit-learn中,我们实现了[1]中描述的重要性(经常被引用,但遗憾的是很少阅读......) . 它有时被称为“基尼重要性”或“平均减少杂质”,并被定义为节点杂质的总减少量(通过到达该节点的概率加权(通过到达该节点的样本的比例近似))平均所有合奏的树木 .
在文献或其他一些软件包中,您还可以找到以“平均降低精度”实现的特征重要性 . 基本上,当您随机置换该功能的值时,我们的想法是测量OOB数据的准确性降低 . 如果降低量较低,则该特征不重要,反之亦然 .
(请注意,这两种算法都可以在randomForest R包中找到 . )
[1]:Breiman,Friedman,“分类和回归树”,1984 .
正如@GillesLouppe上面指出的那样,scikit-learn目前实现了特征重要性的“平均减少杂质”度量 . 我个人觉得第二个指标更有趣,你可以逐个随机地对每个功能的值进行置换,看看你的包外性能有多差 .
由于你所追求的特征重要性是每个特征对整体模型预测性能的贡献程度,第二个指标实际上可以直接衡量这一点,而“平均减少杂质”只是一个很好的代理 .
如果你有兴趣,我写了一个实现Permutation Importance指标的小包,可以用于计算scikit-learn随机森林类的实例中的值:
https://github.com/pjh2011/rf_perm_feat_import
Edit: This works for Python 2.7, not 3