文章目录
XGBoost
参考文章:机器学习算法(15)之Xgboost算法
1.与GBDT区别
- XGBoost的基学习器除了可以是CART(这个时候就是GBDT)也可以是线性分类器,而GBDT只能是CART。
- XGBoost在代价函数中加入了正则项,用于控制模型的复杂度(正则项的方式不同,如果你仔细点话,GBDT是一种类似于缩减系数,而XGBoost类似于L2正则化项)。
- XGBoost借鉴了随机森林的做法,支持特征抽样,不仅防止过拟合,还能减少计算
- XGBoost工具支持并行化
- 综合来说Xgboost的运算速度和算法精度都会优于GBDT
2.XGBoost树的结构
由上图可知。对于其中每一棵回归树,其模型可以写成:
其中ω为叶子节点的得分值,q(x)表示样本x对应的叶子节点。T为该树的叶子节点个数。在这里将树结构的复杂度定义为:
其中,γ为L1正则的惩罚项,λ为L2正则的惩罚项,复杂度的计算例子如下:
3.XGBoost损失函数
在XGBoost中,我们将目标函数由自身的损失函数和正则化惩罚项相加而成,如下图
对上述公式进行变形及泰勒展开可以得到
最终的目标函数只依赖于每个数据点的在误差函数上的一阶导数和二阶导数。这么写的原因很明显,由于之前的目标函数求最优解的过程中只对平方损失函数时候方便求,对于其他的损失函数变得很复杂,通过二阶泰勒展开式的变换,这样求解其他损失函数变得可行了。
之后将上面的正则化项代入可得
定义一个G和H,将目标函数对ω求偏导并令导数为0得到ω,将ω带回原式得到损失函数
以下为一个计算目标函数的例子
4.XGBoost学习策略
在XGBoost学习的过程中,采用贪心算法,每次尝试分裂一个叶节点,计算分裂后的增益然后选择增益最大的。根据XGBoost的损失函数可以得到XGBoost中计算增益的方法:
假设我们要枚举所有x < a 这样的条件,如下图所示,对于某个特定的分割a我们要计算a左边和右边的导数和。我们可以发现对于所有的a,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和GL和GR。然后用上面的公式计算每个分割方案的分数就可以了。
xgboost算法伪代码如下:
为了达到这个目标,精确贪心算法会在所有特征 (features) 上,枚举所有可能的划分(splits)。为了更高效,该算法必须首先根据特征值对数据进行排序,以有序的方式访问数据来枚举Gain公式中的结构得分 (structure score) 的梯度统计 (gradient statistics)
近似算法
以上的精确贪心算法在数据量很大的时候运行效率很低,因此有了近似算法。该算法会首先根据特征分布的百分位数 (percentiles of feature distribution),提出候选划分点 (candidate splitting points)。接着,该算法将连续型特征映射到由这些候选点划分的分桶(buckets) 中,聚合统计信息,基于该聚合统计找到在 proposal 间的最优解。
选取切分点的策略
- 全局策略:学习每棵树前,提出候选切分点;需要更多数据点,速度更快。
- 局部策略:每次分裂前,重新提出候选切分点;适合更深的树木,更准确。
实际算法
实际上XGBoost不是简单地按照样本个数进行分位,而是以二阶导数值作为权重(Weighted Quantile Sketch)。具体参考Xgboost近似分位数算法
5.XGBoost其他细节
(1) 稀疏值处理
稀疏值定义:1)缺失 2)类别one-hot编码 3)大量0值
Sparsity Aware Split Finding算法会对比将特征值为missing的样本分配到左叶子结点和右叶子结点的两种情形,还可以为缺失值或者指定的值指定默认分裂方向。
(2) 步长
Shrinkage会在每一步tree boosting时,会将新加入的weights通过一个因子η进行缩放。与随机优化中的learning rate相类似,对于用于提升模型的新增树(future trees),shrinkage可以减少每棵单独的树、以及叶子空间(leaves space)的影响,有助于防止过拟合,通常取0.1。
(3) 列采样
列采样即对特征进行采样,随机森林也用到了这种技术,有两种方式:按层随机和按列随机
- 按层随机:每次分裂一个节点的时候,对同一层内的每个结点分裂之前先随机选取一部分特征
- 桉树随机:构建树之前就随机选取特征
6.XGBoost系统设计
(1) Column Block(分块并行)
在建树的过程中,最耗时是找最优的切分点,而这个过程中,最耗时的部分是将数据排序。为了减少排序的时间,提出Block结构存储数据。
- Block中的数据以稀疏格式CSC进行存储
- Block中的特征进行排序(不对缺失值排序)— 按列切开,升序存放,分布式计算分裂点
- Block 中特征还需存储指向样本的索引,这样才能根据特征的值来取梯度。
- 一个Block中存储一个或多个特征的值
这样只需在建树前排序一次,后面结点分裂时可以直接通过索引获取梯度信息
(2) Cache-aware Access(缓存优化)
使用Block结构的一个缺点是取梯度的时候,是通过索引来获取的,而这些梯度的获取顺序是按照特征的大小顺序的。这将导致非连续的内存访问,可能使得CPU cache缓存命中率低,从而影响算法效率,缓存优化方法
- 预取数据到buffer中(非连续->连续),再统计梯度信息
- 调节块的大小
(3) Out-of-core Computation
因为XGBoost是要设计一个高效使用资源的系统,所以各种机器资源都要用上,除了CPU和内存之外,磁盘空间也可以利用来处理数据。为了实现这个功能,我们可以将数据分成多个块并将每个块储存在磁盘上。
在计算过程中,使用独立的线程将Block预提取到主内存缓冲区,这样子数据计算和磁盘读取可以同步进行,但由于IO非常耗时,所以还有2种技术来改善这种核外计算:
- Block Compression: 块压缩,并当加载到主内存时由独立线程动态解压缩;
- Block Sharding: 块分片,即将数据分片到多个磁盘,为每个磁盘分配一个线程,将数据提取到内存缓冲区,然后每次训练线程的时候交替地从每个缓冲区读取数据,有助于在多个磁盘可用时,增加读取的吞吐量。
7.参数介绍
xgboost的接口有原生接口和sklearn接口,sklearn接口和普通机器学习使用方法一样,fit函数用来训练,predict函数进行预测。原生接口首先需要将数据集转换成xgboost可用的格式,之后train方法用来训练,predict方法用来预测
参数列表如下:
参考:XGBoost-Python完全调参指南-参数解释篇, xgboost官方文档
(1)通用参数
- booster [default=gbtree]
有两种模型可以选择gbtree和gblinear。gbtree使用基于树的模型进行提升计算,gblinear使用线性模型进行提升计算。缺省值为gbtree - silent [default=0]
取0时表示打印出运行时信息,取1时表示以缄默方式运行,不打印运行时的信息。缺省值为0。建议取0,过程中的输出数据有助于理解模型以及调参。 - nthread [default to maximum number of threads available if not set]
XGBoost运行时的线程数。缺省值是当前系统可以获得的最大线程数,如果你希望以最大速度运行,建议不设置这个参数,模型将自动获得最大线程 - num_feature [set automatically by xgboost, no need to be set by user]
boosting过程中用到的特征维数,设置为特征个数。XGBoost会自动设置 - seed 随机种子
(2) 提升参数
- eta [default=0.3]
加法模型中的收缩步长,通常最后设置eta为0.01~0.2 - gamma [default=0]
叶子结点进行划分时需要损失函数减小的最小值 - max_depth [default=6]
树的最大深度。缺省值为6,树的深度越大,则对数据的拟合程度越高(过拟合程度也越高)。即该参数也是控制过拟合 - min_child_weight [default=1]
叶子结点继续划分的最小的样本权重和,调大这个参数能够控制过拟合。 - max_delta_step [default=0]
通常不需要设置这个值,但在使用logistics 回归时,若类别极度不平衡,则调整该参数可能有效果 - subsample [default=1]
用于训练模型的子样本占整个样本集合的比例。这能够防止过拟合。 - colsample_bytree [default=1]
在建立树时对特征随机采样的比例。 - colsample_bylevel[default=1]
决定每次节点划分时子样例的比例,通常不使用 - scale_pos_weight[default=0]
大于0的取值可以处理类别不平衡的情况。帮助模型更快收敛 - lambda [default=0]
L2 正则的惩罚系数,用于处理正则化部分。通常不使用,但可以用来降低过拟合 - alpha [default=0]
L1 正则的惩罚系数,当数据维度极高时可以使用,使得算法运行更快。 - lambda_bias
在偏置上的L2正则。缺省值为0(在L1上没有偏置项的正则,因为L1时偏置不重要)
(3)任务参数
- objective [ default=reg:linear ]
定义学习任务及相应的学习目标,可选的目标函数如下:- “reg:linear” –线性回归。
- “reg:logistic” –逻辑回归。
- “binary:logistic” –二分类的逻辑回归问题,输出为概率。
- “binary:logitraw” –二分类的逻辑回归问题,输出的结果为wTx。
- “count:poisson” –计数问题的poisson回归,输出结果为poisson分布。
- 在poisson回归中,max_delta_step的缺省值为0.7。(used to safeguard optimization)
- “multi:softmax” –让XGBoost采用softmax目标函数处理多分类问题,同时需要设置参数num_class(类别个数)
- “multi:softprob” –和softmax一样,但是输出的是ndata * nclass的向量,可以将该向量reshape成ndata行nclass列的矩阵。每行数据表示样本所属于每个类别的概率。
- “rank:pairwise” –set XGBoost to do ranking task by minimizing the pairwise loss
- base_score [ default=0.5 ]
the initial prediction score of all instances, global bias - eval_metric [ default according to objective ]
校验数据所需要的评价指标,可选参数如下- “rmse”: root mean square error
- “logloss”: negative log-likelihood
- “error”: Binary classification error rate. It is calculated as #(wrong cases)/#(all cases). For the predictions, the evaluation will regard the instances with prediction value larger than 0.5 as positive instances, and the others as negative instances.
- “merror”: Multiclass classification error rate. It is calculated as #(wrong cases)/#(all cases).
- “mlogloss”: Multiclass logloss
- “auc”: Area under the curve for ranking evaluation.
- “ndcg”:Normalized Discounted Cumulative Gain
- “map”:Mean average precision
- “ndcg@n”,”map@n”: n can be assigned as an integer to cut off the top positions in the lists for evaluation.
- “ndcg-“,”map-“,”ndcg@n-“,”map@n-“: In XGBoost, NDCG and MAP will evaluate the score of a list without any positive samples as 1. By adding “-” in the evaluation metric XGBoost will evaluate these score as 0 to be consistent under some conditions. training repeatively
- seed [ default=0 ]
随机数的种子。缺省值为0
可以用于产生可重复的结果(每次取一样的seed即可得到相同的随机划分)