1. 背景

1.1 Gradient Boosting

Gradient Boosting是一种Boosting的方法,它主要的思想是,每一次建立模型是在之前建立模型损失函数的梯度下降方向。损失函数是评价模型性能(一般为拟合程度+正则项),认为损失函数越小,性能越好。而让损失函数持续下降,就能使得模型不断改性提升性能,其最好的方法就是使损失函数沿着梯度方向下降(讲道理梯度方向上下降最快)。

Gradient Boost是一个框架,里面可以套入很多不同的算法。

1.2 Gradient Boosting Decision Tree

每一次建立树模型是在之前建立模型损失函数的梯度下降方向。即利用了损失函数的负梯度在当前模型的值作为回归问题提升树算法的残差近似值,去拟合一个回归树。

具体算法算理:GBDT原理-Gradient Boosting Decision Tree

1.3 GBDT应用-回归和分类

GBDT分类:每一颗树拟合当前整个模型的损失函数的负梯度,构建新的树加到当前模型中形成新模型,下一棵树拟合新模型的损失函数的负梯度。下面是其在Python的sklearn包下简单调用方法。

from sklearn import ensemble
clf = ensemble.GradientBoostingClassifier()
gbdt_model = clf.fit(X_train, y_train) # Training model
predicty_x = gbdt_model.predict_proba(test1217_x)[:, 1] # predict: probablity of 1
# 包含的参数
# loss = loss, learning_rate = learning_rate, n_estimators = n_estimators,
# min_samples_split = min_samples_split,
# min_samples_leaf = min_samples_leaf,
# min_weight_fraction_leaf = min_weight_fraction_leaf,
# max_depth = max_depth, init = init, subsample = subsample,
# max_features = max_features,
# random_state = random_state, verbose = verbose,
# max_leaf_nodes = max_leaf_nodes, warm_start = warm_start,
# presort = presort

GBDT回归:每一颗树拟合当前整个模型的残差,构建新的树加到当前模型中形成新模型,下一棵树拟合新模型的损失函数的负梯度。

from sklearn import ensemble
clf = ensemble.GradientBoostingRegressor()
gbdt_model = clf.fit(X_train, y_train) # Training model
y_upper = gbdt_model.predict(x_test) # predict
# 包含的参数和上面一致。

GBDT调参问题:sklearn中GBDT调参

GBDT运用的正则化技巧,防止模型过于复杂,参考这篇文章GBDT运用的正则化技巧

2. GBDT构建新的特征思想

特征决定模型性能上界,例如深度学习方法也是将数据如何更好的表达为特征。如果能够将数据表达成为线性可分的数据,那么使用简单的线性模型就可以取得很好的效果。GBDT构建新的特征也是使特征更好地表达数据。

主要参考Facebook[1],原文提升效果:

在预测Facebook广告点击中,使用一种将决策树与逻辑回归结合在一起的模型,其优于其他方法,超过3%。

主要思想:GBDT每棵树的路径直接作为LR输入特征使用。

用已有特征训练GBDT模型,然后利用GBDT模型学习到的树来构造新特征,最后把这些新特征加入原有特征一起训练模型。构造的新特征向量是取值0/1的,向量的每个元素对应于GBDT模型中树的叶子结点。当一个样本点通过某棵树最终落在这棵树的一个叶子结点上,那么在新特征向量中这个叶子结点对应的元素值为1,而这棵树的其他叶子结点对应的元素值为0。新特征向量的长度等于GBDT模型里所有树包含的叶子结点数之和。

上图为混合模型结构。输入特征通过增强的决策树进行转换。 每个单独树的输出被视为稀疏线性分类器的分类输入特征。 增强的决策树被证明是非常强大的特征转换。

例子1:上图有两棵树,左树有三个叶子节点,右树有两个叶子节点,最终的特征即为五维的向量。对于输入x,假设他落在左树第一个节点,编码[1,0,0],落在右树第二个节点则编码[0,1],所以整体的编码为[1,0,0,0,1],这类编码作为特征,输入到线性分类模型(LR or FM)中进行分类。

论文中GBDT的参数,树的数量最多500颗(500以上就没有提升了),每棵树的节点不多于12。

3. GBDT与LR融合方案

在CTR预估中,如何利用AD ID是一个问题。

直接将AD ID作为特征建树不可行,而onehot编码过于稀疏,为每个AD ID建GBDT树,相当于发掘出区分每个广告的特征。而对于曝光不充分的样本即长尾部分,无法单独建树。

综合方案为:使用GBDT对非ID和ID分别建一类树。

  1. 非ID类树:

    不以细粒度的ID建树,此类树作为base,即这些ID一起构建GBDT。即便曝光少的广告、广告主,仍可以通过此类树得到有区分性的特征、特征组合。

  2. ID类树:

    以细粒度 的ID建一类树(每个ID构建GBDT),用于发现曝光充分的ID对应有区分性的特征、特征组合。如何根据GBDT建的两类树,对原始特征进行映射?以如下图3为例,当一条样本x进来之后,遍历两类树到叶子节点,得到的特征作为LR的输入。当AD曝光不充分不足以训练树时,其它树恰好作为补充。

方案如图:

其中kaggle竞赛一般树的数目最多为30,通过GBDT转换得到特征空间相比于原始ID低了很多。

4. 源码内容

具体kaggle-2014-criteo实现的GitHub源码:https://github.com/guestwalk/kaggle-2014-criteo

generate GBDT features:

例子2:下图假设训练了3颗深度2的树模型,对于输入X,在第1个树属于节点4,在第2个树属于节点7,第3颗树属于节点6,所以生成的特征为”1:4 2:7 3:6”

generate features for FFM

  • 数值型特征:进行变换:v←⌊log(v)2⌋v←⌊log(v)2⌋

  • 类别特征:出现小于10的类转换到一个特殊的value,即合为一种。

  • GBDT特征直接使用。
  • 使用hashing trick将三类特征映射到1M-dimensionl。

FFM详细资料>>

5. Python实现

上面的源码用到了多线程实现,Python的sklearn库中提供了该方法,下面简单的实践:

首先要明确使用libFFM还是逻辑回归,两者不同之处在于:

libFFM适用于例子2的情况,即只用使用每棵树的index。

逻辑回归适用于例子1的情况,须将节点使用one-hot编码,核心代码如下:其中关键方法为树模型(GBDT)的apply()方法。

# 弱分类器的数目
n_estimator = 10
# 随机生成分类数据。
X, y = make_classification(n_samples=80000)
# 切分为测试集和训练集,比例0.5
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)
# 将训练集切分为两部分,一部分用于训练GBDT模型,另一部分输入到训练好的GBDT模型生成GBDT特征,然后作为LR的特征。这样分成两部分是为了防止过拟合。
X_train, X_train_lr, y_train, y_train_lr = train_test_split(X_train, y_train, test_size=0.5)
# 调用GBDT分类模型。
grd = GradientBoostingClassifier(n_estimators=n_estimator)
# 调用one-hot编码。
grd_enc = OneHotEncoder()
# 调用LR分类模型。
grd_lm = LogisticRegression() '''使用X_train训练GBDT模型,后面用此模型构造特征'''
grd.fit(X_train, y_train) # fit one-hot编码器
grd_enc.fit(grd.apply(X_train)[:, :, 0]) '''
使用训练好的GBDT模型构建特征,然后将特征经过one-hot编码作为新的特征输入到LR模型训练。
'''
grd_lm.fit(grd_enc.transform(grd.apply(X_train_lr)[:, :, 0]), y_train_lr)
# 用训练好的LR模型多X_test做预测
y_pred_grd_lm = grd_lm.predict_proba(grd_enc.transform(grd.apply(X_test)[:, :, 0]))[:, 1]
# 根据预测结果输出
fpr_grd_lm, tpr_grd_lm, _ = roc_curve(y_test, y_pred_grd_lm)

  

这只是一个简单的demo,具体参数还需要根据具体业务情景调整。 
官方例子介绍:http://scikit-learn.org/stable/auto_examples/ensemble/plot_feature_transformation.html#example-ensemble-plot-feature-transformation-py

总结

对于样本量大的数据,线性模型具有训练速度快的特点,但线性模型学习能力限于线性可分数据,所以就需要特征工程将数据尽可能地从输入空间转换到线性可分的特征空间。GBDT与LR的融合模型,其实使用GBDT来发掘有区分度的特征以及组合特征,来替代人工组合特征。工业种GBDT+LR、GBDT+FM都是应用比较广泛。

csdn原文:http://blog.csdn.net/shine19930820/article/details/71713680

References

    1. Xinran He et al. Practical Lessons from Predicting Clicks on Ads at Facebook, 2014.

    2. GBDT原理-Gradient Boosting Decision Tree

    3. Gradient Boosting Decision Tree学习

    4. 腾讯大数据:CTR预估中GBDT与LR融合方案

转载自https://blog.csdn.net/shine19930820/article/details/71713680

GBDT原理及利用GBDT构造新的特征-Python实现的更多相关文章

  1. 梯度提升树(GBDT)原理小结(转载)

    在集成学习值Adaboost算法原理和代码小结(转载)中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boos ...

  2. 利用GBDT模型构造新特征具体方法

    利用GBDT模型构造新特征具体方法 数据挖掘入门与实战  公众号: datadw   实际问题中,可直接用于机器学**模型的特征往往并不多.能否从"混乱"的原始log中挖掘到有用的 ...

  3. 梯度提升树(GBDT)原理小结

    在集成学习之Adaboost算法原理小结中,我们对Boosting家族的Adaboost算法做了总结,本文就对Boosting家族中另一个重要的算法梯度提升树(Gradient Boosting De ...

  4. GBDT基本理论及利用GBDT组合特征的具体方法(收集的资料)

    最近两天在学习GBDT,看了一些资料,了解到GBDT由很多回归树构成,每一棵新回归树都是建立在上一棵回归树的损失函数梯度降低的方向. 以下为自己的理解,以及收集到的觉着特别好的学习资料. 1.GBDT ...

  5. 机器学习入门:极度舒适的GBDT原理拆解

    机器学习入门:极度舒适的GBDT拆解 本文旨用小例子+可视化的方式拆解GBDT原理中的每个步骤,使大家可以彻底理解GBDT Boosting→Gradient Boosting Boosting是集成 ...

  6. GBDT原理详解

    从提升树出发,——>回归提升树.二元分类.多元分类三个GBDT常见算法. 提升树 梯度提升树 回归提升树 二元分类 多元分类 面经 提升树 在说GBDT之前,先说说提升树(boosting tr ...

  7. XGBoost,GBDT原理详解,与lightgbm比较

    xgb原理: https://www.jianshu.com/p/7467e616f227 https://blog.csdn.net/a819825294/article/details/51206 ...

  8. 手撸GBDT原理(未完成)

    一直对GBDT里面的具体计算逻辑不太清楚,在网上发现了一篇好博客. 先上总结的关系图 GBDT对类别变量是怎么处理的? 这些东西都是在网上发现的,讲的挺好的. GBDT原理与Sklearn源码分析-回 ...

  9. 初级安全入门——SQL注入的原理与利用

    工具简介 SQLMAP: 一个开放源码的渗透测试工具,它可以自动探测和利用SQL注入漏洞来接管数据库服务器.它配备了一个强大的探测引擎,为最终渗透测试人员提供很多强大的功能,可以拖库,可以访问底层的文 ...

随机推荐

  1. sql 存储过程学习

    1.存储过程 存储过程可以包含数据操纵语句.变量.逻辑 控制语句等,比如:单个select语句, select语句块,select语句与逻辑控制块. 存储过程优点: 执行速度更快 允许模块化程序设计 ...

  2. vcenter 忘记 administrator@vsphere.local 密码怎么办

    现有一个windows版本的vcenter5.5管理员密码丢失,我们可以使用vmware的工具vdcadmintool,在命令行进入到vdcadmintool所在的目录,然后执行下vdcadminto ...

  3. 设置MYSQL数据库编码为UTF-8

    设置MYSQL数据库编码为UTF-8   1.  编辑MySql的配置文件 MySql的配置文件Windows下一般在系统目录下或者在MySql的安装目录下名字叫my.ini,可以搜索,Linux下一 ...

  4. springboot中访问jsp文件方式

    首先,添加加载jsp文件的依赖包: <!--jsp依赖 对应springboot版本为2.1.4--><dependency> <groupId>org.apach ...

  5. Linux之判断字符串是否为空

    help命令可以查看帮助 help test 正确做法: #!/bin/sh STRING= if [ -z "$STRING" ]; then     echo "ST ...

  6. Tomcat热部署--start tomcat后就可自动部署war包

    使用tomcat图形化界面,需要现在配置文件中设置用户名和密码: 在maven中配置Tomcat插件: root目录下的内容可以直接访问: 跳过测试: 查看端口占用:

  7. Linux(Ubunt)使用日记------常用软件汇总(不定时更新)

    整理总结日常Ubuntu中使用的一些软件,事实证明使用Linux真的会让人的欲望变小有个能用的就不错啦,不要调三捡四 解压类 Unzip | unzip -O CP936 files Unrar ra ...

  8. MVC中使用Hangfire按秒执行任务

    更新Hangfire版本到1.7.0,才支持使用按秒循环任务执行 RecurringJob.AddOrUpdate("test",()=>writeLog("每20 ...

  9. 按PEP8风格自动排版Python代码

    Autopep8是一个将Python代码自动排版为PEP8风格的小工具.它使用pep8工具来决定代码中的哪部分需要被排版.Autopep8可以修复大部分pep8工具中报告的排版问题. 安装步骤如下: ...

  10. 使用Yii2的Web框架搭建微服务框架

    方法 使用自己的Yii2镜像作为基础 使用Yii2的Web框架搭建,为了节省搭建Yii2框架的时间,直接使用现有的Yii2项目,删除了业务相关的逻辑类,将这个代码库作为搭建微服务框架的基础,本身已经积 ...