LightGBM参数及分布式

Xgboost的缺点

(1)在每一次迭代的时候,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。
(2)预排序方法(pre-sorted):首先,空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如排序后的索引,为了后续快速的计算分割点),这里需要消耗训练数据两倍的内存。其次,时间上也有较大的开销,在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。最后,对cache优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。

很多 boosting 工具使用 pre-sorted based 算法进行决策树学习。这是一种简单的解决方案,但不易于优化。LightGBM 使用 histogram based 算法,将连续特征(属性)值装进离散的容器中,从而加速训练流程并减少内存使用。

LightGBM的优化

基于Histogram的决策树算法
直方图做差加速
基于直方图的稀疏特征优化
直接支持类别特征(Categorical Feature)
带深度限制的Leaf-wise的叶子生长策略
Cache命中率优化
多线程优化

基于Histogram的决策树算法:把连续的浮点特征值离散化成 k 个整数,同时构造一个宽度为 k 的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。 当然, histogram 算法也有缺点,它不能找到很精确的分割点,训练误差没有 pre-sorted 好。但从实验结果来看, histogram 算法在测试集的误差和 pre-sorted 算法差异并不是很大,甚至有时候效果更好。实际上可能决策树对于分割点的精确程度并不太敏感,而且较“粗”的分割点也自带正则化的效果。

直方图做差加速:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟节点的直方图做差得到,提升一倍速度。

基于直方图的稀疏特征优化:对于稀疏特征,只需要 O ( 2 # n o n _ z e r o _ d a t a ) O(2 * \#non\_zero\_data) 来构建直方图。

直接支持类别特征(Categorical Feature):LightGBM 可以直接输入类别特征,不需要额外的 0/1 展开,并在决策树算法上增加了类别特征的决策规则。

Level-wise分裂:过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂
Leaf-wise分裂:一种更高效的策略,每次找到当前所有叶子中,分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise相比,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM在Leaf-wise之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。

多线程优化:在特征并行时,在本地保存全部数据,避免对数据切分结果的通信。在数据并行时,使用分散规约(Reduce scatter)——把直方图合并的任务、分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。基于投票的数据并行(Parallel Voting)则进一步优化数据并行中的通信代价,使通信代价变成常数级别。
特征并行:在不同机器的各份全量的特征集合上,分别寻找最优的分割点,然后在机器间同步最优的分割点数据并行:让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。

LightGBM调参

https://lightgbm.readthedocs.io/en/latest/
https://github.com/Microsoft/LightGBM/
application:目标函数/损失函数。

boosting‘gbdt’, traditional Gradient Boosting Decision Tree;‘dart’, Dropouts meet Multiple Additive Regression Trees;‘goss’, Gradient-based One-Side Sampling;‘rf’, Random Forest。

earning_rate:学习率,默认值:0.1。最开始可以设置得大一些,如0.1。调整完其他参数之后,再将此参数调小。取值范围:0.01~0.3。

max_depth:树的深度,默认值:-1。取值范围3~8,不超过10。

num_leaves:叶子节点数,该参数树控制树模型复杂性的重要参数,默认值31。可以设置为2的n次幂,如 2 m a x _ d e p t h 2^{max\_{depth}} ,但要大于分类的类别数。理论上,可以通过设定 n u m _ l e a v e s = 2 m a x _ d e p t h num\_{leaves} = 2^{max\_{depth}} 去转变成为depth-wise tree。但这样容易过拟合,因为当这两个参数相等时,leaf-wise tree的深度要远超depth-wise tree。因此在调参时,往往会把 num_leaves的值设置得小于 2 m a x _ d e p t h 2^{max\_{depth}} 。例如当max_depth=6时,depth-wise tree可以有个好的准确率,但如果把 num_leaves 设成 127 会导致过拟合,要是把这个参数设置成 70或 80 却有可能获得比depth-wise tree有更好的准确率。事实上,当使用 leaf-wise tree时,可以忽略depth这个概念,毕竟leaves跟depth之间没有一个确切的关系。

min_data_in_leaf:一个叶子上的最少样本数,该参数是避免leaf-wise tree算法过拟合的重要参数,默认值20。在分析大型数据集时,该值取值在 [ , ] [数百,数千] 较为合适。该值受到训练集数量和num_leaves这两个值的影响。把该参数设的更大、能避免生长出过深的树,但也要避免欠拟合。

min_sum_hessian_in_leaf:使一个结点分裂的最小海森值之和,即叶子节点的最小权重和。

feature_fraction:特征列随机采样比例,默认值:1.0。通常在0.5-0.9之间调节。
bagging_fraction:不进行重采样的情况下,样本数据随机采样比例,默认值:1.0。通常在0.5-0.9之间调节。

bagging_freq:bagging的频次,默认值:0。0表示禁用bagging,正整数表示每k轮迭代,进行一次 bagging,通常取值3-5。

lambda_l1:对参数的L1正则化限制。
lambda_l2:对参数的L2正则化限制。

min_split_to_gain:分裂的最小增益,默认值:0.1。

early_stopping_round:早停轮次。如果一个验证数据的某个度量,在最近的early_stopping_round 次中没有提高,模型将停止训练。

max_cat_group:在 group 边界上找到分割点;当类别数量很多时,找分割点很容易过拟合。

drop_rate:Dart 的丢弃率。
skip_drop:Dart 的跳过丢弃步骤的概率。
max_drop:Dart 每次迭代最大丢弃数量。

max_bin:表示 feature 将存入的 bin 的最大数量。LightGBM 将根据 max_bin 自动压缩内存。 例如, 如果 maxbin=255, 那么 LightGBM 将使用 uint8t 的特性值。
categorical_feature:如果 categorical_features = 0,1,2, 则列 0,1,2是 categorical 变量。
ignore_column:与 categorical_features 类似,只不过不是将特定的列视为categorical,而是完全忽略。
save_binary:这个参数为 true 时,则数据集被保存为二进制文件,下次读数据时速度会变快。

https://lightgbm.readthedocs.io/en/latest/Parameters-Tuning.html

在这里插入图片描述

对于非平衡数据集:可以param[‘is_unbalance’]='true’