参考文章:
https://blog.csdn.net/weiyongle1996/article/details/78360873
https://www.cnblogs.com/wj-1314/p/9402324.html
1、简介
如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧。XGBoost算法现在已经成为很多数据工程师的重要武器。它是一种十分精致的算法,可以处理各种不规则的数据。
构造一个使用XGBoost的模型十分简单。但是,提高这个模型的表现就有些困难(至少我觉得十分纠结)。这个算法使用了好几个参数。所以为了提高模型的表现,参数的调整十分必要。在解决实际问题的时候,有些问题是很难回答的——你需要调整哪些参数?这些参数要调到什么值,才能达到理想的输出?
这篇文章最适合刚刚接触XGBoost的人阅读。在这篇文章中,我们会学到参数调优的技巧,以及XGboost相关的一些有用的知识。以及,我们会用Python在一个数据集上实践一下这个算法。
2、内容列表
1、XGBoost的优势
2、理解XGBoost的参数
3、调参示例
3、XGBoost的优势
XGBoost算法可以给预测模型带来能力的提升。当我对它的表现有更多了解的时候,当我对它的高准确率背后的原理有更多了解的时候,我发现它具有很多优势:
| 序号 | 优势 |
描述
|
|---|---|---|
| 1 | 正则化 | 1、标准GBM的实现没有像XGBoost这样的正则化步骤。正则化对减少过拟合也是有帮助的。 2、实际上,XGBoost以“正则化提升(regularized boosting)”技术而闻名。 |
| 2 | 并行处理 | 1、 XGBoost可以实现并行处理,相比GBM有了速度的飞跃。 2、不过,众所周知,Boosting算法是顺序处理的,它怎么可能并行呢?每一课树的构造都依赖于前一棵树,那具体是什么让我们能用多核处理器去构造一个树呢?我希望你理解了这句话的意思。 3、XGBoost 也支持Hadoop实现。 |
| 3 | 高度的灵活性 | 1、XGBoost 允许用户定义自定义优化目标和评价标准 2、它对模型增加了一个全新的维度,所以我们的处理不会受到任何限制。 |
| 4 | 缺失值处理 | 1、XGBoost内置处理缺失值的规则。 2、用户需要提供一个和其它样本不同的值,然后把它作为一个参数传进去,以此来作为缺失值的取值。XGBoost在不同节点遇到缺失值时采用不同的处理方法,并且会学习未来遇到缺失值时的处理方法。 |
| 5 | 剪枝性 | 1、当分裂时遇到一个负损失时,GBM会停止分裂。因此GBM实际上是一个贪心算法。 2、XGBoost会一直分裂到指定的最大深度(max_depth),然后回过头来剪枝。如果某个节点之后不再有正值,它会去除这个分裂。 3、这种做法的优点,当一个负损失(如-2)后面有个正损失(如+10)的时候,就显现出来了。GBM会在-2处停下来,因为它遇到了一个负值。但是XGBoost会继续分裂,然后发现这两个分裂综合起来会得到+8,因此会保留这两个分裂。 |
| 6 | 内置交叉验证 | 1、XGBoost允许在每一轮boosting迭代中使用交叉验证。因此,可以方便地获得最优boosting迭代次数。 2、而GBM使用网格搜索,只能检测有限个值。 |
| 7 | 在已有的模型基础上继续 | 1、XGBoost可以在上一轮的结果上继续训练。这个特性在某些特定的应用上是一个巨大的优势。 2、sklearn中的GBM的实现也有这个功能,两种算法在这一点上是一致的。 |
4、XGBoost接口类型
Xgboost有两大类接口:Xgboost原生接口 和sklearn接口,并且Xgboost能够实现分类回归两种任务。下面对这四种情况做以解析
| 分类 |
|
|---|---|
| 基于Xgboost原生接口的分类 | from xgboost import XGBClassifier booster:gbtree 常用的booster有树模型(tree)和线性模型(linear model) objective:multi:softmax 目标函数,softmax目标函数处理多分类问题 num_class:3 当目标函数是处理多分类问题,需要设置参数类别个数 gamma:0.1 叶子节点进一步分区所需的最小损失减少,越大越保守,一般设0.1 ,0.2 max_depth:6 树深度 reg_lambda:2 L2 正则的惩罚系数。通常不使用,但可以用来降低过拟合 subsample:0.7 训练模型的子样本占整个样本集合的比例 colsample_bytree:0.7 对特征随机采样的比例 min_child_weight:3 孩子节点中最小的样本权重和 slient:1 取0时表示打印出运行时信息,取1时表示不打印运行时的信息 learning_rate:0.1 为了防止过拟合,更新过程中用到的收缩步长。在每次提升计算之后,算法会直接获得新特征的权重。 eta通过缩减特征的权重使提升计算过程更加保守 seed:1000 随机数的种子 |
| 基于Xgboost原生接口的回归 | from xgboost import XGBRegressor booster:gblinear 常用的booster有树模型(tree)和线性模型(linear model) objective:multi:softmax 目标函数,softmax目标函数处理多分类问题 num_class:3 当目标函数是处理多分类问题,需要设置参数类别个数 gamma:0.1 叶子节点进一步分区所需的最小损失减少,越大越保守,一般设0.1 ,0.2 max_depth:6 树深度 reg_lambda:2 L2 正则的惩罚系数。通常不使用,但可以用来降低过拟合 subsample:0.7 训练模型的子样本占整个样本集合的比例 colsample_bytree:0.7 对特征随机采样的比例 min_child_weight:3 孩子节点中最小的样本权重和 slient:1 取0时表示打印出运行时信息,取1时表示不打印运行时的信息 learning_rate:0.1 为了防止过拟合,更新过程中用到的收缩步长。在每次提升计算之后,算法会直接获得新特征的权重。 eta通过缩减特征的权重使提升计算过程更加保守 seed:1000 随机数的种子 |
| Xgboost使用sklearn接口的分类(推荐) | from xgboost.sklearn import XGBClassifier silent=0, 设置成1则没有运行信息输出,最好是设置为0,是否在运行升级时打印消息 nthread = 4 CPU 线程数 默认最大 learning_rate=0.3 如同学习率 min_child_weight = 1 这个参数默认为1,是每个叶子里面h的和至少是多少,对正负样本不均衡时的0-1分类而言,假设h在0.01附近,min_child_weight为1 意味着叶子节点中最少需要包含100个样本。这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易过拟合 max_depth=6 构建树的深度,越大越容易过拟合 gamma = 0 树的叶子节点上做进一步分区所需的最小损失减少,越大越保守,一般0.1 0.2这样子 subsample=1 随机采样训练样本,训练实例的子采样比 max_delta_step=0 最大增量步长,我们允许每个树的权重估计 colsample_bytree=1 生成树时进行的列采样 reg_lambda=1 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合 reg_alpha=0 L1正则项参数 scale_pos_weight =1 如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛,平衡正负权重 objective = ‘multi:softmax’ 多分类问题,指定学习任务和响应的学习目标 # num_class = 10 类别数,多分类与multisoftmax并用 n_estimators=100 树的个数 seed = 1000 随机种子 eval_metric =‘auc’ |
| 基于Scikit-learn接口的回归 | from xgboost.sklearn import XGBRegressor 参数与回归一致 |
5、XGBoost的参数
XGBoost的作者把所有的参数分成了三类:
在运行Xgboost之前,必须设置三种类型参数:general parameters,booster parameters和task parameters:
1、通用参数(General Parameters):该参数控制在提升(boosting)过程中使用哪种booster,常用的booster有树模型(tree)和线性模型(linear model)。
2、Booster参数(Booster Parameters):控制每一步的booster(tree/regression)。
3、学习目标参数(Task Parameters):控制训练目标的表现。控制学习的场景,例如在回归问题中会使用不同的参数控制排序
在这里我会类比GBM来讲解,所以作为一种基础知识,强烈推荐先阅读GBM调参。
尽管有两种booster可供选择,这里只介绍tree booster,因为它的表现远远胜过linear booster,所以linear booster很少用到。
如果你之前用的是Scikit-learn,你可能不太熟悉这些参数。但是有个好消息,python的XGBoost模块有一个sklearn包,XGBClassifier。这个包中的参数是按sklearn风格命名的。会改变的函数名是:
1、eta -> learning_rate
2、lambda -> reg_lambda
3、alpha -> reg_alpha
5.1 通用参数
| 参数 |
|
|---|---|
| booster | 有两种模型可以选择gbtree和gblinear。 gbtree使用基于树的模型进行提升计算 gblinear使用线性模型进行提升计算 [默认gbtree] |
| silent | 当这个参数值为1时,静默模式开启,不会输出任何信息。 一般这个参数就保持默认的0,因为这样能帮我们更好地理解模型 [默认0] |
| nthreadx 最大可能的线程数 |
这个参数用来进行多线程控制,应当输入系统的核数。 如果你希望使用CPU全部的核,那就不要输入这个参数,算法会自动检测它。 [默认0] |
| boosting 特征维数 |
过程中用到的特征维数,设置为特征个数。XGBoost会自动设置,不需要手工设置 |
| num_pbuffer | XGBoost会自动设置,不需要手工设置 |
5.2 tree booster参数
| 参数 |
|
|---|---|
| learning_rate 学习速率 |
和GBM中的 learning rate 参数类似,通过减少每一步的权重,可以提高模型的鲁棒性。[默认0.3],典型值为0.01-0.2。 |
| min_child_weight 决定最小叶子节点样本权重和 |
和GBM的 min_child_leaf 参数类似,但不完全一样。XGBoost的这个参数是最小样本权重的和,而GBM参数是最小样本总数。 这个参数用于避免过拟合。当它的值较大时,可以避免模型学习到局部的特殊样本。但是如果这个值过高,会导致欠拟合。这个参数需要使用CV来调整。 为了防止过拟合,更新过程中用到的收缩步长,在每次提升计算之后,算法会直接获得新特征的权重。 eta通过缩减特征的权重使提升计算过程更加保守。缺省值为 1,通常最后设置eta为0.01~0.2 |
| max_depth 树的最大深度 |
这个值也是用来避免过拟合的。树的深度越大,则对数据的拟合程度越高(过拟合程度也越高),即模型会学到更具体更局部的样本。 需要使用CV函数来进行调优。典型值:3-10 |
| gamma | 在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。 Gamma指定了节点分裂所需的最小损失函数下降值。这个参数的值越大,算法越保守。 模型在默认情况下,对于一个节点的划分只有在其损失函数得到结果大于0的情况下才进行,而gamma 给定了所需的最低损失函数的值。 gamma值使得算法更conservation,且其值依赖于损失函数 ,在模型中应该进行调参。调整在0-1之间。 |
| max_delta_step 限制每棵树权重改变的最大步长 |
如果取值为0,那么意味着无限制。如果取为正数,则其使得xgboost更新过程更加保守。 通常不需要设置这个值,但在使用logistics 回归时,若类别极度不平衡,则调整该参数可能有效果。 默认值为0。 |
| subsample 练模型的子样本占整个样本集合的比例 |
用于训练模型的子样本占整个样本集合的比例。如果设置为0.5则意味着XGBoost将随机的从整个样本集合中抽取出50%的子样本建立树模型,这能够防止过拟合,但是,如果这个值设置得过小,它可能会导致欠拟合。 取值范围为:(0,1],默认值为1,典型值:0.5-1 |
| colsample_bytree 特征随机采样的比例 |
在建立树时对特征随机采样的比例。 缺省值为1取值范围:(0,1] ,典型值:0.5-1 |
| colsample_bylevel 决定每次节点划分时子样例的比例 |
通常不使用,因为subsample和colsample_bytree已经可以起到相同的作用了 |
| scale_pos_weight | 在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。默认1 |
| reg_lambda L2 正则的惩罚系数 |
用于处理XGBoost的正则化部分。通常不使用,但可以用来降低过拟合,默认1 |
| reg_alpha 权重的L1正则化项 |
当数据维度极高时可以使用,使得算法运行更快,默认0 |
| lambda_bias 在偏置上的L2正则 |
。缺省值为0(在L1上没有偏置项的正则,因为L1时偏置不重要) |
5.3 学习目标参数
| 参数 |
|
|---|---|
| objective 定义学习任务及相应的学习目标 |
default=reg:linear 。 可选的目标函数如下: reg:linear: –线性回归。 reg:logistic :逻辑回归。 binary:logistic:二分类的逻辑回归问题,返回预测的概率(不是类别)。 binary:logitraw:二分类的逻辑回归问题,输出的结果为wTx。 count:poisson:计数问题的poisson回归,输出结果为poisson分布。在poisson回归中,max_delta_step的缺省值为0.7。 multi:softmax:让XGBoost采用softmax目标函数处理多分类问题,返回预测的类别(不是概率),同时需要设置参数num_class(类别个数)。 multi:softprob:和softmax一样,但是输出的是ndata * nclass的向量,可以将该向量reshape成ndata行nclass列的矩阵。每行数据表示样本所属于每个类别的概率。即返回的是每个数据属于各个类别的概率。 |
| base_score 最小的预测分数 |
default=0.5。 若设置为0.5,则预测概率>0.5,均预测为真 |
| eval_metric 校验数据的评价指标 |
不同的目标函数将会有缺省的评价指标,用户可以添加多种评价指标,对于Python用户,要以list传递参数对给程序,而不是map参数,list参数不会覆盖’eval_metric’ 对于回归问题,默认值是rmse,对于分类问题,默认值是error 典型值有: ♦ rmse 均方根误差() ♦ mae 平均绝对误差() ♦ logloss 负对数似然函数值 ♦ error 二分类错误率(阈值为0.5) ♦ merror 多分类错误率 ♦ mlogloss 多分类logloss损失函数 ♦ auc 曲线下面积 |
| seed 随机数的种子 |
设置它可以复现随机数据的结果,也可以用于调整参数 默认0 |
6、参数调优的一般方法
我们会使用和GBM中相似的方法。需要进行如下步骤:
1、选择较高的学习速率(learning rate)。一般情况下,学习速率的值为0.1。但是,对于不同的问题,理想的学习速率有时候会在0.05到0.3之间波动。选择对应于此学习速率的理想决策树数量。XGBoost有一个很有用的函数“cv”,这个函数可以在每一次迭代中使用交叉验证,并返回理想的决策树数量。
2、对于给定的学习速率和决策树数量,进行决策树特定参数调优(max_depth, min_child_weight, gamma, subsample, colsample_bytree)。在确定一棵树的过程中,我们可以选择不同的参数,待会儿我会举例说明。
3、xgboost的正则化参数的调优。(lambda, alpha)。这些参数可以降低模型的复杂度,从而提高模型的表现。
降低学习速率,确定理想参数。
第一步:确定学习速率和tree_based参数调优的估计器数目
为了确定Boosting参数,我们要先给其他参数一个初始值。咱们先按照如下方法取值:
1,max_depth = 5:这个参数的取值最好在3-10之间,我选的起始值为5,但是你可以选择其他的值。起始值在4-6之间都是不错的选择。
2,min_child_weight = 1 :这里选择了一个比较小的值,因为这是一个极不平衡的分类问题。因此,某些叶子节点下的值会比较小。
3,gamma = 0 :起始值也可以选择其它比较小的值,在0.1到0.2之间就可以,这个参数后继也是要调整的。
4,subsample,colsample_bytree = 0.8 这个是最常见的初始值了。典型值的范围在0.5-0.9之间。
5,scale_pos_weight =1 这个值时因为类别十分不平衡。
注意,上面这些参数的值知识一个初始的估计值,后继需要调优。这里把学习速率就设成默认的0.1。然后用Xgboost中的cv函数来确定最佳的决策树数量。
from xgboost as XGBClassifier
param = {
'n_estimators': range(50,301,50)}#这里只确定了决策树个数,没有确定学习效率
gsearch = GridSearchCV(estimator = XGBClassifier(learning_rate =0.1,#学习效率
max_depth=6,#树深度
min_child_weight=1,#最小叶子节点样本权重
gamma=0,#节点分类所需的最小损失函数下降值
subsample=0.8,#控制每棵树的随机采样比例
colsample_bytree=0.8,#特征随机采样比例
objective= 'binary:logistic',#二分类的逻辑回归问题,返回预测的概率
scale_pos_weight=1,#;在各类别样本十分不平衡时,把这个参数设定为一个正值,可以使算法更快收敛。默认1
seed=27

最低0.47元/天 解锁文章
2234

被折叠的 条评论
为什么被折叠?



