xgboost原理及参数分析
XGBOOST
三要素:损失函数/弱评估器/综合集成结果
思想上的两点优化
1.树容易过拟合(剪枝),要注意精确性与复杂度模型复杂度之间的平衡,也是经验风险与结构风险之间的平衡
以前的方法:先关注经验风险,再去剪枝,关注结构风险
XGBOOST:为损失函数加入结构风险项,构成目标函数(评估器集合决定)/使用新的不纯度衡量指标(单个评估器如何分枝)
2.提升建树速度
1. 使用估计贪婪算法、平行学习、分位数草图算法等方法构建了适用于大数据的全新建树流程
2. 使用感知缓存访问技术与核外计算技术,提升算法在硬件上的运算性能
3. 引入Dropout技术,为整体建树流程增加更多随机性、让算法适应更大数据
3.保留了GBDT的一些方法
比如:1.弱评估器(回归器)的输出类型与集成算法输出类型(分类器)不一致
2.拟合负梯度,且当损失函数是0.5倍MSE时,拟合残差
3.抽样思想
特别注意,它是一个独立算法库,不是sklearn.ensemble里的
如何区分分类还是回归:看损失函数
参数图!!!!!!!!!!!!!!!!!!!!!!11
1.迭代过程/目标函数
max_delta_step:每次迭代时被允许的最大 𝜂𝑓𝑘(𝑥𝑖)。如果样本极度不均衡,那可以尝试在这个参数中设置1~10左右的数。其它时候不要用
目标函数:针对每一棵树的,而不是针对一个样本或整个算法(因为要控制树的复杂度)
𝑇表示当前第𝑘棵树上的叶子总量,𝑤𝑗则代表当前树上第𝑗片叶子的叶子权重(leaf weights)
2.弱评估器结构 :评估器有哪些,如果是决策树具体是什么决策树
参数booster:可以输入"gbtree": 遵循XGBoost规则的CART树
"gblinear":线性模型,当弱评估器类型是"gblinear"而损失函数是MSE时,表示使用xgboost方法来集成线性回归。当弱评估器类型是"gblinear"而损失函数是交叉熵损失时,则代表使用xgboost来集成逻辑回归。(除非过拟合才用这个)
或者"dart":抛弃提升树,在建树过程中会随机抛弃一些树的结果,可以更好地防止过拟合。在数据量巨大、过拟合容易产生时,DART树经常被使用。
3.dart树:
可以设置抛弃率,每次抛弃n颗树,注意每轮抛弃的树下一轮迭代又回来了
参数rate_drop:每一轮迭代时抛弃树的比例(实操中只调这个)
参数skip_drop:每一轮迭代时可以不执行dropout的概率
参数sample_type:抛弃时所使用的抽样方法。填写字符串"uniform":表示均匀不放回抽样。填写字符串"weighted":表示按照每棵树的权重进行有权重的不放回抽样。
参数normalize_type:增加新树时,赋予新树的权重。填写字符串"tree",表示新生成的树的权重等于所有被抛弃的树的权重的均值。填写字符串"forest",表示新生成的树的权重等于所有被抛弃的树的权重之和。 算法默认为"tree",当我们的dropout比例较大,且我们相信希望给与后续树更大的权重时,会选择"forest"模式。
注意:这个树的权重其实指的是整棵树上所有叶子权重之和
DART树最明显的缺点就是:
用于微调模型的一些树可能被抛弃,微调可能失效
由于存在随机性,模型可能变得不稳定,因此提前停止等功能可能也会变得不稳定
由于要随机抛弃一些树的结果,在工程上来说就无法使用每一轮之前计算出的 𝐻𝑘−1
,而必须重新对选中的树结果进行加权求和,可能导致模型迭代变得略微缓慢
4.弱评估器的训练数据
分枝评分:结构分数(Structure Score)与结构分数增益(Gain of Structure Score),公式为节点𝑗上所有样本的一阶导数之和的平方/(节点𝑗上所有样本的二阶导数之和+𝜆)
5.剪枝与提前停止
剪枝:
参数min_child_weight:可以被广义理解为任意节点上所允许的样本量(样本权重)。
参数gamma:目标函数中叶子数量 T 前的系数,同时也是允许分枝的最低结构分数增益。当分枝时结构增益不足gamma中设置的值,该节点被剪枝。
参数lambda和alpha:正则化系数,同时也位于结构分数中间接影响树的生长和分枝。
提前停止:
样本抽样:
参数subsample:对样本进行抽样的比例
参数sampling_method:对样本进行抽样时所使用的抽样方法
特征抽样:
对于GBDT、随机森林来说,特征抽样是发生在每一次建树之前。但对XGBoost来说,特征的抽样可以发生在建树之前(由colsample_bytree控制)、生长出新的一层树之前(由colsample_bylevel控制)、或者每个节点分枝之前(由colsample_bynode控制)。
全特征集 >= 建树所用的特征子集 >= 建立每一层所用的特征子集 >= 每个节点分枝时所使用的特征子集
6.其它功能性参数
参数early_stopping_rounds:位于xgb.train方法当中。如果规定的评估指标不能连续early_stopping_rounds次迭代提升,那就触发提前停止。
参数evals:位于xgb.train方法当中,用于规定训练当中所使用的评估指标,一般都与损失函数保持一致,也可选择与损失函数不同的指标。该指标也用于提前停止。
参数verbosity:用于打印训练流程和训练结果的参数。不是用。
参数scale_pos_weight:调节样本不均衡问题,类似于sklearn中的class_weight,仅在算法执行分类任务时有效。参数scale_pos_weight的值时负样本比正样本的比例,默认为1,
参数nthread:允许并行的最大线程数
参数重要性图!!!!!!!!!
注意:
1.在随机森林中影响力巨大的max_depth在XGBoost中默认值为6,比GBDT中的调参空间略大,但还是没有太多的空间,因此影响力不足。
2.在GBDT中影响力巨大的max_features对标XGBoost中的colsample_by*系列参数,原则上来说影响力应该非常大,但由于三个参数共同作用,调参难度较高,在只有1个参数作用时效果略逊于max_features。
3.精剪枝参数往往不会对模型有太大的影响,但在XGBoost当中,min_child_weight与结构分数的计算略微相关,因此有时候会展现出较大的影响力。故而将这个精剪枝参数设置为4星参数。
4.类似于objective这样影响整体学习能力的参数一般都有较大的影响力,但XGBoost当中每种任务可选的损失函数不多,因此一般损失函数不在调参范围之内,故认为该参数的影响力不明显。
5.XGBoost的初始化分数只能是数字,因此当迭代次数足够多、数据量足够大时,起点的影响会越来越小。因此我们一般不会对base_score进行调参。
如何选择参数:5星参数+当算力足够/优化算法运行较快的时候,我们可以考虑将大部分时候具有影响力的参数(4星)也都加入参数空间。一般来说,只要样本量足够,我们还是愿意尝试subsample以及max_depth,如果算力充足,我们还可以加入obejctive这样或许会有效的参数。
需要说明的是,一般不会同时使用三个colsample_by*参数、更不会同时调试三个colsample_by*参数。首先,参数colsample_bylevel较为不稳定,不容易把握,因此当训练资源充足时,会同时调整colsample_bytree和colsample_bynode。如果计算资源不足,或者优先考虑节约计算时间,则会先选择其中一个参数、尝试将特征量控制在一定范围内来建树,并观察模型的结果。在这三个参数中,使用bynode在分枝前随机,比使用bytree建树前随机更能带来多样性、更能对抗过拟合,但同时也可能严重地伤害模型的学习能力。在这里,我将尝试同时使用两个参数进行调参。
确认参数空间:
对于有界的参数(比如colsample_bynode,subsamples等),或者有固定选项的参数(比如booster,objective),无需确认参数空间。
对取值较小的参数(例如学习率eta,一般树模型的min_impurity_decrease等),或者通常会向下调整的参数(比如max_depth),一般是围绕默认值向两边展开构建参数空间。
对于取值可大可小,且原则上可取到无穷值的参数(num_boost_round,gamma、lambda、min_child_weight等),一般需要绘制学习曲线进行提前探索,或者也可以设置广而稀的参数空间,来一步步缩小范围。