之前一直使用的集成回归树模型都是RF,Xgboost,GBDT这三个,其中RF是bagging思想,Xgboost和GBDT是boosting思想。但是在尝试了微软开源的Lightgbm之后,感觉再也回不去了。这款横空出世的轻量级tree boost模型,在不损失精度的情况下,大大提升了计算效率。同时也做出了一些改进。在这里先聊一聊它对‘category’’这种类别型数据的处理的支持。
如果你对算法有一定的了解,你会知道是无法直接处理类别型数据的,即离散特征。我们需要对类别型数据做一个one-hot,将类别型数据稀疏化。例如用鞋子品牌这一特征维度对鞋子进行分类:耐克鞋,阿迪鞋,李宁鞋。你不能将他们编码成(0,1,2),因为这样你就已经不公平的定义了三者之间的距离,阿迪和耐克的距离是1,而李宁和耐克的距离是2,我们不能这样贸然定义,不能做一个莽夫。众生平等,所以我们要一视同仁,采取one-encode编码将三者转换为(1,0,0),(0,1,0),(0,0,1)。让距离的计算变得更加合理。
而Lightgbm可以直接支持category特征的处理,在用pandas结构使用LGB时可以指定哪一列是类别型数据,省去one-hot的步骤。如果类别过多,如商品ID,在one-hot处理后数据会变得过于稀疏,大大增加了训练集的大小,浪费计算资源。而LGB则会采用一种直方图式的方法去处理,max bin的默认值是256,对于category类型的feature,则是每一种取值放入一个bin,且当取值的个数大于max bin数时,会忽略那些很少出现的category值。在求split时,对于category类型的feature,算的是"按是否属于某个category值划分"的gain,它的实际效果就是类似one-hot的编码方法。
在最近的一个项目中,我第一直觉认为商品ID应该是和商品销量高度相关的特征,对商品ID进行one-hot后,在输出的feature importance中该特征得分非常高,也符合我的直觉。但是最终结果却变差了。针对这一问题,我个人的理解是,在过于稀疏化后,相当于变相减少了数据量,在学习能力很强的模型下,很容易导致过拟合的现象,若不能获取更多的数据,可以考虑放弃该列特征或者将商品ID按照其他的方法进行重新分成各大类,降低稀疏化程度,也可以获得不错的效果。