参考&引用:陈天奇论文,ppt等(已上传https://download.csdn.net/download/haozhepeng/11287103) &
https://blog.csdn.net/qq_22238533/article/details/79477547
目录
一、原理
1.Bias-Variance(偏差方差思想)
任何机器学习的问题都可以从目标函数(objective function)出发,目标函数的主要由两部分组成 损失函数+正则项
损失函数用于描述模型拟合数据的程度。
正则项用于控制模型的复杂度。
这个就是偏差方差思想,也是所有机器学习考虑的两个角度,可以对比RF,RF是最小化方差的模型。
2.XGB过程推导
-
XGB过程简述
首先需要了解的前提是XGB和GBDT一样,都是GB的,也就是树是顺序生成,每颗树是拟合残差的。
如下图,第一个图表示生成第一颗树,小男孩预测值为2,假设样本值为4 ,那训练过程中,第二颗树(图2)拟合目标是残差2(4-2),最后每棵树预测结果相加,就是XGB预测结果
-
XGB训练过程&推导
假设训练K颗树
目标函数则为
我们的训练过程图下:
所以我们每一轮需要的拟合的是f(x)函数
二阶泰勒展开如下:
其中当作x,当作,
我们假设一阶导和二阶导如下:
则目标函数可以写成下面式子:
去掉所有常数项:
我们令f(x)如下,其中q(x)是叶子节点的编号:
可以理解为一棵树其实可以由若干个叶子节点和叶子节点对应的值来表达。每个样本最后都会落在一个叶子上。
那么,我们上面的正则项就了其中一个思路。我们可以对叶子节点值进行惩罚(正则),比如取L2正则(L1稀疏特征,L2 使得特征权重减小),以及我们控制一下叶子节点的个数T,所以我们令损失项如下(这里损失项不是唯一解):
所以可以推导得:
令落在j叶子节点的样本空间:
我们令
则
这是个关于的二次函数。
关于二次函数我们知道(一阶导数=0求极值):
所以可得:
三、生成树的分裂准则
由上面推出的损失函数最优值为可以看出可以作为生成树的标准 ,所以XGB定义分裂标准。
需要注意这里是XGB比GBDT先进的一点,GBDT是自定义损失函数后,我们可以选择MSE,MAE来评价我们的分裂的质量,这种选择是启发式的,分裂的好坏和我们的损失在理论上没有直接挂钩。而XGB是直接通过推导找到作为生成树的分裂的准则来生成树。整个生成过程相当于贪心(greedy)
四、缺失值处理
XGB提供了缺失值处理,方式是先把所有缺失值放在右边,计算gain ,再把所有的空值放在左边计算gain ,选择分高的来划分缺失值。
二、实际应用
1.实例
详情参照: https://blog.csdn.net/qq_22238533/article/details/79477547
下面只阐述认为理论部分比较迷糊的地方,如何求G,和H。具体过程写的很好,请参照前面的地址。
数据集地址http://archive.ics.uci.edu/ml/datasets/Container+Crane+Controller+Data+Set
这里为了简单起见,树的深度设置为3(max_depth=3),树的颗数设置为2(num_boost_round=2),学习率为0.1(eta=0.1)。
另外再设置两个正则的参数,。
损失函数选择logloss。
2.调参
参考https://www.cnblogs.com/zhangbojiangfeng/p/6428988.html & https://blog.csdn.net/strwolf/article/details/76462459 & https://blog.csdn.net/han_xiaoyang/article/details/52665396
XGBoost的作者把所有的参数分成了三类:
- 通用参数:宏观函数控制。
- Booster参数:控制每一步的booster(tree/regression)。
- 学习目标参数:控制训练目标的表现。
和GDBT调参差不多,不同的地方是:
1.通用参数booster[默认gbtree](可选gbtree:基于树的模型(一般用这个),gbliner:线性模型)
2.不需要调参n_estimators,而是使用xgboost.cv每次交叉验证返回最理想的决策树数量。之后使用GridSearchCV确定其它参数。
(xgboost.cvGridSearchCV,它存在的意义就是自动调参,只要把参数输进去,它在参数列表中进行穷举搜索,对每种情况进行训练,就能给出最优化的结果和参数。但是这种方法的主要缺点是 比较耗时!这个方法适合于小数据集,一旦数据的量级上去了,很难得出结果)所以对于大数据量,还是要根据经验手动调,和GBDT差不多。
3.调节gamma,lambda, alpha
关于着3个参数,https://juejin.im/post/5b74e892e51d45664153b080 讲的很好
XGB调参步骤:
建议参考https://blog.csdn.net/han_xiaoyang/article/details/52665396,写的很好。
-
选择较高的学习速率(learning rate)。一般情况下,学习速率的值为0.1。但是,对于不同的问题,理想的学习速率有时候会在0.05到0.3之间波动。选择对应于此学习速率的理想决策树数量。XGBoost有一个很有用的函数“cv”,这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量。
-
对于给定的学习速率和决策树数量,进行决策树特定参数调优(max_depth, min_child_weight, gamma, subsample, colsample_bytree)。在确定一棵树的过程中,我们可以选择不同的参数,待会儿我会举例说明。
-
xgboost的正则化参数的调优。(lambda, alpha)。这些参数可以降低模型的复杂度,从而提高模型的表现。
-
降低学习速率,确定理想参数。
第一步:确定学习速率和tree_based 参数调优的估计器数目
为了确定boosting
参数,我们要先给其它参数一个初始值。咱们先按如下方法取值:
1、max_depth
= 5 :这个参数的取值最好在3-10之间。我选的起始值为5,但是你也可以选择其它的值。起始值在4-6之间都是不错的选择。
2、min_child_weight
= 1:在这里选了一个比较小的值,因为这是一个极不平衡的分类问题。因此,某些叶子节点下的值会比较小。
3、gamma
= 0: 起始值也可以选其它比较小的值,在0.1到0.2之间就可以。这个参数后继也是要调整的。
4、subsample, colsample_bytree
= 0.8: 这个是最常见的初始值了。典型值的范围在0.5-0.9之间。
5、scale_pos_weight
= 1: 这个值是因为类别十分不平衡。
这里把学习速率就设成默认的0.1。然后用xgboost中的cv函数来确定最佳的决策树数量。前文中的函数可以完成这个工作。每一次迭代中使用交叉验证,并返回理想的决策树数量。这个值取决于系统的性能。
第二步: max_depth (3-9)和 min_child_weight(决定最小叶子节点样本权重和范围1-5) 参数调优
第三步:gamma参数调优(0-0.5尝试)
第四步:调整subsample 和 colsample_bytree 参数(0.6-0.9调试)
第五步:正则化参数调优lambda, alpha(大范围调试 'reg_alpha':[1e-5, 1e-2, 0.1, 1, 100])
下一步是应用正则化来降低过拟合。由于gamma函数提供了一种更加有效地降低过拟合的方法,大部分人很少会用到这个参数。但是我们在这里也可以尝试用一下这个参数。
三、XGB和GBDT,lightGBM 对比
1 、XGBoost 与 GBDT 对比
- 传统 GBDT 以 CART 作为基分类器,XGboost 还支持线性分类器
- 从目标函数上看,XGB是损失函数+正则项(偏差-方差思想),而GDBT只有损失函数。没有这则项。
- 从推导过程看, GBDT 在优化时只用到一阶导数信息,xgboost 用到了一阶和二阶导数。xgboost 还支持支持自定义代价函数,只要函数可一阶和二阶求导。
- 从建树流程看,xgboost在建树的时候利用的准则来源于目标函数推导,而GBDT建树利用的是启发式准则。(这一点,我个人认为是xgboost牛B的所在,也是为啥要费劲二阶泰勒展开)
- 建树时使用到可并行的近似直方图算法。三分位数。实际上XGBost不是简单地按照样本个数进行分位,而是以二阶导数值作为权重。
- xgboost中可以自动处理空缺值,自动学习空缺值的分裂方向,GBDT(sklearn版本)不允许包含空缺值。
- 列抽样(column subsampling)。xgboost 借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是 xgboost 异于传统 gbdt 的一个特性。
- 工程角度:xgboost 支持在特征粒度上的并行。训练之前,预先对数据进行了Pre-sort,然后保存为 block结构,后面的迭代中重复地使用这个结构,大大减小计算量。
2 、LightGBM 与 XGBoost 的不同点
- 建树选择分裂特征和值时,XGBoost 使用的是近似算法,先对特征值进行预排序 Pre-sort,然后根据二阶梯度进行分桶,复杂度较高。LightGBM 使用的是 histogram 算法,占用的内存更低,数据分割的复杂度更低。
- 决策树生长策略,XGBoost 采用的是 Level-wise 的树生长策略,LightGBM 采用的是 leaf-wise 的生长策略,以最大信息增益为导向。后者进度更高,容易过拟合,所以要控制最大深度。
- 并行策略对比,XGBoost 的并行主要集中在特征并行上,而 LightGBM 的并行策略分特征并行,数据并行以及投票并行。
3 、LightGBM 与 XGboost 的并行策略
3.1 特征并行
lgbm特征并行的前提是每个worker留有一份完整的数据集,但是每个worker仅在特征子集上进行最佳切分点的寻找;worker之间需要相互通信,通过比对损失来确定最佳切分点;然后将这个最佳切分点的位置进行全局广播,每个worker进行切分即可。
xgb的特征并行与lgbm的最大不同在于xgb每个worker节点中仅有部分的列数据,也就是垂直切分,每个worker寻找局部最佳切分点,worker之间相互通信,然后在具有最佳切分点的worker上进行节点分裂,再由这个节点广播一下被切分到左右节点的样本索引号,其他worker才能开始分裂。
二者的区别就导致了lgbm中worker间通信成本明显降低,只需通信一个特征分裂点即可,而xgb中要广播样本索引。
3.2 数据并行
当数据量很大,特征相对较少时,可采用数据并行策略。
lgbm中先对数据水平切分,每个worker上的数据先建立起局部的直方图,然后合并成全局的直方图,采用直方图相减的方式,先计算样本量少的节点的样本索引,然后直接相减得到另一子节点的样本索引,这个直方图算法使得worker间的通信成本降低一倍,因为只用通信以此样本量少的节点。
xgb中的数据并行也是水平切分,然后单个worker建立局部直方图,再合并为全局,不同在于根据全局直方图进行各个worker上的节点分裂时会单独计算子节点的样本索引,因此效率贼慢,每个worker间的通信量也就变得很大。
3.3 投票并行(lgbm)
当数据量和维度都很大时,选用投票并行,该方法是数据并行的一个改进。数据并行中的合并直方图的代价相对较大,尤其是当特征维度很大时。
大致思想是:每个worker首先会找到本地的一些优秀的特征,然后进行全局投票,根据投票结果,选择top的特征进行直方图的合并,再寻求全局的最优分割点。
四、特征准备注意事项
类别特征需要one-hot ,可以onehot 后用NN embeding
五、xgboost如何用于特征选择
特征重要性有3种计算方式,weight,gain,cover .
1.weight:
一般我们调用de xgb库的get_fscore()使用的就是指标weight,他代表着某个特征被选作分裂的次数,没有用于分裂点则没有。
2.gain:
可以利用get_score()来选择,其代表着某个特征的平均增益。
比如,特征x1被选了6次作为分裂的特征,每次的增益假如为Gain1,Gain2,…Gain6,那么其平均增益为(Gain1+Gain2+...Gain3)/6(Gain1+Gain2+...Gain3)/6
3.cover:
指的是特征覆盖了多少个样本。也就是特征在分裂时结点处的平均二阶导数。 我们不妨假设损失函数是mse,我们求其二阶导数,很容易得到为常数1。也就是每个样本对应的二阶导数都是1,那么这个cover指标不就是意味着,在某个特征在某个结点进行分裂时所覆盖的样本个数吗