如何利用gcForest为特征打分?

 

楼主前面有一篇博客提到了周志华老师又一力作:gcForest:探索深度神经网络以外的方法,不了解的小伙伴可以翻前面的博客。

这个算法的确比传统的集成树算法:RandomForest,XGBoost,lightGBM都要优秀,而且引入层的概念后很好的解决了集成树算法容易过拟合的问题。

简单讲他就是借鉴了深度学习分层训练的思路,将机器学习中常用的RandomForest,XGBoost,LogisticRegression等算法进行集成,通过模型和样本的多样性让模型更加优秀。

正是因为它这种集成思想,反而抹杀了传统集成树算法的一大优势,gcForest无法给特征打分。原因很简单,它每层用的基学习器像前面提到的RandomForest,XGBoost提取特征的方式是不一样的:

首先RandomForest作为Bagging的代表,它是通过给指定特征X随机加入噪声,通过加入噪声前后袋外数据误差的差值来衡量该特征的重要程度。具体请参考:随机森林之特征选择;而XGBoost作为典型的Boosting算法提取特征的方式和RandomForest有很大的不同,看了下他的打分函数有weight,gain,cover三种方式,其中默认的是weight,这种方式其实就是统计特征X在每棵决策树当中出现的次数,最后特征X出现的次数之和就作为特征X的最后的得分。我们可以看出这两种算法打分方式不同,得到的数值也不是一个量纲的。同样LogisticRegression提取特征的方式也和前两者不一样。

并且gcForst还提供了用户自己添加基学习器的接口(添加方法请了解:gcForest官方代码详解),也就意味着gcForest还可以使用更多的基学习器,如果要封装一个提取重要特征的方法,就要考虑太多太多,每进来一个基学习器都要改变特征打分的方法。

综上所述,我觉得也是gcForest作者没有封装特征打分方法的原因。

基于我的问题,我做了一些思考。我处理的数据用RandomForest,XGBoost都能得到不错的结果,我们知道RandomForest可以很好的减少方差,XGBoost可以很好的减少偏差。为了构建一个低偏差和低方差的模型,我想将这两种算法进行集成。所以在gcForest中我只用了这两个基学习器。

如何利用gcForest为特征打分?_第1张图片

通过对RandomForest,XGBoost打分函数的学习,我和小伙伴shi.chao 对gcForest封装了一个特征打分方法,利用的还是源码里手写数字识别的数据,每层只有RandomForest,XGBoost,为了方便调试,就构建了两层。

大体思想如下:

在源码目录:lib->gcforest->cascade->cascade_classifier.py  fit_transform()方法中进行了一些操作。这个方法就是gcForest进行模型训练的函数。上面也提到了不同的算法特征打分的方法是不一样的,所以在这里需要通过变量est_configs["type"]对基学习器类型进行判断。如果是RandomForest,就直接调用RandomForest的打分函数,得到该基学习器返回的一个map,其中包含特征名称和得分,这里用一个临时变量保存,等到下一层获取RandomFores打分函数得到的另一个map,然后将这个两个map合并,相同key的将value累加,最后得到一个final_feature_rf_importance_list,是整个gcForest所有层中RandomFores得到的特征得分。XGBoost,类似操作。具体见代码注释。

感兴趣的小伙伴可以在这个基础上继续对另外的基学习器特征打分算法进行封装。最后gcForest的特征得分:可以是各个基学习器特征得分的一个融合。

比如我的模型中只用到了RandomForest和XGBoost,最后gcForest的第i个特征的得分可以这样表示:

Zi  = w1 * Xi/sum(X) + w2 * Yi/sum(Y)

其中Xi代表RandomForest中第i个特征的得分,Yi代表XGBoost中第i个特征的得分,这两个值虽然不是一个量纲,但是通过处以它们全部特征之和就可以得到该特征在它的模型中的相对特征,最后通过设置w1,w2的系数,可以调整两种模型在gcForest中的重要程度。

代码已经开源到github:https://github.com/phyllisyuell/gcForest-master-feature

欢迎各位交流学习,批评指正。

有问题请联系,一起讨论:[email protected]

 

 

 

你可能感兴趣的:(大数据,机器学习,决策树,gcForest)