树模型特征重要性计算方法总结

最近在复习特征重要性时候,考虑到我们在使用GBDT、RF、Xgboost等树类模型建模时,往往可以通过feature_importance 来返回特征重要性,下面收集整理了一下各模型输出特征重要性的原理与方法;

1. 计算特征重要性方法

首先,目前计算特征重要性计算方法主要有两个方面:

1.1 训练过程中计算


训练过程中通过记录特征的分裂总次数、总/平均信息增益来对特征重要性进行量化。例如实际工程中我们会用特征在整个GBDT、XgBoost里面被使用的次数或者带来的总/平均信息增益来给特征重要度打分,最后进行排序。由于本身Ensemble模型在选择特征分裂时带有一定随机性,一般会跑多个模型然后把特征重要性求平均后排序。


1.2 训练后使用OOB(Out of Bag)数据计算


第二种方式是训练好模型之后,用Out of Bag(或称Test)数据进行特征重要性的量化计算。具体来说,先用训练好的模型对OOB数据进行打分,计算出AUC或其他业务定义的评估指标;接着对OOB数据中的每个特征:
(1)随机shuffle当前特征的取值;
(2)重新对当前数据进行打分,计算评估指标;
(3)计算指标变化率
按照上面方式,对每个特征都会得到一个变化率,最后按照变化率排序来量化特征重要性。


延伸到 DNN 对特征重要性判定:
DNN不像Boosting这类模型那样存在所谓的分裂次数与信息增益,就需要使用第二种方式,对每个特征进行随机shuffle,观察模型指标的变化,最后按照变化率进行排序。比如AUC下滑率,下滑的越多说明当前这个指标越重要。当然,实际操作中需要结合业务经验先指定一个候选变量池,对这部分变量计算重要度,不然计算开销太大。
2. 树模型特征重要性判定

2.1 Random Foreast

  • 袋外数据错误率(可参考上一问的OOB特征选择方法)
  • 基尼指数

随机森林特征重要性评定可参考:https://blog.csdn.net/zjuPeco/article/details/77371645?locationNum=7&fps=1

2.2 GBDT

基尼指数

2.3 Xgboost

get_score(fmap=’’, importance_type=‘weight’)
Get feature importance of each feature. Importance type can be defined as:

‘weight’: the number of times a feature is used to split the data across all trees.
‘gain’: the average gain across all splits the feature is used in.
‘cover’: the average coverage across all splits the feature is used in.
‘total_gain’: the total gain across all splits the feature is used in.
‘total_cover’: the total coverage across all splits the feature is used in.

树模型特征重要性计算方法总结_第1张图片

下面就结合这张图,解释下各指标含义:

weight:  {‘f0’: 1, ‘f1’: 2}
在所有树中,某特征被用来分裂节点的次数,在本例中,可见分裂第1个节点时用到f0,分裂第2,3个节点时用到f1,所以weight_f0 = 1, weight_f1 = 2。


total_cover:  {‘f0’: 10.0, ‘f1’: 8.0}
第1个节点,f0被用来对所有10个样例进行分裂,之后的节点中f0没再被用到,所以f0的total_cover为10.0,此时f0 >= 0.855563045的样例有5个,落入右子树;
第2个节点,f1被用来对上面落入右子树的5个样例进行分裂,其中f1 >= -0.178257734的样例有3个,落入右子树;
第3个节点,f1被用来对上面落入右子树的3个样例进行分裂。
总结起来,f0在第1个节点分裂了10个样例,所以total_cover_f0 = 10,f1在第2、3个节点分别用于分裂5、3个样例,所以total_cover_f1 = 5 + 3 = 8。total_cover表示在所有树中,某特征在每次分裂节点时处理(覆盖)的所有样例的数量。


cover:  {‘f0’: 10.0, ‘f1’: 4.0}
cover = total_cover / weight,在本例中,cover_f0 = 10 / 1,cover_f1 = 8 / 2 = 4.


total_gain:  {‘f0’: 0.265151441, ‘f1’: 0.75000003}
在所有树中,某特征在每次分裂节点时带来的总增益,如果用熵或基尼不纯衡量分裂前后的信息量分别为i0和i1,则增益为(i0 - i1)。


gain:  {‘f0’: 0.265151441, ‘f1’: 0.375000015}
gain = total_gain / weight,在本例中,gain_f0 = 0.265151441 / 1,gain_f1 = 75000003 / 2 = 375000015.

在平时的使用中,多用total_gain来对特征重要性进行排序。

 

 

参考文献


[1] https://blog.csdn.net/tinkle181129/article/details/80231871
[2] https://blog.csdn.net/lz_peter/article/details/85010931
[3] https://blog.csdn.net/zjuPeco/article/details/77371645?locationNum=7&fps=1
 


 

你可能感兴趣的:(机器学习)