xgboost 正则项_深入理解Boosting算法(4)-XGBoost
导语:记得第一次使用XGBoost的时候还是2016年,那会的XGBoost工具还不完善,深度模型还没有怎么样火起来,大家用的最多的还是Sklearn里面的GBDT,或者R语言的GBM。后来在工作中也把这工具用在搜索点击率预估上,然后就时不时收到预测超时等性能问题。后来,又出现了LightGBM, 跑树模型基本上也就基本上告别了这个工具,但是很多人第一个集成树模型应该是XGBoost,它使得GBDT模型在大数据时代大规模的普及使用起到了重要作用,本文简单纪念一下它。
本文大纲如下:
- GBDT模型训练复杂度分析
- 正则化的损失函数(总)
- 第
次迭代的损失函数(分)
- 从损失函数到树的评分函数
- 特征最优切分点算法
- 稀疏特征处理方式
GBDT模型训练复杂度分析
对于神经网络模型,可以通过利用mini-batch的形式将数据小批量地输入进行模型训练,而对于传统的机器学习模型,如GBDT模型在一次训练过程中需要使用整个训练数据集,而且在构建树的过程中还需要对整个数据集进行多轮的遍历,因此从近几年才发表的XGBoost, LightGBM的引用论文中就可以发现,从1998年开始,就有很多论文在开始研究如何在大规模数据下高效训练模型的方法。 在GBDT训练过程中,最耗时的部分在于回归树的构建过程中最优分裂特征,分裂阈值的查找过程。目前主要有以下几大类方式:
- 特征预排序: 对特征的取值进行预先排序,枚举出可能的分裂点,如使用贪心算法进行枚举(并不高效,但是可以找到最优分裂点),或者利用特征的分位点进行近似的近似算法等(XGBoost中使用的方式,本文将进行介绍);
- 基于特征直方图:对于连续型的特征将其进行离散化,得到特征的离散取值(bin),用于构建关于特征信息的(一阶导数,二阶导数)直方图;使用直方图的优势在于可以不需要对特征进行排序,毕竟排序算法很耗时的, 在LightGBM算法中将进行详细介绍该方法。
关于计算复杂度的简单计算,如果利用
有了上述的复杂度的基本认识,就知道从哪些方向进行优化,如如何在训练过程中减少训练样本,以及减少特征个数等,在LightGBM里面将详细介绍(hmm, 咋一直跑题)。为了保证更好的理解以及以后方便查阅,本文搞了很多公式,但是机器学习里面的公式都是加加减减,多看几遍就真香了,本文包含的内容:
- XGBoost在损失函数上的设计,从整个模型的损失计算到第
次迭代过程的推导计算;
- XGBoost最优特征分裂方式,增益计算
- XGBoost针对稀疏特征的学习方式
本文不包含系统设计,虽然大规模机器学习系统是一个很有魅力的方向,对其中涉及到的分布式算法,通信等复杂问题需要补上N篇论文才能说的清楚,有兴趣的同学可以参考这个链接进行学习(https://github.com/mercari/ml-system-design-pattern)。
正则化的损失函数(总)
XGBoost是Boosting算法家族中的一员,因此其形式上也是有
其中的假设空间中的所有CART回归树模型
- 树的结构(树的深度,叶子节点个数)以及特征分裂阈值,
- 叶子节点的权重(特别说明GBDT,XGBoost等使用的回归树,因为叶子节点存在权重信息)
单颗树的结构由符号
离散化映射到
有了上述定义符号表示,就要介绍XGBoost中使用的正则化的损失函数了,相比GBDT模型,引入了正则项用于防止过拟合,其形式如下所示(其实很早就有了类似的思想):
从损失函数上不难理解,在给定
- 叶子节点权重的
范数,目的是使得权重值更平滑,连续;
- 叶子节点的个数
,在XGBoost中树的生长方式是Level-wise的方式,每一层都需要同时进行分裂,有可能导致不必要的特征参与分裂,如下图对比所示(后续的文章中会加入LigthGBM的原理,会有更详细的对比)
图1:两种决策树生长方式
第
假设在完成第
此时,将损失函数
完成了在第
- 上述公式的第一步中,跟
的区别是,正则项只有前颗树,因为此时才迭代到第颗树,后面的树还需要在学习;
- 从第二步到第三步,发现已经将正则项,从累加变成了第
颗树的正则项,以及常数,因此在此时前面第颗树是已知的,所以其正则项之后也是已知的,用表示即可,方便后续推导;
从损失函数到树的评分函数
众所周知,XGBoost利用二阶泰勒展开来近似表示第
将上述公式与XGBoost的在第
因此,可以定义损失函数
上述公式中,常数
即可求出,最优值为:
将
有了该公式,我们可以用于评价生成的树的得分,得分越小,说明树的结构越好。到目前为止,我们知道了叶子节点的最优取值(解析解),以及最小的损失函数取值,然而,仔细回顾一下,我们还没有确定树的结构,公式也没有告诉我们该怎么得到最优的树的结构,下面部分将解答该问题。
特征最优切分点算法
树长成啥样还不知道,我们只是有了评价树结构好不好的公式。最近简单的办法,就是暴力枚举所有可能的结构,但这肯定是不能被接受的。那就要贪心法上场了,每次尝试分裂一个节点,计算分裂前后的增益,选择增益最大的那次分裂即可,依次循环下去。注意,贪心法不是XGBoost才有,从最经典的ID3,C4.5,CART树开始就有了,只不过,其使用的评估指标不一样而已;
- ID3, 信息增益
- C4.5, 信息增益比
- CART, Gini系数,平方损失
- XGboost, 由一阶导数,二阶导数构成的打分函数
如果对这部分知识点有点疑问,可以参考此前的文章中关于回归树的生长分裂过程。在XGboost中具体实现中,有两种特征切分点算法, 贪心法和近似算法。
贪心算法
对一个特征最佳特征分裂阈值的选择,是用分裂之前的评估指标值,减去分裂后的值,找到增益最大的,即完成本次分裂搜索,对于XGboost而言,一次分裂之后,会将该节点上的样本划分到两个不相交的样本空间, 用
每次特征分裂的增益计算: 分裂前:
分裂后:
所以,分裂之后的增益为:
贪心算法的流程如下图所示:
贪心算法对每个特征都做线性搜索,根据样本特征的排序值,逐步将更多的样本加入到左子树,根据增益函数得到的最大的点,即为最优的分割点。 步骤:
- 从当前节点出发,依次为
个特征,将属于该节点上的样本按照特征的取值进行升序排列,依次枚举出分裂点,根据增益函数得到该分裂点的增益值,保存中间结果;
- 选择增益最大的分裂点,作为当前节点的最佳分裂点
- 回到第一步,并行地为其他的节点选择最佳的分裂点(layer-wise树生长方式容易并行);
近似算法
由于贪心算法需要对每个特征进行排序,因此成为计算速度的瓶颈。近似算法就是根据特征的分布提前计算得到
从算法流程图中,可以看到,第一步是提前计算,或者每次分裂的时候计算各个特征的分位点,而在第二个for循环中,是分别为每个特征,统计得到落在各个区间的样本的一阶导数和二阶导数汇总起来,得到对应区间的
- 根据特征的分布,找到3分位点,将当前节点下的样本分成了3份;
- 根据损失函数,得到各个样本在某次迭代过程中的一阶导数
和二阶导数;
- 将各个区间内的样本的一阶导数和二阶导数进行求和汇总,分别得到
,,
- 利用与贪心算法相同的方法,寻找区间最佳的分裂点,由于只有3个区间,因此只有2两组合方式,1|2,3, 或者 1, 2 | 3
简单总结贪心算法与近似算法
- 贪心算法需要为每个特征进行线性搜索,枚举出所有的分裂点,而近似算法只需要统计分位点信息,枚举分位的取值即可;
- 贪心算法在样本级别寻找特征的最佳分裂点,而近似算法在区间级别;查找的次数大大减少
论文中也对两种的算法的精度做了比较,这里先不赘述
补充:常用损失函数的一阶导数,二阶导数推导
以下对平方损失函数,对数损失函数进行求导:
- 平方损失函数
即
时
- 损失函数为对数损失
令
,表示前颗树对于样本的预测值,由对数损失函数的定义可知,
对数损失函数的一阶导数,以及二阶导数的的推导,由于对数损失函数是有两部分组成,因此在二分类时(
当
时,当
时,
而对于二阶导数,只需要在对
sigmoid
函数的求导,即可得到我们的结果:
稀疏特征处理方式
所谓的稀疏特征就是特征
至于各个特征应该往哪个方向偏,也是利用数据进行训练得到的,选择增益最大的方向, 训练过程如下图所示(以特征
- 对于特征
, 选择取值为非空的样本,构成样本集合, 利用近似算法进行特征最优阈值查找;
- 假定将缺失特征样本全部分裂到右子树,计算得到该特征的增益值;
- 假定将缺失特征样本全部分裂到左子树,计算得到该特征的增益值;
- 根据特征增益值,选择取值最大的方向作为该特征的默认最大值
在训练的过程中,可以将稀疏特征处理方式和非稀疏特征整合在一起。
本系列其他文章:
质数:深入理解Boosting算法(1)-基础知识回顾zhuanlan.zhihu.com
质数:深入理解Boosting算法(2)-AdaBoostzhuanlan.zhihu.com
质数:深入理解Boosting算法(3)-GBDTzhuanlan.zhihu.com
xgboost 正则项_深入理解Boosting算法(4)-XGBoost相关推荐
- xgboost 正则项_详述Xgboost原理
声明:文章转自 https://www.jianshu.com/p/7467e616f227 xgboost 已然火爆机器学习圈,相信不少朋友都使用过.要想彻底掌握xgboost,就必须搞懂其内部的模 ...
- python xgboost实战_史上最详细的XGBoost实战
0. 环境介绍 Python 版 本: 3.6.2 操作系统 : Windows 集成开发环境: PyCharm 1. 安装Python环境 安装Python 首先,我们需要安装Python环境.本人 ...
- xgboost参数_具有贝叶斯优化的XGBoost和随机森林
作者 | Edwin Lisowski 编译 | CDA数据分析师 XGBoost and Random Forest with Bayesian Optimisation 在这篇文章中,我们将介绍带 ...
- a*算法的优缺点_轻松理解机器学习算法-朴素贝叶斯
1.预备知识 贝叶斯定理(Bayes' theorem)是概率论中的一个定理,它跟随机变量的条件概率以及边缘概率分布有关.通常事件A在事件B发生的条件下的概率,与事件B在事件A发生的条件下的概率是不一 ...
- [机器学习] Boosting算法2 --- GBDT
[机器学习] Boosting算法1 --- AdaBoost [机器学习] Boosting算法2 --- GBDT [机器学习] Boosting算法3 --- XGBoost [机器学习] Bo ...
- 集成学习boosting算法:AdaboostGBDTXgboostLightGBMCatBoost
Adaboost&GBDT&Xgboost&LightGBM&CatBoost 0简介 0.0发展史 0.1 经典文章链接/文章总结链接 0.2 bagging和boo ...
- [机器学习] Boosting算法1 --- AdaBoost
[机器学习] Boosting算法1 --- AdaBoost [机器学习] Boosting算法2 --- GBDT [机器学习] Boosting算法3 --- XGBoost [机器学习] Bo ...
- [机器学习] Boosting算法4 --- LightGBM介绍与分布式
[机器学习] Boosting算法1 --- AdaBoost [机器学习] Boosting算法2 --- GBDT [机器学习] Boosting算法3 --- XGBoost [机器学习] Bo ...
- boosting算法_集成学习:boosting、BDT、GBDT的概括理解
boosting是一种集成学习的方法,与bagging并列形成俩中不同的集成学习算法,本文主要概括boosting方法. boosting在训练过程中,它通过改变训练样本的权重,学习多个学习器,然后将 ...
最新文章
- OpenStack Ocata版本国内代码贡献盘点
- nas servers
- Linux常用命令----压缩解压命令
- mysql 5.7.20主从配置_mysql5.7.20免安装版配置方法图文教程
- linux如何使用vnc远程登录,如何使用Xmanager及VNC登录远程桌面
- android 设备注册,i2c_设备注册流程
- 微信jssdk在iframe页面失效问题的解决措施
- DevExtreme 移动跨平台开发 C#语言
- python线程池threadpool
- 非线性发展方程定解问题
- 什么A股,B股,H股?什么是红筹股,蓝筹股?
- session的到底是做什么的?
- 31-最大子矩阵(蓝桥杯)
- 万邦京东获取推荐商品列表 API
- 屏幕分辨率(QQVGA、QVGA、VGA、XGA、WXGA、WUXGA和WSXGA+)
- 【C语言】实现双人控制的战斗小游戏
- kitti数据集理解及可视化
- 同济大学计算机学院杨志强,大学计算机课程论坛-同济大学计算机基础教研室.PDF...
- matlab中增大迭代次数,贝叶斯优化matlab
- Oracle通过定时任务+dblink+存储过程传数据到中间库