目录
3.3.3 分布式加权直方图算法(Weighted Quantile Sketch)
1. XGBoost
XGBoost是提升方法中的一个可扩展的机器学习系统。XGBoost在许多机器学习和数据挖掘问题中产生了广泛的影响,在竞赛中也被广泛使用。
XGBoost成功的最重要因素就是它在任何场景下的可扩展性。XGBoost系统在单台机器上的运行速度比现有流行的解决方案快10倍以上,并可在分布式或内存限制设置中扩展到数十亿个示例。XGBoost的可扩展性是由于在它的系统实现中的一些创新,包括:
- 为处理稀疏数据使用了一个新颖的树学习算法;
- 理论上合理的加权分位数草图过程,使得能够在近似树学习中处理实例权重;
- 并行和分布式计算使得学习更快,从而能够更快的进行模型探索;
- 最重要的是XGBoost使用核外计算并且能够让数据科学家在台式机上处理数以亿计的示例;
- 结合这些技术使端到端系统以最少的集群资源扩展到更大的数据;
2. CART树
分类与回归树(classification and regression tree,CART)由特征选择、树的生成及剪枝组成,既可用于分类也可用于回归。CART是一棵二叉树,每一次分裂只会产生两个节点。CART树由两步组成:
- 决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;
- 决策树剪枝:用验证集数据集对已生成的树进行剪枝并选择最优子树,这时用损失函数最小作为剪枝的标准。
2.1 优缺点
- 优点:既能是分类树,又能是回归树,且二叉树的结构更为简洁。
- 缺点:是一种大样本统计方法,样本量较小时模型不稳定。
2.2 分裂依据
当CART是分类树时,采用GINI值作为节点分裂的依据;当CART是回归树时,采用样本的最小方差作为节点分裂的依据。
2.2.1 分类
GINI值的计算公式:
其中,pi表示节点中属于类i的概率。 节点越不纯,GINI值越大;反之,则GINI值越小。
2.2.2 回归
回归方差计算公式:
方差越大,表示该节点的数据越分散,预测的效果就越差。如果一个节点的所有数据都相同,那么方差就为0,此时可以很肯定地认为该节点的输出值;如果节点的数据相差很大,那么输出的值有很大的可能与实际值相差较大。
2.3总结
无论是分类树还是回归树,CART都要选择使子节点的GINI值或者回归方差最小的属性作为分裂的方案。
2.4 参考
https://blog.csdn.net/xiaohukun/article/details/78112917
3. 算法原理
如果不考虑工程实现、解决问题上的一些差异,xgboost与gbdt比较大的不同就是目标函数的定义。xgboost的目标函数如下:
红色箭头指向的l为损失函数;红色方框为正则项,包括L1、L2;红色圆圈为常数项。xgboost对目标函数执行二阶泰勒展开,提升树模型只采用一阶泰勒展开。这也是xgboost 和GBT的另一个重要区别。
对于上面的目标函数,我们接下来进行化简。
3.1 定义树的复杂度
对于f的定义做一下细化,把树拆分成结构部分q和叶子权重部分w。下图是一个具体的例子。结构函数q把输入映射到叶子的索引号上面去,而w给定了每个索引号对应的叶子分数是什么。
定义这个复杂度包含了一棵树里面节点的个数,以及每个树叶子节点上面输出分数的L2模平方。当然这不是唯一的一种定义方式,不过这一定义方式学习出的树效果一般都比较不错。下图还给出了复杂度计算的一个例子。其中方框部分,对应模型参数中的lambda ,gamma。
- 叶结点越多,则决策树越复杂。
- 每个叶结点输出值的绝对值越大,则决策树越复杂。
注:该复杂度是一个经验公式。事实上还有很多其他的定义复杂度的方式,只是这个公式效果还不错。
在这种新的定义下,我们可以把目标函数进行如下改写,其中I定义为每个叶子上面的样本集合 ,g是一阶导数,h是二阶导数
这一个目标包含了T个相互独立的单变量二次函数。我们可以定义:
最终公式可以化简为:
通过对求导等于0,可以得到:
然后把最优解代入得到:
3.2 打分函数计算示例
Obj代表了当我们指定一个树的结构的时候,我们在目标上面最多减少多少。我们可以把它叫做结构分数(structure score):
3.3 分裂结点
3.3.1 贪心法
每一次尝试去对已有的叶子加入一个分割:
对于每次扩展,我们还是要枚举所有可能的分割方案,如何高效地枚举所有的分割呢?我假设我们要枚举所有x < a 这样的条件,对于某个特定的分割a我们要计算a左边和右边的导数和。
我们可以发现对于所有的a,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和GL和GR。然后用上面的公式计算每个分割方案的分数就可以了。
观察这个目标函数,大家会发现第二个值得注意的事情就是引入分割不一定会使得情况变好,因为我们有一个引入新叶子的惩罚项。优化这个目标对应了树的剪枝, 当引入的分割带来的增益小于一个阀值的时候,我们可以剪掉这个分割。大家可以发现,当我们正式地推导目标的时候,像计算分数和剪枝这样的策略都会自然地出现,而不再是一种因为heuristic(启发式)而进行的操作了。
下面是论文中的算法:
3.3.2 近似算法
主要针对数据太大,不能直接进行计算。
近似算法寻找最优分裂点时不会枚举所有的特征值,而是对特征值进行聚合统计,然后形成若干个桶。然后仅仅将桶边界上的特征的值作为分裂点的候选,从而获取计算性能的提升。
分桶有两种模式:
1、全局模式:在算法开始时,对每个维度分桶一次,后续的分裂都依赖于该分桶并不再更新。
- 优点是:只需要计算一次,不需要重复计算。
- 缺点是:在经过多次分裂之后,叶结点的样本有可能在很多全局桶中是空的。
2、局部模式:除了在算法开始时进行分桶,每次拆分之后再重新分桶。
- 优点是:每次分桶都能保证各桶中的样本数量都是均匀的。
- 缺点是:计算量较大。
全局模式会构造更多的候选拆分点,局部模式会更适合构建更深的树。
分桶时的桶区间间隔大小是个重要的参数。区间间隔越小,则桶越多,则划分的越精细,候选的拆分点就越多。
下面是论文中的算法:
3.3.3 分布式加权直方图算法(Weighted Quantile Sketch)
4. 损失函数(指定grad、hess)
- 平方损失函数:
- 逻辑损失函数:
grad、hess推导:
4.1 参考
https://blog.csdn.net/a819825294/article/details/51206410
5. 缺失值
真实场景中,有很多可能导致产生稀疏。如:数据缺失、某个特征上出现很多 0 项、人工进行 one-hot 编码导致的大量的 0。
- 理论上,数据缺失和数值0的含义是不同的,数值 0 是有效的。
- 实际上,数值0的处理方式类似缺失值的处理方式,都视为稀疏特征。在xgboost 中,数值0的处理方式和缺失值的处理方式是统一的。这只是一个计算上的优化,用于加速对稀疏特征的处理速度。
- 对于稀疏特征,只需要对有效值进行处理,无效值则采用默认的分裂方向。注意:每个结点的默认分裂方向可能不同。
在xgboost 算法的实现中,允许对数值0进行不同的处理。可以将数值0视作缺失值,也可以将其视作有效值。如果数值0是有真实意义的,则建议将其视作有效值。
缺失值处理算法中,通过两轮遍历可以确保稀疏值位于左子树和右子树的情形。
6. 其他优化
6.1 正则化
xgboost 在学习过程中使用了如下的正则化策略来缓解过拟合:
- 通过学习率来更新模型:
- 类似于随机森林,采取随机属性选择;
6.2 计算速度提升
xgboost 在以下方面提出改进来提升计算速度:(1)预排序pre-sorted;(2)cache-aware 预取;(3)Out-of-Core 大数据集。
6.2.1 预排序pre-sorted
1、xgboost 提出column block 数据结构来降低排序时间。
- 每一个block 代表一个属性,样本在该block 中按照它在该属性的值排好序。
- 这些block 只需要在程序开始的时候计算一次,后续排序只需要线性扫描这些block 即可。
- 由于属性之间是独立的,因此在每个维度寻找划分点可以并行计算。
2、block 可以仅存放样本的索引,而不是样本本身,这样节省了大量的存储空间。
6.2.2 cache-aware 预取
1、由于在column block中,样本的顺序会被打乱,这会使得从导数数组中获取时的缓存命中率较低。因此xgboost 提出了cache-aware 预取算法,用于提升缓存命中率。
2、xgboost会以minibatch的方式累加数据,然后在后台开启一个线程来加载需要用到的导数。这里有个折中:minibatch 太大,则会引起cache miss ;太小,则并行程度较低。
6.2.3 Out-of-Core 大数据集
1、xgboost 利用硬盘来处理超过内存容量的大数据集。其中使用了下列技术:
- 使用block 压缩技术来缓解内存和硬盘的数据交换IO: 数据按列压缩,并且在硬盘到内存的传输过程中被自动解压缩。
- 数据随机分片到多个硬盘,每个硬盘对应一个预取线程,从而加大"内存-硬盘"交换数据的吞吐量。
7. 优缺点
7.1 优点
与GBDT相比,XGBoost有以下进步:
1)GBDT以传统CART作为基分类器,而XGBoost支持线性分类器,相当于引入L1和L2正则化项的逻辑回归(分类问题)和线性回归(回归问题);
2)GBDT在优化时只用到一阶导数,XGBoost对代价函数做了二阶Talor展开,引入了一阶导数和二阶导数;
3)当样本存在缺失值是,XGBoost能自动学习分裂方向;
4)XGBoost借鉴RF的做法,支持列抽样,这样不仅能防止过拟合,还能降低计算;
5)XGBoost的代价函数引入正则化项,控制了模型的复杂度,正则化项包含全部叶子节点的个数,每个叶子节点输出的score的L2模的平方和。从贝叶斯方差角度考虑,正则项降低了模型的方差,防止模型过拟合;
6)XGBoost在每次迭代之后,为叶子结点分配学习速率,降低每棵树的权重,减少每棵树的影响,为后面提供更好的学习空间;
7)XGBoost工具支持并行,但并不是tree粒度上的,而是特征粒度,决策树最耗时的步骤是对特征的值排序,XGBoost在迭代之前,先进行预排序,存为block结构,每次迭代,重复使用该结构,降低了模型的计算;block结构也为模型提供了并行可能,在进行结点的分裂时,计算每个特征的增益,选增益最大的特征进行下一步分裂,那么各个特征的增益可以开多线程进行;
8)可并行的近似直方图算法,树结点在进行分裂时,需要计算每个节点的增益,若数据量较大,对所有节点的特征进行排序,遍历的得到最优分割点,这种贪心法异常耗时,这时引进近似直方图算法,用于生成高效的分割点,即用分裂后的某种值减去分裂前的某种值,获得增益,为了限制树的增长,引入阈值,当增益大于阈值时,进行分裂;
7.2 缺点
与LightGBM相比,有以下不足:
1)XGBoost采用预排序,在迭代之前,对结点的特征做预排序,遍历选择最优分割点,数据量大时,贪心法耗时,LightGBM方法采用histogram算法,占用的内存低,数据分割的复杂度更低;
2)XGBoost采用level-wise生成决策树,同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合,但很多叶子节点的分裂增益较低,没必要进行跟进一步的分裂,这就带来了不必要的开销;LightGBM采用深度优化,leaf-wise生长策略,每次从当前叶子中选择增益最大的结点进行分裂,循环迭代,但会生长出更深的决策树,产生过拟合,因此引入了一个阈值进行限制,防止过拟合;
8. 应用场景
XGBoost可以用于解决回归、二分类和多分类问题。由于其可以并行化实现,因此也可以用于工业规模的应用中。
9. XGBoost参数
XGBoost参数地址:https://xgboost.readthedocs.io/en/latest/parameter.html
在运行 XGBoost 之前,我们必须设置三种类型的参数:常规参数、提升器参数和任务参数。
- 常规参数与我们用于提升的提升器有关,通常是树模型或线性模型;
- 提升器参数取决于你所选择的提升器;
- 学习任务参数决定了学习场景,例如回归任务可以使用不同的参数进行排序相关的任务;
- 命令行参数的行为与 xgboost 的 CLI 版本相关;
General Parameters | booster | 默认:gbtree。使用哪种提升器。可以是gbtree、gblinear或dart。 gbtree和dart使用基于树的模型;gblinear使用线性函数。 |
silent(已弃用) | 默认:0。已弃用,请使用verbosity。 | |
verbosity | 默认:1。 0 (silent), 1 (warning), 2 (info), 3 (debug)。 | |
nthread | 默认:最大线程数。用于运行XGBoost的并行线程数。 | |
disable_default_eval_metric | 默认:0。标记以禁用默认度量标准。 设置为>0表示禁用? | |
num_pbuffer | XGBoost自动设置,无需用户设置。 预测缓冲区的大小,通常设置为训练实例的数量。 缓冲区用于保存最后一次增强步骤的预测结果。 | |
num_feature | XGBoost自动设置,无需用户设置。 用于增强的特征尺寸,设置为特征的最大尺寸。 | |
Parameters for Tree Booster | eta | 默认:0.3。别名:learning_rate。 用于防止过拟合。在每个提升步骤之后,我们可以直接获得新特征的权重,并且eta缩小特征权重以使提升过程更加健壮。 范围:[0,1] |
gamma | 默认:0。别名:min_split_loss。 在树的叶节点上进行进一步分区所需的最小loss减少。gamma越大,算法越健壮。 范围:[0,∞] | |
max_depth | 默认:6。树的最大深度。 增加此值将使模型更复杂,更容易过拟合。 0表示没有限制。请注意,当grow_policy设置为depthwise时,需要限制。 | |
min_child_weight | 默认:1。叶节点所需的实例权重(hessian)的最小总和。 如果树分区步骤导致叶节点的实例权重之和小于min_child_weight,则构建过程将放弃进一步的分区。在线性回归任务中,这仅对应于每个节点中需要的最小实例数。 min_child_weight越大,算法越健壮。 | |
max_delta_step | 默认:0。允许每个叶子输出的最大增量步长。 如果该值设置为0,则表示没有约束。如果将其设置为正值,则可以帮助使更新步骤更加健壮。通常不需要此参数,但是当类非常不平衡时,它可能有助于逻辑回归。将其设置为值1-10可能有助于控制更新。 | |
subsample | 默认:1。训练集的子样本比例。 将其设置为0.5意味着XGBoost会在生长树之前随机抽取一半训练数据。这样可以防止过度拟合。下采样将在每次增强迭代中发生一次。 范围: (0,1] | |
colsample_bytree, colsample_bylevel, colsample_bynode | 默认:1。这是一组用于列的下采样的参数。 范围: (0,1]
这3个参数的作用会累积。例如,具有64个特征的组合{'colsample_bytree':0.5,'colsample_bylevel':0.5,'colsample_bynode':0.5}将在每次拆分时留下4个特征供您选择? | |
lambda | 默认:1。别名:reg_lambda。L2正则化项。 增加此值将使模型更加健壮。 | |
alpha | 默认:0。别名:reg_alpha。L1正则化项。 增加此值将使模型更加健壮。 | |
tree_method | 默认:auto。XGBoost中使用的树构造算法。 可选项:auto,exact,approx,hist,gpu_exact,gpu_hist。 分布式和外部存储器版本仅支持tree_method = approx。
| |
sketch_eps | 默认:0.03。范围:(0,1)
| |
scale_pos_weight | 默认:1。控制正负权重的平衡,对不平衡的类有用。 要考虑的典型值:sum(负实例)/ sum(正实例)。 | |
updater | 默认:grow_colmaker,prune。 逗号分隔的字符串,用于定义要运行的树更新程序序列,提供构建和修改树的模块化方法。这是一个高级参数,通常会自动设置,具体取决于其他一些参数。但是,它也可以由用户明确设置。存在以下更新程序插件:
在分布式设置中,隐式更新程序序列值将调整为grow_histmaker,prune。 | |
refresh_leaf | 默认:1。这是刷新更新程序插件的参数。
| |
process_type | 默认:default。A type of boosting process to run。 可选项:default,update。
| |
grow_policy | 默认:depthwise。控制将新节点添加到树中的方式。 仅当tree_method=hist时才支持。
| |
max_leaves | 默认:0。要添加的最大节点数。 仅在grow_policy = lossguide时相关。 | |
max_bin | 默认:256。分桶连续特征的最大离散箱数。 仅在tree_method = hist时使用。 | |
predictor | 默认:cpu_predictor。要使用的预测算法类型。 提供相同的结果,但允许使用GPU或CPU。
| |
Additional parameters for Dart Booster (booster=dart) | sample_type | 默认:uniform。采样算法的类型。
|
normalize_type | 默认:tree。归一化算法的类型。 tree:新树的每棵树都有相同的权重。
| |
rate_drop | 默认:0.0。丢弃比例。 范围:[0.0,1.0] | |
one_drop | 默认:0。启用此标志后,在丢弃期间始终会丢弃至少一颗树(允许从原始DART paper中进行Binomial-plus-one或epsilon-dropout)。 | |
skip_drop | 默认:0.0。在boosting迭代期间跳过丢弃过程的概率。
| |
Parameters for Linear Booster (booster=gblinear) | lambda | 默认:0。别名:reg_lambda。L2正则化项。 增加此值将使模型更加健壮。标准化为训练样本的数量。 |
alpha | 默认:0。别名:reg_alpha。L1正则化项。 增加此值将使模型更加健壮。标准化为训练样本的数量。 | |
updater | 默认:shotgun。线性模型拟合所使用的算法。
| |
feature_selector | 默认:cyclic。特征选择和排序方法。
| |
top_k | 默认:0。在greedy 和thrifty的特征选择器中选择的top特征的数量。值0表示使用所有特征。 | |
Parameters for Tweedie Regression (objective=reg:tweedie) | tweedie_variance_power | 默认:1.5。 控制Tweedie分布方差的参数:var(y) ~ E(y) ^ tweedie_variance_power; |
Learning Task Parameters | objective | 默认:reg:linear。
|
base_score | 默认:0.5。所有实例的初始预测分数,全局偏差。 对于足够数量的迭代,更改此值不会产生太大影响。 | |
eval_metric | 默认:通过objective来确定默认值。 验证数据的评估指标,将根据objective来分配默认指标(回归使用rmse;分类使用误差,ranking使用mAP平均平均精度)。
| |
seed | 默认:0。随机数种子。 | |
Command Line Parameters | num_round | boosting轮数 |
data | 训练数据集的路径 | |
test:data | 用于预测的测试数据集的路径 | |
save_period | 默认:0。保存模型的时间段。 设置save_period = 10意味着每10轮XGBoost将保存模型。将其设置为0表示在训练期间不保存任何模型。 | |
task | 默认:train。可选项:train, pred, eval, dump。
| |
model_in | 默认:NULL。输入模型的路径,测试、评估、转储任务所需。 如果在训练中指定,XGBoost将继续从输入模型进行训练。 | |
model_out | 默认:NULL。训练结束后输出模型的路径。 如果未指定,XGBoost将输出名称为0003.model的文件,其中0003是boosting轮数。 | |
model_dir | 默认: models/。训练期间保存模型的输出目录。 | |
fmap | 特征映射,用于转储模型。 | |
dump_format | 默认: text。可选项:text, json。模型转储文件的格式。 | |
name_dump | 默认:dump.txt。模型转储文件的名称。 | |
name_pred | 默认:pred.txt。预测文件的名称,用于pred模式。 | |
pred_margin | 默认:0。预测margin而不是转换概率。 |
参考
https://shimo.im/docs/Mh60mVwFZxEUvt0f
XGBClassifier函数
https://www.cnblogs.com/wanglei5205/p/8579244.html
XGBoost调参
https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/
XGBoost调参
https://blog.csdn.net/slx_share/article/details/82389343
XGBoost参数调优
https://blog.csdn.net/han_xiaoyang/article/details/52665396
Xgboost参数解释及调参
https://blog.csdn.net/iyuanshuo/article/details/80142730
sklearn参数解释
https://blog.csdn.net/wuxiaosi808/article/details/78036633
XGBoost的基本原理
https://blog.csdn.net/qq_24519677/article/details/81809157
Xgboost原理
https://blog.csdn.net/github_38414650/article/details/76061893
XGBoost原理
https://blog.csdn.net/g11d111/article/details/73409811
xgboost原理
https://blog.csdn.net/a819825294/article/details/51206410
XGBoost理论篇
https://blog.csdn.net/u013709270/article/details/77388009
https://zhuanlan.zhihu.com/p/25308051?utm_medium=social&utm_source=wechat_session
http://www.huaxiaozhuan.com/统计学习/chapters/7_GBT.html