用GBDT构建组合特征

一、理论

Facebook在2014年发表“Practical Lessons from Predicting Clicks on Ads at Facebook”,论文中提出经典的GBDT+LR的模型结构,开启特征工程模型化、自动化的新阶段。文章提出采用GBDT自动进行特征筛选和组合,进而生成新的特征向量,再把该特征向量作为LR模型的输入,预测CTR,模型结构如下图所示。其中采用GBDT构造新特征的方法可以使特征工程自动化,十分方便,这里介绍如何使用GBDT构建新的组合特征。

1.1 GBDT为何可以做特征组合

首先,我们知道GBDT是由许多回归树组成的森林,后一棵树采用前一颗树的预测结果与真实结果的残差来作为拟合目标,每棵树的生成过程都是一颗标准的回归树的生成过程;

因此每个节点的分裂都是在做特征选择,多层节点的结构自然构成有效的特征组合;

而且做特征选择的过程,是利用信息熵对样本作划分,选择最优特征和最优划分的过程,这样组合起来的特征可以有效划分样本,得到很好的特征组合,组合特征也具有一定的解释性。

1.2 如何构造组合特征

首先,我们先训练好的GBDT模型,然后用训练好的模型对数据做预测,便可得到组合特征。具体来说,一个样本在输入GBDT的一颗子树后,会根据每个节点的划分规则最终落入某一叶子节点,那么这个叶子节点置为1,其他节点置为0,所有叶子节点组成的向量形成了该棵树的特征向量,把GBDT所有子树的特征向量连接起来,即形成了后续LR模型输入的特征向量。

举例来说,比如GBDT由三颗子树构成,每个子树有4个叶子节点,一个训练样本进来后,先后落到了“子树1”的第3个叶节点中,那么特征向量就是[0,0,1,0],“子树2”的第1个叶节点,特征向量为[1,0,0,0],“子树3”的第4个叶节点,特征向量为[0,0,0,1],最后concatenate所有特征向量,形成的最终的特征向量为[0,0,1,0,1,0,0,0,0,0,0,1],我们再把该向量作为LR的输入,预测CTR。

在实际采用GBDT构造组合特征时,我们可以选择sklearn或者lightGBM中的GBDT模型来实现,由于GBDT模型最终输出的是每个样本在每棵树中落入叶子节点的索引,实际使用时,先得到所有样本在子树中叶子节点索引的数组,然后对每棵树的叶子节点做one-hot,即可得到所有样本的组合特征。

比如:1000个样本,采用GBDT训练得到10棵树的模型,最终生成1000×10×1的三维数组,其中:若索引为(1, 2, 1)的位置保存的值3,表示第一个样本在第二颗树中划分到第3个叶子节点。将三维数组重构为1000×10的二维数组,其中每一行表示一个样本,每一列表示一颗子树(每一列的值是树的叶子节点的索引位置),对每一颗子树做one-hot,即可得到所有样本的组合特征。

二、实现

下面采用sklearn和lightgbm两种方法构造组合特征:

sklearn:
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import log_loss
from sklearn.preprocessing import OneHotEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier# baseline:LR
def lr_predict(X, y):# 划分数据集x_tr, x_val, y_tr, y_val = train_test_split(X, y, test_size=0.3, random_state=2019)# LRlr = LogisticRegression(solver='lbfgs')lr.fit(x_tr, y_tr)# 评估:log_losstr_logloss = log_loss(y_tr, lr.predict_proba(x_tr)[:, 1])print("lr_tr: ", tr_logloss)val_logloss = log_loss(y_val, lr.predict_proba(x_val)[:, 1])print("lr_val", val_logloss)# GBDT + LR
def gbdt_lr(X, y):# 训练GBDTgbc = GradientBoostingClassifier(n_estimators=50, random_state=2019, subsample=0.8, max_depth=6)gbc.fit(X, y)# 构造组合特征gbc_leaf = gbc.apply(X)gbc_feats = gbc_leaf.reshape(-1, 50)      # 50棵树enc = OneHotEncoder(categories='auto')enc.fit(gbc_feats)gbc_new_feature = np.array(enc.transform(gbc_feats).toarray())# 原始特征&组合特征X = np.concatenate((X, gbc_new_feature),axis=1)# 划分数据集x_train, x_val, y_train, y_val = train_test_split(X, y, test_size = 0.3, random_state = 2019)# LRlr = LogisticRegression(solver='lbfgs')lr.fit(x_train, y_train)# 评估:log_losstr_logloss = log_loss(y_train, lr.predict_proba(x_train)[:, 1])print("gbdt_lr_tr: ", tr_logloss)val_logloss = log_loss(y_val, lr.predict_proba(x_val)[:, 1])print("gbdt_lr_val", val_logloss)if __name__ == '__main__':iris = datasets.load_iris()X = iris.data[:100]y = iris.target[:100]lr_predict(X, y)gbdt_lr(X, y)

输出:

lr_tr:  0.02796944108291242
lr_val 0.033278794811420216
gbdt_lr_tr:  0.003021625219689864
gbdt_lr_val 0.003096137856021479

明显可以看出,GBDT构造组合特征后,采用LR训练的模型log_loss更小。

其中:

  • model.apply(X_train)的用法:
    model.apply(X)返回训练数据X在训练好的模型里每棵树中所处的叶子节点的位置(索引);

    sklearn-apply

  • sklearn.preprocessing 中OneHotEncoder的使用:
    除了pandas中的 get_dummies(),sklearn也提供了一种对Dataframe做One-hot的方法;
    OneHotEncoder() 首先fit() 过待转换的数据后,再次transform() 待转换的数据,就可实现对这些数据的所有特征进行One-hot 操作;
    由于transform() 后的数据格式不能直接使用,所以最后需要使用.toarray() 将其转换为我们能够使用的数组结构。
    enc.transform(gbc_feats).toarray()

lightgbm:
def lgb_predict(X, y):x_train, x_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=2019)print('开始训练gbdt..')gbm = lgb.LGBMRegressor(objective='binary', subsample=0.8, max_depth=6, n_estimators=50)gbm.fit(x_train, y_train,eval_set=[(x_train, y_train), (x_val, y_val)],eval_names=['train', 'val'],eval_metric='binary_logloss',)model = gbm.booster_print('训练得到叶子数')gbm_feats = model.predict(X, pred_leaf=True)gbc_feats = gbm_feats.reshape(-1, 50)  # 50棵树enc = OneHotEncoder(categories='auto')enc.fit(gbc_feats)gbc_new_feature = np.array(enc.transform(gbc_feats).toarray())# 原始特征&组合特征X = np.concatenate((X, gbc_new_feature), axis=1)# 划分数据集x_train, x_val, y_train, y_val = train_test_split(X, y, test_size=0.3, random_state=2019)# LRlr = LogisticRegression(solver='lbfgs')lr.fit(x_train, y_train)# 评估:log_losstr_logloss = log_loss(y_train, lr.predict_proba(x_train)[:, 1])print("gbdt_lr_tr: ", tr_logloss)val_logloss = log_loss(y_val, lr.predict_proba(x_val)[:, 1])print("gbdt_lr_val", val_logloss)


lightgbm-pred_leaf

参考资料:
回顾Facebook经典CTR预估模型
GBDT+LR算法解析及Python实现

用GBDT构建组合特征相关推荐

  1. python机器学习案例系列教程——GBDT构建新特征

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 GBDT的算法参考:https://blog.csdn.net/luanpeng825485697/article/details/7 ...

  2. XGBoost Plotting API以及GBDT组合特征实践

    XGBoost Plotting API以及GBDT组合特征实践 写在前面: 最近在深入学习一些树模型相关知识点,打算整理一下.刚好昨晚看到余音大神在Github上分享了一波 MachineLearn ...

  3. 【数据竞赛】组合特征的构建技巧,如何快速构建百大组合特征池

    作者:尘沙杰少.樱落.新峰.DOTA.谢嘉嘉 特征工程--无序/有序类别/数值特征的组合特征! 前 言 这是一个系列篇,如果有任何问题或者疑问的可添加我的微信一起讨论,备注:"竞赛小册&qu ...

  4. 【数据竞赛】十组不同类型的组合特征!

    作者:尘沙杰少.樱落.新峰.DOTA.谢嘉嘉 特征工程--数值&时间的二阶组合特征! 前 言 本篇文章是关于数值特征与其它类型特征的二阶组合特征以及时间特征与其它特征的组合特征,这一块的东西相 ...

  5. 【数据竞赛】十大重要的时间组合特征!

    作者:尘沙杰少.樱落.新峰.DOTA.谢嘉嘉 特征工程--无序类别&时间信息的组合特征! 前 言 本篇文章我们会介绍10大与时间相关的组合特征,这些特征在95%涉及到时间信息的竞赛中都是极为重 ...

  6. 特征工程+特征组合+特征交叉+特征变换+生成特征

    特征组合+特征交叉(交叉特征,组合特征,特征组合)+特征变换+生成特征+特征提取+ 特征缩放+特征选择+特征分箱+时间特征+特征关联+文本特征+特征采样 特征关联---->corr() 特征分箱 ...

  7. ML之FE:数据处理—特征工程之高维组合特征的处理案例(矩阵分解)——基于LoR算法的广告点击预估问题

    ML之FE:数据处理-特征工程之高维组合特征的处理案例(矩阵分解)--基于LoR算法的广告点击预估问题 目录 特征工程之高维组合特征的处理思路 1.原始数据:语⾔言和类型两种离散特征 2.为了提高拟合 ...

  8. 什么是高维组合特征?

    为了提高模型对数据复杂关系的拟合能力,在做特征工程时常常对一些特征进行组合,构成高阶特征. 以逻辑回归为例,假设数据特征向量为X=(x1,x2,...,xk)X = (x_1, x_2, ..., x ...

  9. LR和GBDT高维稀疏特征

    LR和GBDT高维稀疏特征 面试被问到GBDT是否适合处理高维稀疏特征,没有答上来,感觉自己对模型理解深度不够. 结论:LR适合处理高维稀疏特征,而GBDT不适合. 主要原因有: 1.高维特征会导致g ...

最新文章

  1. 【Qt】Qt再学习(八):Media Player(Qt实现多媒体播放器)
  2. android jar 电子书下载,【Android】Gradle project sync jar包长时间下载不下来的解决办法...
  3. 截取指定长度html内容,并保留html格式标记
  4. 十面阿里,七面头条,你猜我进阿里没?
  5. Socket与WebSocket交互的实现思路
  6. Windows Live Messenger 新功能预览
  7. css分页实例讲解,CSS 分页实例
  8. [导入]CLR探索系列:Server and Workstation Garbage Collection探索(垃圾回收系列)
  9. txt文档下载另存为解决
  10. 关于WIN10下NVIDIA安装驱动后没有控制面板的解决办法
  11. mysql数据库面试题学生表_SQL笔试题:下面是学生表(student)的结构说明
  12. 残差自回归模型的R实现
  13. hbase的快速下载
  14. win10计算机的数字小键盘,让Win10登录时默认开启数字小键盘
  15. Linux 将本地文件上传Linux服务器, 即ssh 命令上传本地文件
  16. 用css+jquery实现视频永远占满全屏效果
  17. imx6ul mqs 音频爆破音
  18. JAVA圆和正方形组合图形_关于java:图形数据流组合框架
  19. 计组-流水线(三张图解决流水线概念计算吞吐率)
  20. uniapp消息推送(个推-PHP服务端推送)

热门文章

  1. oracle sql语言模糊查询--通配符like的使用教程
  2. MISC-bugku一个普通的压缩包
  3. 【干货·案例】金融行业应用型CMDB建设实录
  4. 三个点菜单(选项菜单)
  5. python程序设计教程杨年华_Python程序设计教程
  6. wireshark中抓取ICMP报文
  7. 80后的蚁族尴尬:滞苦的一代
  8. elemet-ui图标—特殊字符的unicode编码表
  9. powershell反弹shell
  10. python 栈和队列的区别_Python 栈与队列