2018-01-12
机器学习-集成学习-理解与应用XGBoost
• 分类:
ml
• 标签:
ml
XGBoost–eXtreme Gradient Boosting
发展历程
XGBoost是从决策树一步步发展而来的。
- 决策树 ⟶ 对样本重抽样,然后多个树平均 ⟶ Tree bagging
- Tree bagging ⟶ 再同时对特征进行随机挑选 ⟶ 随机森林
- 随机森林 ⟶ 对随机森林中的树进行加权平均,而非简单平均 ⟶ Boosing (Adaboost, GradientBoost)
- boosting ⟶ 对boosting中的树进行正则化 ⟶ XGBoosting
基础
在运行XGBoost之前,必须设置三种类型成熟:general parameters,booster parameters和task parameters:
- General parameters:参数控制在提升(boosting)过程中使用哪种booster,常用的booster有树模型(tree)和线性模型(linear model)。
- Booster parameters:这取决于使用哪种booster。
- Task parameters:控制学习的场景,例如在回归问题中会使用不同的参数控制排序。
- 除了以上参数还可能有其它参数,在命令行中使用
XGBoost使用的基学习器是CART
- 决策规则与决策树的一样
- 每个叶子节点上都包含了一个权重,也有人叫做分数
二阶泰勒展开
pass
决策树的复杂度
Shrinkage与列抽样
- Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(补充:传统GBDT的实现也有学习速率)
- 列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。
缺失值处理
对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。
- XGBoost内置处理缺失值的规则。
- 用户需要提供一个和其它样本不同的值,然后把它作为一个参数传进去,以此来作为缺失值的取值。XGBoost在不同节点遇到缺失值时采用不同的处理方法,并且会学习未来遇到缺失值时的处理方法。
近似直方图算法
可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。
交叉验证
- XGBoost允许在每一轮boosting迭代中使用交叉验证。因此,可以方便地获得最优boosting迭代次数。
GridSearchCV
1 | from xgboost import XGBClassifier |
并行化
xgboost工具支持并行。
boosting不是一种串行的结构吗?怎么并行的?注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。
机器学习算法中GBDT和XGBOOST的区别有哪些?
首先XGBoost是Gradient Boosting的一种高效系统实现,并不是一种单一算法。XGBoost里面的基学习器除了用tree(gbtree),也可用线性分类器(gblinear)。而GBDT则特指梯度提升决策树算法。XGBoost相对于普通gbm的实现,可能具有以下的一些优势:
- 显式地将树模型的复杂度作为正则项加在优化目标
- 公式推导里用到了二阶导数信息,而普通的GBDT只用到一阶
- 允许使用column(feature) sampling来防止过拟合,借鉴了Random Forest的思想,sklearn里的gbm好像也有类似实现
- 实现了一种分裂节点寻找的近似算法,用于加速和减小内存消耗
- 节点分裂算法能自动利用特征的稀疏性
- data事先排好序并以block的形式存储,利于并行计算
- cache-aware, out-of-core computation
- 支持分布式计算可以运行在MPI,YARN上,得益于底层支持容错的分布式通信框架rabit。
LR+XGBoost
pass
Xgboost和LightGBM部分参数对照
Xgboost | LightGbm |
---|---|
booster(default=gbtree) | boosting(default=gbdt) |
eta(default=0.3) | learning_rate(default=0.1) |
max_depth(default=6) | num_leaves(default=31) |
min_child_weight(default=1) | min_sum_hessian_in_leaf(1e-3) |
gamma(default=0) | min_gain_to_split(default=20) |
subsample(default=1) | bagging_fraction(default=1.0) |
colsample_bytree(default=1) | feature_fraction( default=1.0) |
alpha(default=0) | lambda_l1(default=0) |
lambda(default=1) | lambda_l2(default=0) |
objective( default=reg:linear) | application(default=regression) |
eval_metric(default according to objective) | metric |
nthread | num_threads |
- 使用num_leaves
因为LightGBM使用的是leaf-wise的算法,因此在调节树的复杂程度时,使用的是num_leaves而不是max_depth。
大致换算关系:num_leaves = 2^(max_depth)。它的值的设置应该小于2^(max_depth),否则可能会导致过拟合。
对于非平衡数据集:可以param[‘is_unbalance’]=’true’
Bagging参数:bagging_fraction+bagging_freq(必须同时设置)、feature_fraction。bagging_fraction可以使bagging的更快的运行出结果,feature_fraction设置在每次迭代中使用特征的比例。
min_data_in_leaf:这也是一个比较重要的参数,调大它的值可以防止过拟合,它的值通常设置的比较大。
max_bin:调小max_bin的值可以提高模型训练速度,调大它的值和调大num_leaves起到的效果类似。
参数速查:
xgb | lgb | xgb.sklearn | lgb.sklearn |
---|---|---|---|
booster=’gbtree’ | boosting=’gbdt’ | booster=’gbtree’ | boosting_type=’gbdt’ |
objective=’binary:logistic’ | application=’binary’ | objective=’binary:logistic’ | objective=’binary’ |
max_depth=7 | num_leaves=2**7 | max_depth=7 | num_leaves=2**7 |
eta=0.1 | learning_rate=0.1 | learning_rate=0.1 | learning_rate=0.1 |
num_boost_round=10 | num_boost_round=10 | n_estimators=10 | n_estimators=10 |
gamma=0 | min_split_gain=0.0 | gamma=0 | min_split_gain=0.0 |
min_child_weight=5 | min_child_weight=5 | min_child_weight=5 | min_child_weight=5 |
subsample=1 | bagging_fraction=1 | subsample=1.0 | subsample=1.0 |
colsample_bytree=1.0 | feature_fraction=1 | colsample_bytree=1.0 | colsample_bytree=1.0 |
alpha=0 | lambda_l1=0 | reg_alpha=0.0 | reg_alpha=0.0 |
lambda=1 | lambda_l2=0 | reg_lambda=1 | reg_lambda=0.0 |
scale_pos_weight=1 | scale_pos_weight=1 | scale_pos_weight=1 | scale_pos_weight=1 |
seed | bagging_seedfeature_fraction_seed | random_state=888 | random_state=888 |
nthread | num_threads | n_jobs=4 | n_jobs=4 |
evals | valid_sets | eval_set | eval_set |
eval_metric | metric | eval_metric | eval_metric |
early_stopping_rounds | early_stopping_rounds | early_stopping_rounds | early_stopping_rounds |
verbose_eval | verbose_eval | verbose | verbose |
XGBoost还需要做特征工程吗?
特征工程是个很广的概念,包括特征筛选、特征变换、特征合成、特征提取等等。对于XGBoost,它能够很好地做到特征选择,所以这一点不用我们去操心太多。至于特征变换(离散化、归一化、标准化、取log等等),我们也不需要做太多,因为XGBoost是基于决策树,决策树自然能够解决这些。相比较来说,线性模型则需要做离散化或者取log处理。因为XGBoost(树类模型)不依赖于线性假设。但是对于分类特征,XGBoost需要对其进行独热编码,否则无法训练模型。XGBoost也可以免于一部分特征合成的工作,比如线性回归中的交互项a:b,在树类模型中都可以自动完成。但是对于加法a+b,减法a-b,除法a-b这类合成的特征,则需要手动完成。
绝大部分模型都无法自动完成的一步就是特征提取。很多nlp的问题或者图象的问题,没有现成的特征,你需要自己去提取这些特征,这些是我们需要人工完成的。
综上来说,XGBoost的确比线性模型要省去很多特征工程的步骤。但是特征工程依然是非常必要的。
附录——参数
1 | max_depth : int |
参考
- http://wepon.me/2016/05/07/XGBoost%E6%B5%85%E5%85%A5%E6%B5%85%E5%87%BA/
- http://blog.csdn.net/weiyongle1996/article/details/78446244
- https://www.jianshu.com/p/8346d4f80ab0
- http://chuan92.com/2016/03/19/XGBoost-and-gbdt
- http://sofasofa.io/forum_main_post.php?postid=1001161
dzzxjl