数据竞赛中XGBOOST等集成学习算法


数据竞赛中XGBOOST等集成学习算法


Boosting Adboost RandomForest GBDT XGBOOST

sklearn 集成方法

集成方法的目的是结合一些基于某些算法训练得到的基学习器来改进其泛化能力

和鲁棒性

Boosting 分类器属于集成学习模型,它基本思想是把成百上千个分类准确率较低的

弱学习器组合起来,成为一个准确率很高的模型。这个模型会不断地迭代,每次迭代就生成

一颗新的树。对于如何在每一步生成合理的树。它在生成每一棵树的时候采用梯度下降的思

想,以之前生成的所有树为基础,向着最小化给定目标函数的方向多走一步。在合理的参数

设置下,我们往往要生成一定数量的树才能达到令人满意的准确率。

集成学习按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习器

之间存在强依赖关系,另一类是个体学习器之间不存在强依赖关系。前者的代表算法就是是

boosting系列算法。在 boosting系列算法中, Adaboost是最著名的算法之一。Adaboost

既可以用作分类,也可以用作回归。

Boosting 算法的工作机制是首先从训练集用初始权重训练出一个弱学习器 1,根据弱

学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器 1 学习误差率高的训练

样本点的权重变高,使得这些误差率高的点在后面的弱学习器 2 中得到更多的重视。然后

基于调整权重后的训练集来训练弱学习器 2.,如此重复进行,直到弱学习器数达到事先指

定的数目 T,最终将这 T 个弱学习器通过集合策略进行整合,得到最终的强学习器。

Adaboost 是模型为加法模型,学习算法为前向分步学习算法,损失函数为指数函数

的分类问题。模型为加法模型好理解,我们的最终的强分类器是若干个弱分类器加权平均

而得到的。前向分步学习算法也好理解,我们的算法是通过一轮轮的弱学习器学习,利用

前一个弱学习器的结果来更新后一个弱学习器的训练集权重。Adaboost 损失函数为指数

函数:

Yi 取-1 和 1.


详情可见:http://www.cnblogs.com/pinard/p/6133937.html


梯度提升树(GBDT)

GBDT 有很多简称,有 GBT(Gradient Boosting Tree), GTB(Gradient Tree Boosting ),

GBRT(Gradient Boosting Regression Tree), MART(Multiple Additive Regression

Tree),其实都是指的同一种算法,本文统一简称 GBDT。

GBDT 也是集成学习 Boosting 家族的成员,但是却和传统的 Adaboost 有很大的不

同。回顾下 Adaboost,我们是利用前一轮迭代弱学习器的误差率来更新训练集的权

重,这样一轮轮的迭代下去。GBDT 也是迭代,使用了前向分布算法,但是弱学习器限定

了只能使用 CART 回归树模型,同时迭代思路和 Adaboost 也有所不同。

在 GBDT 的迭代中,假设我们前一轮迭代得到的强学习器是 ft−1(x), 损失函数是

L(y,ft−1(x)), 我们本轮迭代的目标是找到一个 CART 回归树模型的弱学习器 ht(x),让本轮


的损失损失 L(y,ft(x)=L(y,ft−1(x)+ht(x))最小。也就是说,本轮迭代找到决策树,要让样本

的损失尽量变得更小。


详情可见:http://www.cnblogs.com/pinard/p/6140514.html

scikit-learn 梯度提升树(GBDT)调参小结

scikit-learn 中,GradientBoostingClassifier 为 GBDT 的分类, 而 GradientBoostingRegressor

为 GBDT 的回归类。两者的参数类型完全相同,当然有些参数比如损失函数 loss 的可选择项并不相同。

这些参数中,类似于 Adaboost,我们把重要参数分为两类,第一类是 Boosting 框架的重要参数,第二

类是弱学习器即 CART 回归树的重要参数。

详情可见:http://www.cnblogs.com/pinard/p/6143927.html

Lightgbm: https://github.com/Microsoft/LightGBM

这块待后续看过论文再做。

XGBOOST

XGBoost、LightGBM的详细对比介绍:

链接:https://www.cnblogs.com/infaraway/p/7890558.html

bagging

基本思想

独立的训练一些基学习器(一般倾向于强大而复杂的模型比如完全生长的决策树),然后综合

他们的预测结果,通常集成模型的效果会优于基学习器,因为模型的方差有所降低。

常见变体(按照样本采样方式的不同划分)

• Pasting:直接从样本集里随机抽取的到训练样本子集

• Bagging:自助采样(有放回的抽样)得到训练子集

• Random Subspaces:列采样,按照特征进行样本子集的切分

• Random Patches:同时进行行采样、列采样得到样本子集

sklearn-bagging

学习器

• BaggingClassifier

• BaggingRegressor

参数

• 可自定义基学习器

• max_samples,max_features 控制样本子集的大小

• bootstrap,bootstrap_features 控制是否使用自主采样法

o 当使用自助采样法时,可以设置参数 oob_score=True 来通过包外估计来

估计模型的泛化误差(也就不需要进行交叉验证了)

Note:方差的产生主要是不同的样本训练得到的学习器对于同一组测试集做出分类、预测结

果的波动性,究其原因是基学习器可能学到了所供学习的训练样本中的局部特征或者说是拟

合了部分噪声数据,这样综合不同的学习器的结果,采取多数表决(分类)或者平均(回归)的

方法可以有效改善这一状况。

sklearn-forests of randomized trees

学习器

• RandomForest: 采取自主采样法构造多个基学习器,并且在学习基学习器时,不是

使用全部的特征来选择最优切分点,而是先随机选取一个特征子集随后在特征子集

里挑选最优特征进行切分;这种做法会使得各个基学习器的偏差略微提升,但在整

体上降低了集成模型的方差,所以会得到整体上不错的模型

o RandomForestClassifier


o RandomForestRegressor

Notes:

• 不同于原始的模型实现(让各个基学习器对样本的分类进行投票),sklearn 里随机森

林的实现是通过将各个基学习器的预测概率值取平均来得到最终分类

• 随机森林的行采样(bagging)和列采样(feature bagging)都是为了减小模型之间的相

关性使基学习器变得不同从而减小集成模型的方差

• Extra-Trees(extremely randomized trees):相较于 rf 进一步增强了随机性,rf 是

对各个基学习器随机挑选了部分特征来做维特征子集从中挑选最佳的特征切分,而

Extra-Trees 更进一步,在特征子集里挑选最佳特征时不是选择最有区分度的特征

值,而是随机选择这一划分的阈值(该阈值在子特征集里的特征对应的采样后的样本

取值范围里随机选取),【对于特征子集的特征,对于有放回抽样得到的样本,在特征

i 中随机选取阈值,根据阈值的划分将表现好的特征作为划分特征】而不同的随机阈

值下的特征中表现最佳的作为划分特征,这样其实增强了随机性,更进一步整大了

基学习器的偏差但降低了整体的方差

o ExtraTreesClassifier

o ExtraTreesRegressor

调参

• 最重要的两个参数

o n_estimators:森林中树的数量,初始越多越好,但是会增加训练时间,到

达一定数量后模型的表现不会再有显著的提升

o max_features:各个基学习器进行切分时随机挑选的特征子集中的特征数

目,数目越小模型整体的方差会越小,但是单模型的偏差也会上升,经验性

的设置回归问题的 max_features 为整体特征数目,而分类问题则设为整体

特征数目开方的结果

• 其他参数

o max_depth:树的最大深度,经验性的设置为 None(即不设限,完全生长)

o min_samples_split,节点最小分割的样本数,表示当前树节点还可以被进

一步切割的含有的最少样本数;经验性的设置为 1,原因同上

o bootstrap,rf 里默认是 True 也就是采取自助采样,而 Extra-Trees 则是

默认关闭的,是用整个数据集的样本,当 bootstrap 开启时,同样可以设置

oob_score 为 True 进行包外估计测试模型的泛化能力

o n_jobs,并行化,可以在机器的多个核上并行的构造树以及计算预测值,不

过受限于通信成本,可能效率并不会说分为 k 个线程就得到 k 倍的提升,不

过整体而言相对需要构造大量的树或者构建一棵复杂的树而言还是高效的

o criterion:切分策略:gini 或者 entropy,默认是 gini,与树相关

o min_impurity_split–>min_impurity_decrease:用来进行早停止的参数,

判断树是否进一步分支,原先是比较不纯度是否仍高于某一阈值,0.19 后

是判断不纯度的降低是否超过某一阈值

o warm_start:若设为 True 则可以再次使用训练好的模型并向其中添加更多

的基学习器

o class_weight:设置数据集中不同类别样本的权重,默认为 None,也就是所

有类别的样本权重均为 1,数据类型为字典或者字典列表(多类别)

o balanced:根据数据集中的类别的占比来按照比例进行权重设置

n_samples/(n_classes*np.bincount(y))


o balanced_subsamples:类似 balanced,不过权重是根据自助采样

后的样本来计算

方法

• predict(X):返回输入样本的预测类别,返回类别为各个树预测概率均值的最大值

• predict_log_proba(X):

• predict_proba(X):返回输入样本 X 属于某一类别的概率,通过计算随机森林中各树

对于输入样本的平均预测概率得到,每棵树输出的概率由叶节点中类别的占比得到

• score(X,y):返回预测的平均准确率

特征选择

特征重要性评估:一棵树中的特征的排序(比如深度)可以用来作为特征相对重要性的一个评

估,居于树顶端的特征相对而言对于最终样本的划分贡献最大(经过该特征划分所涉及的样

本比重最大),这样可以通过对比各个特征所划分的样本比重的一个期望值来评估特征的相

对重要性,而在随机森林中,通过对于不同树的特征的期望取一个平均可以减小评估结果的

方差,以供特征选择;在 sklearn 中这些评估最后被保存在训练好的模型的参数 feature

importances 里,是各个特征的重要性值经过归一化的结果,越高代表特征越匹配预测函

Notes:

• 此外 sklearn 还有一种 RandomTreesEmbedding 的实现,不是很清楚有何特殊用

随机森林与 KNN

• 相似之处:均属于所谓的权重近邻策略(weighted neighborhoods schemes):指的

是,模型通过训练集来通过输入样本的近邻样本点对输入样本作出预测,通过一个

带权重的函数关系

XGBoost

过拟合

XGBoost 里可以使用两种方式防止过拟合

• 直接控制模型复杂度

o max_depth,基学习器的深度,增加该值会使基学习器变得更加复杂,荣易过拟

合,设为 0 表示不设限制,对于 depth-wise 的基学习器学习方法需要控制深度

o min_child_weight,子节点所需的样本权重和(hessian)的最小阈值,若是基学

习器切分后得到的叶节点中样本权重和低于该阈值则不会进一步切分,在线性模

型中该值就对应每个节点的最小样本数,该值越大模型的学习约保守,同样用于

防止模型过拟合

o gamma,叶节点进一步切分的最小损失下降的阈值(超过该值才进一步切分),越

大则模型学习越保守,用来控制基学习器的复杂度(有点 LightGBM 里的 leaf-

wise 切分的意味)

• 给模型训练增加随机性使其对噪声数据更加鲁棒


o 行采样:subsample

o 列采样:colsample_bytree

o 步长:eta 即 shrinkage

数据类别分布不均

对于 XGBoost 来说同样是两种方式

• 若只关注预测的排序表现(auc)

o 调整正负样本的权重,使用 scale_pos_weight

o 使用 auc 作为评价指标

• 若关注预测出正确的概率值,这种情况下不能调整数据集的权重,可以通过设置参数

max_delta_step 为一个有限值比如 1 来加速模型训练的收敛

调参

一般参数

主要用于设置基学习器的类型

• 设置基学习器 booster

o 基于树的模型

o gbtree

o dart

o 线性模型

o gblinear

• 线程数 nthread,设置并行的线程数,默认是最大线程数

基学习器参数

在基学习器确定后,根据基学习器来设置的一些个性化的参数

• eta,步长、学习率,每一轮 boosting 训练后可以得到新特征的权重,可以通过 eta 来

适量缩小权重,使模型的学习过程更加保守一点,以防止过拟合


• gamma,叶节点进一步切分的最小损失下降的阈值(超过该值才进一步切分),越大则

模型学习越保守,用来控制基学习器的复杂度(有点 LightGBM 里的 leaf-wise 切分的

意味)

• max_depth,基学习器的深度,增加该值会使基学习器变得更加复杂,荣易过拟合,

设为 0 表示不设限制,对于 depth-wise 的基学习器学习方法需要控制深度

• min_child_weight,子节点所需的样本权重和(hessian)的最小阈值,若是基学习器

切分后得到的叶节点中样本权重和低于该阈值则不会进一步切分,在线性模型中该值

就对应每个节点的最小样本数,该值越大模型的学习约保守,同样用于防止模型过拟

• max_delta_step,树的权重的最大估计值,设为 0 则表示不设限,设为整数会是模型

学习相对保守,一般该参数不必设置,但是对于基学习器是 LR 时,在针对样本分布

极为不均的情况控制其值在 1~10 之间可以控制模型的更新

• 行采样:subsample,基学习器使用样本的比重

• 列采样:

o colsample_bytree,用于每棵树划分的特征比重

o colsample_bylevel,用于每层划分的特征比重

• 显式正则化,增加该值是模型学习更为保守

o L1:alpha

o L2:lambda

• tree_method,树的构建方法,准确的说应该是切分点的选择算法,包括原始的贪

心、近似贪心、直方图算法(可见 LightGBM 这里并不是一个区别)

o auto,启发式地选择分割方法,近似贪心或者贪心

o exact,原始的贪心算法,既针对每一个特征值切分一次

o approx,近似的贪心算法选取某些分位点进行切分,使用 sketching 和 histogram

o hist,直方图优化的贪心算法,对应的参数有 grow_policy,max_bin

o gpu_exact

o gpu_hist

• scale_pos_weight,针对数据集类别分布不均,典型的值可设置为

sum(negativecases)sum(positivecases)sum(negativecases)sum(positivecases)


• grow_policy,控制树的生长方式,目前只有当树的构建方法 tree_method 设置为

hist 时才可以使用所谓的 leaf-wise 生长方式

o depthwise,按照离根节点最近的节点进行分裂

o lossguide,优先分裂损失变化大的节点,对应的一个参数还有 max_leaves,

表示可增加的最大的节点数

• max_bin,同样针对直方图算法 tree_method 设置为 hist 时用来控制将连续特征离

散化为多个直方图的直方图数目

• predictor,选择使用 GPU 或者 CPU

o cpu_predictor

o gpu_predictor

任务参数

根据任务、目的设置的参数,比如回归任务与排序任务的目的是不同的

• objective,训练目标,分类还是回归

o reg:linear,线性回归

o reg:logistic,逻辑回归

o binary:logistic,使用 LR 二分类,输出概率

o binary:logitraw,使用 LR 二分类,但在进行 logistic 转换之前直接输出分类得

o count:poisson,泊松回归

o multi:softmax,使用 softmax 进行多分类,需要设置类别数 num_class

o multi:softprob

o rank:pairwise,进行排序任务,最小化 pairwise 损失

o reg:gamma,gamma 回归

o reg:tweedie,tweedie 回归

• 评价指标 eval_metric,默认根据目标函数设置,针对验证集,默认情况下,最小均

方误差用于回归,错分用于分类,平均精确率用于排序等,可以同时使用多个评估指

标,在 python 里使用列表来放置

o 均方误差 rmse


o 平均绝对值误差 mae

o 对数损失 logloss,负的对数似然

o 错误率 error,根据 0.5 作为阈值判断的错分率

o 自定义阈值错分率 error@t

o 多分类错分率 merror

o 多分类对数损失 mlogloss

o auc 主要用来排序

o ndcg,normalized discounted cumulative gain 及其他的一些针对泊松回归等问题

的评价指标

命令行参数

• num_round 迭代次数,也对应基学习器数目

• task 当前对模型的任务,包括

o 训练 train

o 预测 pred

o 评估/验证 eval

o 导出模型 dump

• 导入导出模型的路径 model_in 和 model_out

• fmap,feature map 用来导出模型

LightGBM

特点

效率和内存上的提升

直方图算法,LightGBM 提供一种数据类型的封装相对 Numpy,Pandas,Array 等数据对象

而言节省了内存的使用,原因在于他只需要保存离散的直方图,LightGBM 里默认的训练

决策树时使用直方图算法,XGBoost 里现在也提供了这一选项,不过默认的方法是对特征

预排序,直方图算法是一种牺牲了一定的切分准确性而换取训练速度以及节省内存空间消

耗的算法


• 在训练决策树计算切分点的增益时,预排序需要对每个样本的切分位置计算,所以时

间复杂度是 O(#data)而 LightGBM 则是计算将样本离散化为直方图后的直方图切割位

置的增益即可,时间复杂度为 O(#bins),时间效率上大大提高了(初始构造直方图是需

要一次 O(#data)的时间复杂度,不过这里只涉及到加和操作)

• 直方图做差进一步提高效率,计算某一节点的叶节点的直方图可以通过将该节点的直

方图与另一子节点的直方图做差得到,所以每次分裂只需计算分裂后样本数较少的子

节点的直方图然后通过做差的方式获得另一个子节点的直方图,进一步提高效率

• 节省内存

o 将连续数据离散化为直方图的形式,对于数据量较小的情形可以使用小型的数据

类型来保存训练数据

o 不必像预排序一样保留额外的对特征值进行预排序的信息

• 减少了并行训练的通信代价

稀疏特征优化

对稀疏特征构建直方图时的时间复杂度为 O(2*#非零数据)

准确率上的优化

LEAF-WISE(BEST-FIRST)树生长策略

相对于 level-wise 的生长策略而言,这种策略每次都是选取当前损失下降最多的叶节点进

行分割使得整体模型的损失下降得更多,但是容易过拟合(特别当数据量较小的时候),可

以通过设置参数 max_depth 来控制树身防止出现过拟合

Notes:XGBoost 现在两种方式都是支持的

直接支持类别特征

对于类别类型特征我们原始的做法是进行独热编码,但是这种做法对于基于树的模型而言

不是很好,对于基数较大的类别特征,可能会生成非常不平衡的树并且需要一颗很深的树

才能达到较好的准确率;比较好的做法是将类别特征划分为两个子集,直接划分方法众多

(2^(k-1)-1),对于回归树而言有一种较高效的方法只需要 O(klogk)的时间复杂度,基本思

想是对类别按照与目标标签的相关性进行重排序,具体一点是对于保存了类别特征的直方

图根据其累计值(sum_gradient/sum_hessian)重排序,在排序好的直方图上选取最佳切分位

网络通信优化

使用 collective communication 算法替代了 point-to-point communication 算法提升了效率

并行学习优化

特征并行

特征并行是为了将寻找决策树的最佳切分点这一过程并行化


• 传统做法

o 对数据列采样,即不同的机器上保留不同的特征子集

o 各个机器上的 worker 根据所分配的特征子集寻找到局部的最优切分点(特征、阈

值)

o 互相通信来从局部最佳切分点里得到最佳切分点

o 拥有最佳切分点的 worker 执行切分操作,然后将切分结果传送给其他的 worker

o 其他的 worker 根据接收到的数据来切分数据

o 传统做法的缺点

o 计算量太大,并没有提升切分的效率,时间复杂度为 O(#data)(因为每个

worker 持有所有行,需要处理全部的记录),当数据量较大时特征并行并不能

提升速度

o 切分结果的通信代价,大约为 O(#data/8)(若一个数据样本为 1bit)

• LightGBM 的做法

让每个机器保留整个完整的数据集(并不是经过列采样的数据),这样就不必在切分后

传输切分结果数据,因为每个机器已经持有完整的数据集

o 各个机器上的 worker 根据所分配的特征子集寻找到局部的最优切分点(特征、阈

值)

o 互相通信来从局部最佳切分点里得到最佳切分点

o 执行最优切分操作

Notes:典型的空间换时间,差别就是减少了传输切分结果的步骤,节省了这里的通信消耗

数据并行

上述特征并行的方法并没有根本解决寻找切分点的计算效率问题,当记录数过大时需要考

虑数据并行的方法

• 传统做法

o 行采样,对数据进行横向切分

o worker 使用分配到的局部数据构建局部的直方图

o 合并局部直方图得到全局的直方图

o 对全局直方图寻找最优切分点,然后进行切分


o 缺点:通信代价过高,若使用 point-to-point 的通信算法,每个机器的通信代价

时间复杂度为 O(#machine*#feature*#bin),若使用 collective 通信算法则通信代价

为 O(2*#feature*#bin)

• LightGBM 的做法(依然是降低通信代价)

o 不同于合并所有的局部直方图获得全局的直方图,LightGBM 通过 Reduce

Scatter 方法来合并不同 worker 的无交叉的不同特征的直方图,这样找到该直方

图的局部最优切分点,最后同步到全局最优切分点

o 基于直方图做差的方法,在通信的过程中可以只传输某一叶节点的直方图,而对

于其邻居可通过做差的方式得到

o 通信的时间复杂度为 O(0.5*#feature*#bin)

并行投票

进一步减小了数据并行中的通信代价,通过两轮的投票来减小特征直方图中的通信消耗

其他特点

直接支持类别(标称)特征

LightGBM 可以直接用类别特征进行训练,不必预先进行独热编码,速度会提升不少,参

数设置 categorical_feature 来指定数据中的类别特征列

早停止

sklearn-GBDT,XGBoost,LightGBM 都支持早停止,不过在细节上略有不同

• sklearn-GBDT 中的 early stopping 是用来控制基学习器的生长的:通过参数

min_impurity_split(原始)以及 min_impurity_decrease 来实现,前者的是根

据节点的不纯度是否高于阈值,若不是则停止增长树,作为叶节点;后者则根据分裂

不纯度下降值是否超过某一阈值来决定是否分裂(此外这里的 early stopping 似乎与

XGBoost 里显示设置的 early stopping 不同,这里是控制树的切分生长,而 XGBoost

则是控制基学习器的数目)

• XGBoost 和 LightGBM 里的 early_stopping 则都是用来控制基学习器的数目的

o 两者都可以使用多组评价指标,但是不同之处在于 XGBoost 会根据指标列表中

的最后一项指标控制模型的早停止,而 LightGBM 则会受到所有的评估指标的影

o 在使用 early stopping 控制迭代次数后,模型直接返回的是最后一轮迭代的学习

器不一定是最佳学习器,而在做出预测时可以设置参数选择某一轮的学习器作出

预测

o XGBoost 里保存了三种状态的学习器,分别是 bst.best_score,

bst.best_iteration, bst.best_ntree_limit,官方的建议是在做预


测时设置为 bst.best_ntree_limit,实际使用时感觉

bst.best_iteration 和 bst.best_ntree_limit 的表现上区别不大

o LightGBM 则仅提供了 bst.best_iteration 这一种方式

实践上

• 内置 cv

• 支持带权重的数据输入

• 可以保留模型

• DART

• L1/L2 回归

• 保存模型进行进一步训练

• 多组验证集

支持的任务

• 回归任务

• 分类(二分类、多分类)

• 排序

支持的评价指标 METRIC

• 绝对值误差 l1

• 平方误差 l2

• 均方误差 l2_root

• 对数损失 binary_logloss,multi_logloss

• 分类误差率 binary_error,multi_error

• auc

• ndcg

• 多分类对数损失

• 多分类分类误差率


调参

核心参数

• 叶节点数 num_leaves,与模型复杂度直接相关(leaf-wise)

• 任务目标

o 回归 regression,对应的损失函数如下

o regression_l1,加了 l1 正则的回归,等同于绝对值误差

o regression_l2,等同于均方误差

o huber,Huber Loss

o fair,Fair Loss

o poisson,泊松回归

o 分类

o binary,二分类

o multiclass,多分类

o 排序

o lambdarank

• 模型

o boosting

o gbdt,传统的梯度提升决策树

o rf,随机森林

o dart,Dropouts meet Multiple Additive Regression Trees

o goss,Gradient-based One-Side Sampling

• 迭代次数 num_iterations,对于多分类问题,LightGBM 会构建

num_class*num_iterations 的树

• 学习率/步长 learning_rate,即 shrinkage

• 树的训练方式 tree_learner,主要用来控制树是否并行化训练


o serial,单机的树学习器

o feature,特征并行的树学习器

o data,数据并行的树学习器

• 线程数 num_threads

• 设备 device,使用 cpu 还是 gpu

o cpu

o gpu

训练控制参数

防止过拟合

• 树的最大深度 max_depth,主要用来避免模型的过拟合,设为负数值则表明不限制

• 叶节点的最少样本数 min_data_in_leaf

• 叶节点的最小海森值之和 min_sum_hessian_in_leaf

• 列采样 feature_fraction,每棵树的特征子集占比,设置在 0~1 之间,可以加快训

练速度,避免过拟合

• 行采样 bagging_fraction,不进行重采样的随机选取部分样本数据,此外需要设置

参数 bagging_freq 来作为采样的频率,即多少轮迭代做一次 bagging;

• 早停止 early_stopping_roung,在某一验证数据的某一验证指标当前最后一轮迭

代没有提升时停止迭代

• 正则化

o lambda_l1

o lambda_l2

• 切分的最小收益 min_gain_to_split

IO 参数

直方图相关

• 最大直方图数 max_bin,特征值装载的最大直方图数目,一般较小的直方图数目会降

低训练的准确性但会提升整体的表现,处理过拟合

• 直方图中最少样本数 min_data_in_bin,设置每个直方图中样本数的最小值,同样

防止过拟合


特征相关

• 是否预排序 is_pre_partition

• 是否稀疏 is_sparse

• 类别特征列 categorical_feature,声明类别特征对应的列(通过索引标记),仅支持

int 类型

• 声明权重列 weight,指定一列作为权重列

内存相关

• 分阶段加载数据 two_round,一般 LightGBM 将数据载入内存进行处理,这样会提升

数据的加载速度,但是对于数据量较大时会造成内存溢出,所以此时需要分阶段载入

• 保存数据为二进制 save_binary,将数据文件导出为二进制文件,下次加载数据时就

会更快一些

缺失值

• 是否处理缺失值 use_missing

• 是否将 0 值作为缺失值 zeros_as_missing

目标参数

• sigmoid,sigmoid 函数中的参数,用于二分类和排序任务

• scale_pos_weight,设置正例在二分类任务中的样本占比

• 初始化为均值 boost_from_average,调整初始的分数为标签的均值,加速模型训练

的收敛速度,仅用于回归任务

• 样本类别是否不平衡 is_unbalance

• num_class,用于多分类

调参小结

LEAF-WISE

• num_leaves,对于 leaf-wise 的模型而言该参数是用来控制模型复杂度的主要参数,

理论上可以通过设置 num_leaves=2^(max_depth)来设置该参数值,实际是不可取

的,因为在节点数目相同的前提下,对于 leaf-wise 的模型会倾向于生成深度更深的

模型,如果生硬的设置为 2^(max_depth)可能会造成模型的过拟合,一般设置的值小

于 2^(max_depth),


• min_data_in_leaf,在设置了叶节点数后,该值会对模型复杂度造成影响,若设的

较大则树不会生长的很深,但可能造成模型的欠拟合

• max_depth

效率

• bagging_fraction 和 bagging_freq,使用 bagging 进行行采样提升训练速度(减小

了数据集)

• feature_fraction,列采样

• 设置较少的直方图数目,max_bin

• 保存数据为二进制文件以便于未来训练时能快速加载,save_binary

• 通过并行训练来提速

准确率

• 设置较大的直方图数目 max_bin,当然这样会牺牲训练速度

• 使用较小的学习率 learning_rate,这样会增加迭代次数

• 设置较大的叶节点数 num_leaves,可能造成模型过拟合

• 使用较大的训练数据

• 尝试 dart 模型

过拟合

• 设置较少的直方图数目,max_bin

• 设置较小的叶节点数 num_leaves

• 设置参数 min_data_in_leaf 和 min_sum__hessian_in_leaf

• 使用 bagging 进行行采样 bagging_fraction 和 bagging_freq

• feature_fraction,列采样

• 使用较大的训练数据

• 正则化

o lambda_l1

o lambda_l2


o 切分的最小收益 min_gain_to_split

• 控制树深 max_depth

总结

GBDT vs. XGBoost vs. LightGBM(论文层面)

GBDT vs. XGBoost

• GBDT 无显式正则化

• GBDT 仅使用了目标函数一阶泰勒展开,而 XGBoost 使用了二阶的泰勒展开值

o 为什么二阶展开?

o 一说加快收敛速度

o 另外有说本身模型训练的学习率 shrinkage 可以通过二阶导数做一个逼近,

而原始的 GBDT 没有计算这个,所以一般是通过预设的超参数 eta 人为指

• XGBoost 加入了列采样

• XGBoost 对缺失值的处理

• XGBoost 通过预排序的方法来实现特征并行,提高模型训练效率

• XGBoost 支持分布式计算

XGBoost vs. LightGBM

• 树的切分策略不同

o XGBoost 是 level-wise 而 LightGBM 是 leaf-wise

• 实现并行的方式不同

o XGBoost 是通过预排序的方式

o LightGBM 则是通过直方图算法

• LightGBM 直接支持类别特征,对类别特征不必进行独热编码处理

sklearn GBDT vs. XGBoost vs. LightGBM(实现层面)


实际在库的实现层面原始论文里的很多区别是不存在的,差异更多在一些工程上的性能优

sklearn GBDT vs. XGBoost

• 正则化方式不同

o sklearn GBDT 中仅仅通过学习率来做一个正则化(影响到基学习器的数目),此外

gbdt 里的 early stopping 也达到了一个正则化的效果,对应的主要参数是

min_impurity_split 即控制了判断叶节点是否进一步切分的不纯度的阈值,

若超过该阈值则可以进一步切分,否则不行,故而控制了树的深度即控制了基学

习器的复杂度

o XGBoost 除了学习率以外还有显示的设置正则化项 l1,l2 以及对应论文里的叶节

点数(对应参数 gamma)以及节点权重和(参数 min_child_weight)来控制模型复杂

• GBDT 仅使用了目标函数一阶泰勒展开,而 XGBoost 使用了二阶的泰勒展开值

• XGBoost 自有一套对缺失值的处理方法

• early-stopping 意义不同

o sklearn GBDT 中控制基学习器进一步切分、生长

o XGBoost 控制基学习器的数目

• 特征重要性的判断标准

o sklearn GBDT 是根据树的节点特征对应的深度来判断

o XGBoost 则有三种方法(get_score)

o weight:特征用来作为切分特征的次数

o gain:使用特征进行切分的平均增益

o cover:各个树中该特征平均覆盖情况(根据样本?)

• 树的切分算法

o XGBoost 存在三种切分方法,

o 原始的贪心算法(每个特征值切分)

o 近似贪心(分位点切分)(使得对于大量的特征取值尤其是连续变量时

XGBoost 会比 sklearn-gbdt 快很多)

o 直方图算法


• XGBoost 支持 level-wise 和 leaf-wise 两种树的生长方式

• XGBoost 支持 GPU

• XGBoost 支持多种评价标准、支持多种任务(回归、分类、排序)

XGBoost vs. LightGBM

XGBoost 目前已经实现了 LightGBM 之前不同的一些方法比如直方图算法,两者的区别更

多的在与 LightGBM 优化通信的的一些处理上

o LightGBM 直接支持类别特征,可以不必预先进行独热编码,提高效率

(categorical_feature)

o 优化通信代价

o 特征并行

o 数据并行

o point to point communication–>collective communication

o 使用多项评价指标同时评价时两者的早停止策略不同,XGBoost 是根据评价指标

列表中的最后一项来作为停止标准,而 LightGBM 则受到所有评价指标的影响


分享到:


相關文章: