XGBOOST的基本原理以及使用

XGBOOST的基本原理以及使用

XGBOOST的基本原理

XGBOOST的模型形式

XGBOOST是boosting方法的一种加法模型,训练的时候采用前向分布算法进行贪婪学习,每次迭代都学习一颗CART树来拟合之前t-1棵树的预测结果与训练样本真实值的残差。
XGBOOST的模型形式比较类似于GBDT算法。其基本形式为对于给定数据集
在这里插入图片描述
学习包括N棵树的加法模型,其中K是子分类器的数量,f是子分类器,F是子分类器从属的函数空间
在这里插入图片描述

XGBOOST的损失函数

XGBOOST的目标函数如下所示,其中还包含了正则项
在这里插入图片描述
对于f是决策树而不是连续函数,所以没办法用梯度下降的办法进行优化,所以我们使用贪心算法来获得最优解。
在这里插入图片描述
将上述目标函数按照泰勒级数展开
在这里插入图片描述
在这里插入图片描述
假设子分类器f的正则项有叶子节点的数量,以及叶子节点的权重的平方和两部分组成。
在这里插入图片描述
则XGBOOST最终的损失函数如下所示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上述公式对w求导后为0,得到

在这里插入图片描述

XGBOOST的学习策略

上一节最后红色的部分就是学习优化的关键,要让红色的部分月大越好。因此XGBoost中计算增益的方法入下图所示:
在这里插入图片描述
在选择分裂点的过程中,如果使用精确贪心算法,对每个特征排序完之后,枚举完所有分裂点之后。假设树的深度为H,特征数为d,则复杂度为O(Hdnlogn),其中排序为O(nlogn)。

当数据量十分庞大,无法全部存入内存中时,精确算法很慢。所以要采用近似算法,即根据特征的分布将特征分为l个桶。按照不同的桶进行切分。在将特征分为不同的桶的过程中,XGBOOST并没有采取简单的分为数方法,而是以二阶梯度h作为权重进行划分。
对特征k构造multi-set的数据集
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

XGBOOST的控制处理

XGBoost能对缺失值进行自动处理,原理就是将缺失值分别划分到左子树和右子树,分别计算增益。看哪个方向的增益比较大就把缺失值放到哪个方向。

XGBOOST的工程实现

在建树的过程中,最耗时的是寻找最优切分点,而在这个过程中,最耗时的部分是将数据排序。为了减少排序时间,XGBOOST使用了Block结构存储数据。
Block中的数据以稀疏格式CSC进行存储
Block中的特征进行预排序,并通过索引获得内存中的梯度信息
在这里插入图片描述
使用Block结构的缺点是取梯度的时候,是通过索引来获取的,而这些梯度的获取顺序是按照特征的大小排序的。这将导致非连续的内存访问,可能使CPU Cache中缓存命中率低,从而影响算法的效率。对于精确算法中,使用缓存预取。具体来说,对于每个线程分配一个连续的buffer,读取梯度信息并且存入Buffer中,然后再统计梯度信息。这种方式在大样本的情况下非常的有用。

XGBOOST的优缺点总结

优点:

  • 精度更高:GBDT 只用到一阶泰勒展开,而 XGBoost 对损失函数进行了二阶泰勒展开。XGBoost 引入二阶导一方面是为了增加精度,另一方面也是为了能够自定义损失函数,二阶泰勒展开可以近似大量损失函数
  • 灵活性更强:GBDT 以 CART 作为基分类器,XGBoost 不仅支持 CART 还支持线性分类器,(使用线性分类器的 XGBoost 相当于带 L1 和 L2 正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题))。此外,XGBoost 工具支持自定义损失函数,只需函数支持一阶和二阶求导
  • 正则化:XGBoost 在目标函数中加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、叶子节点权重的 L2 范式。正则项降低了模型的方差,使学习出来的模型更加简单,有助于防止过拟合
  • 缺失值处理:XGBoost 采用的稀疏感知算法极大的加快了节点分裂的速度
  • 可以并行化操作:块结构可以很好的支持并行计算

缺点:

  • 虽然利用预排序和近似算法可以降低寻找最佳分裂点的计算量,但在节点分裂过程中仍需要遍历数据集
  • 预排序过程的空间复杂度过高,不仅需要存储特征值,还需要存储特征对应样本的梯度统计值的索引,相当于消耗了两倍的内存

XGBOOST Python实用调参过程

XGBOOST的参数一般分为三类:

  1. 通用参数:控制宏观函数的调用
  2. Booster参数:控制每一个booster生成的参数。booster参数一般可以调控模型的效果和计算代价。所以我们说的调参,很大程度上就是调整booster参数
  3. 学习目标参数:控制训练目标的表现。我们对于问题的划分主要体现在学习目标参数上。比如我们要做回归还是分类,主要体现在目标函数上面。

通用参数:
booster:可全gbtree,和gblinear。gbtree采用树的结构,gblinear采用线性的方式
nthread:使用的线程数,一般选择-1就是使用所有线程进行计算

booster参数:
n_estimators:迭代次数
learning_rate:shrink的速率,默认是0.3
gamma:默认是0。分裂后造成
subsample:每个booster采用率,默认是1,一般选择0.5-0.8
colsample_bytree:树层面的列抽样
colsample_bylevel:每一次分裂的列抽样,默认是1
max_depth:树的最大深度
max_delta_step:限制了每棵树权重该表的最大步长。默认是0就是没有约束。通常不需要设置,但是在部分样本不平衡的情况下,由于存在二阶导,所以可以防止权重异常的增加。
lambda:L2正则项,默认0
alpha:L1正则项,默认0
scale_pos_weight:默认1,用来平衡样本的数量
学习目标参数
objective:默认reg:linear

  • reg:linear :线性回归
  • reg:logistic :逻辑回归
  • binary:logistic :二分类逻辑回归
  • binary:logitraw :二分类逻辑回归,输出为wTx
  • count:poisson :计数问题poisson回归
  • multi:softmax :设置XGBOOST使用softmax目标函数做多分类,需要设置参数num_class
  • multi:softprob :如同softmax,但输出结果为ndata*nclass的向量,其中的值是每个数据分为每个类的概率
    eval_metric: 默认是使用objective相同的参数
  • rmse:均方根误差
  • mae:绝对值误差
  • logloss:最大似然取负
  • error:二分类错误率
  • merror: 多分类错误率
  • mlogloss:多分类log损失
  • auc: auc曲线下面的面积
  • ndcg:Normalized Discounted Cumulative Gain
  • map: 平均正确率

我们先查看一下调整scale_pos_weight对输出产生的影响
class_weight=1,mean Y result=0.064
class_weight=2,mean Y result=0.100
class_weight=10,mean Y result=0.256
class_weight=20,mean Y result=0.354
我们可以看出,基本上scale_pos_weight越大,概率输出也越大。如果对概率的正确性有要求,一般不用调scale_pos_weight

调整n_estimators,和learning_rate
在这里插入图片描述
我们发现n_estimators越大效果越好,然而learning_rate则不一定,选取0.1的时候是最优的

我随后尝试调整一下样本抽样subsample和列抽样colsample_bytree,看看是否对准去率有一定的影响
在这里插入图片描述
可以看出,这两个值越大,auc值越多,但是colsample_bytree超过0.8之后边际效益就出来了,所以最终选择subsample=0.5,colsample_bytree=0.8

调整max_depth和gamma,看看剪枝是否可以提升模型的效果
在这里插入图片描述
我们发现max_depth=10的时候效果最好,gamma没有明显影响

我们试图加入L2正则项Lambda,看看正则化对模型效果是否有影响
在这里插入图片描述
最后发现正则化对模型最终区分能力AUC没有太大的影响,但会减小模型的方差。这里选取lambda=0.1即可

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值