XGBoost简介

本文据此对XGBoost的原理做简单的介绍...



XGBoost[1]是2014年2月诞生的专注于梯度提升算法的机器学习函数库,此函数库因其优良的学习效果以及高效的训练速度而获得广泛的关注。仅在2015年,在Kaggle[2]竞赛中获胜的29个算法中,有17个使用了XGBoost库,而作为对比,近年大热的深度神经网络方法,这一数据则是11个。在KDDCup 2015 [3]竞赛中,排名前十的队伍全部使用了XGBoost库。

XGBoost不仅学习效果很好,而且速度也很快,相比梯度提升算法在另一个常用机器学习库scikit-learn中的实现,XGBoost的性能经常有十倍以上的提升。

在今年的KDD会议上,XGBoost的作者陈天奇将这一库函数所涉及到的理论推导和加速方法整理为论文发表出来[4],本文据此对其原理做简单的介绍。尽管这是一个机器学习方面的函数库,但其中有大量通用的加速方法,也值得我们学习。
1.   GBDT算法原理
XGBoost实现的是一种通用的Tree Boosting算法,此算法的一个代表为梯度提升决策树(Gradient Boosting Decision Tree, GBDT),又名MART(Multiple Additive Regression Tree)。

GBDT的原理是,首先使用训练集和样本真值(即标准答案)训练一棵树,然后使用这棵树预测训练集,得到每个样本的预测值,由于预测值与真值存在偏差,所以二者相减可以得到“残差”。接下来训练第二棵树,此时不再使用真值,而是使用残差作为标准答案。两棵树训练完成后,可以再次得到每个样本的残差,然后进一步训练第三棵树,以此类推。树的总棵数可以人为指定,也可以监控某些指标(例如验证集上的误差)来停止训练。

在预测新样本时,每棵树都会有一个输出值,将这些输出值相加,即得到样本最终的预测值。

使用两棵树来预测一个人是否喜欢电脑游戏的示意图如下,小男孩和老人的预测值为两棵树预测值的加和。
2.   XGBoost所做的改进


2.1.  损失函数从平方损失推广到二阶可导的损失

GBDT的核心在于后面的树拟合的是前面预测值的残差,这样可以一步步逼近真值。然而,之所以拟合残差可以逼近到真值,是因为使用了平方损失作为损失函数,公式如下
如果换成是其他损失函数,使用残差将不再能够保证逼近真值。XGBoost的方法是,将损失函数做泰勒展开到第二阶,使用前两阶作为改进的残差。可以证明,传统GBDT使用的残差是泰勒展开到一阶的结果,因此,GBDT是XGBoost的一个特例。注意:此处省略了严格的推导,详情请参阅陈天奇的论文。

2.2.  加入了正则化项

正则化方法是数学中用来解决不适定问题的一种方法,后来被引入机器学习领域。通俗的讲,正则化是为了限制模型的复杂度的。模型越复杂,就越有可能“记住”训练数据,导致训练误差达到很低,而测试误差却很高,也就是发生了“过拟合”。在机器学习领域,正则化项大多以惩罚函数的形式存在于目标函数中,也就是在训练时,不仅只顾最小化误差,同时模型复杂度也不能太高。

在决策树中,模型复杂度体现在树的深度上。XGBoost使用了一种替代指标,即叶子节点的个数。此外,与许多其他机器学习模型一样,XGBoost也加入了L2正则项,来平滑各叶子节点的预测值。

2.3.  支持列抽样

列抽样是指,训练每棵树时,不是使用所有特征,而是从中抽取一部分来训练这棵树。这种方法原本是用在随机森林中的,经过试验,使用在GBDT中同样有助于效果的提升。
3.为什么XGBoost效果这么好
XGBoost是boosting算法中的一种,其他的还包括AdaBoost等。Boosting方法是目前最好的机器学习方法之一,关于其优良的学习效果,已有理论解释包括偏差-方差分解和Margin理论,但都不完美。下面结合个人理解做一些通俗的讨论。

机器学习就是模型对数据的拟合。对于一组数据,使用过于复杂的模型去拟合,往往会发生过拟合,这时就需要引入正则化项来限制模型复杂度,然而正则化项的选取、正则化系数的设定都是比较随意的,也比较难做到最佳。而如果使用过于简单的模型,由于模型能力有限,很难把握数据中蕴含的规律,导致效果不佳。

Boosting算法比较巧妙,首先使用简单的模型去拟合数据,得到一个比较一般的结果,然后不断向模型中添加简单模型(多数情况下为层数较浅决策树),随着树的增多,整个boosting模型的复杂度逐渐变高,直到接近数据本身的复杂度,此时训练达到最佳水平。

因此,boosting算法要取得良好效果,要求每棵树都足够“弱”,使得每次增加的复杂度都不大,同时树的总数目要足够多。XGBoost中,对每棵树的叶子节点数做了惩罚,从而限制了叶子节点的增长,使得每棵树都是“弱”的,同时还引入了学习速率,进一步降低了每棵树的影响。这样做的代价是,数的总数目会多一些,但从其取得的效果上看,这样做是值得的。
4.   为什么XGBoost运行这么快
4.1.  连续型特征的处理

决策树在训练时需要进行分叉,对于连续型特征,枚举所有可能分叉点将会十分耗时。一种近似方法是只枚举若干个分位点,例如将所有样本根据此特征进行排序,然后均分10份,两份之间断开的数值即为分位点,枚举所有9个分位点后,使用降低损失最多的那个作为分叉点。

4.2.  利用数据稀疏性

数据稀疏有三个原因:缺失数据;某些特征本身就含有大量的0;对离散特征做了one-hot处理。无论是哪种,都会导致样本中出现大量的0。通常,利用稀疏性可以提高运算效率。XGBoost的方法是,每次分叉时,都指定一条默认分支,如果样本的这个特征为0,就走这个默认分支。这样,训练时不必考虑这些0元素,大大提高了运算速度。陈天奇的实验表明,此方法在稀疏数据上可以提高50倍。

4.3.  数据的预排序和分块存储

分叉的时候为了判断分叉点,需要对每个特征进行排序。这个步骤是要重复多次的,因此XGBoost在训练之前预先对数据进行每一列做了排序,并按列存储到内存中。在分布式环境下,可以进行分块存储。

4.4. 减少读写相关,提高Cache命中率

由于预排序的数据是按列存储的,但训练时并不总是按列读取和写回,在需要按行读写的时候,将需要的行预先收集到一块连续内存上,再进行计算。这样由于是连续内存地址,可以提高Cache命中率,从而提高了运算速度。

4.5.  数据量大时,提高硬盘吞吐率

当数据量很大,不能装入内存时,需要将一部分数据放在硬盘里。然而硬盘读写速度慢,会严重影响计算效率。XGBoost使用了两种方法提高吞吐率,一个是对存储的内容进行压缩,读取时再进行解压,这相当于在读取代价和解压代价之间做了一个权衡。另一个方法是做数据分片,即在多块硬盘上存储数据,然后同时读写,从而提高读写速度。
5.   结语
XGBoost综合了前人关于梯度提升算法的众多工作,并在工程实现上做了大量优化,是目前最成功的机器学习算法之一。目前,XGBoost已被工业界广泛使用,而GBDT及其改进算法也几乎成为了数据挖掘面试的必考题目。本文只是对其进行了走马观花式的梳理,对于它更深入的数学原理和优化细节,还请参看陈天奇在KDD’16上的原始论文[4]。
参考文献
[1] https://github.com/dmlc/XGBoost

[2] https://www.kaggle.com/

[3] http://kddcup2015.com/submission-rank.html

[4] Chen T, Guestrin C. XGBoost: A Scalable Tree Boosting System[C]. Knowledge discovery and data mining, 2016.
### XGBoost 的基本概念与用途 XGBoost 是一种强大的机器学习算法,在梯度提升框架的基础上进行了优化和改进。作为一种梯度提升树算法,它因其卓越的性能和广泛的适用性而在多个领域得到了广泛应用[^2]。 #### 基本原理 XGBoost 使用集成学习的思想,通过构建多棵决策树并将其组合起来形成最终预测模型。每一棵树都试图纠正前一棵树的误差,从而逐步提高整体模型的准确性。这种迭代过程的核心在于最小化损失函数,并利用一阶导数(梯度)和二阶导数(Hessian矩阵)来指导参数更新。 #### 工作机制 XGBoost 的工作机制可以概括如下: - **目标函数定义**:XGBoost 定义了一个通用的目标函数,其中包括训练损失项和正则化项。这使得模型不仅关注拟合能力,还能够有效防止过拟合。 - **分裂策略**:在每次分割节点时,XGBoost 计算增益值以评估候选分裂数的有效性。只有当增益超过预设阈值时才会执行分裂操作。 - **稀疏感知设计**:对于含有缺失值的数据集,XGBoost 提供了一种高效的解决方案,允许自动推断最佳方向来进行划分[^4]。 #### 应用场景 由于其灵活性和高性能表现,XGBoost 被广泛应用于各类实际问题中,特别是在结构化或表格型数据上表现出色。以下是几个典型的应用实例: 1. **零售行业需求预测** 零售商经常面临库存管理和销售预测等问题。借助于历史交易记录以及外部因素的影响(如季节变化),XGBoost 可以为企业提供精准的需求量估计,进而辅助制定更合理的采购计划[^1]。 2. **信用评分评估** 在金融信贷审批过程中,银行或其他金融机构通常会运用复杂的风控模型来判断申请者的还款可能性。凭借对复杂关系的良好捕捉能力,XGBoost 成为了此类任务的理想选择之一。 3. **生物医学研究中的分类任务** 当涉及到基因表达数据分析或者疾病诊断时,往往存在大量的特征变量需要考虑。此时采用像 XGBoost 这样的方法可以帮助识别重要的标志物并实现准确分类[^3]。 ```python import xgboost as xgb from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载乳腺癌数据集作为演示例子 data = load_breast_cancer() X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2, random_state=42) # 将数据转换成DMatrix格式 dtrain = xgb.DMatrix(X_train, label=y_train) dtest = xgb.DMatrix(X_test, label=y_test) params = { 'objective': 'binary:logistic', # 设置目标函数为逻辑回归 'eval_metric': 'error' # 错误率作为评价标准 } num_rounds = 100 bst = xgb.train(params=params, dtrain=dtrain, num_boost_round=num_rounds) # 测试集上的预测 pred_prob = bst.predict(dtest) # 输出概率值 threshold = 0.5 # 设定阈值 predictions = (pred_prob >= threshold).astype(int) accuracy = accuracy_score(y_test, predictions) print(f"Accuracy: {accuracy * 100:.2f}%") ``` 上述代码片段展示了如何使用 Python 实现一个简单的 XGBoost 模型,并对其进行训练及测试的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值