机器学习竞赛大杀器XGBoost--原理篇

在机器学习竞赛中被广泛使用的XGBoost系统已经久负盛名,近期两周时间我参加了一个京东金融的贷款预测竞赛使用的就是XGB,之前虽然也简单的使用过,但并没有真正去深入了解这个系统,这次通过阅读XGB原论文和官方Tutorials 之后才算有了一些深入的了解,本文将对XGB进行一个简单的讲解,以供小伙伴学习。

XGB是一个具有可扩展性的树提升算法机器学习系统,它的可扩展性体现在以下四个方面:

  • 模型的scalability,弱分类器除cart外也支持lr和linear
  • 策略的scalability,可以支持不同的loss functions,来优化效果,只要一、二阶可导即可
  • 算法的scalability,做了很多细节工作,来优化参数学习和迭代速度,特征压缩技,bagging学习中的特征抽样,特征选择与阈值分裂的分位方法和并行方法等
  • 数据的scalability,因为3中的优化,支持B级别的快速训练和建模;同时也因为加上了正则项和随机特征抽样,减少了过拟合问题

(来自王浩的一个回答。)

XGB系统的主要优势及创新根据作者的描述,可以归纳为以下几点:

  1. 一个新奇的(novel)处理稀疏数据的树学习算法;
  2. 使用近似树学习( approximate tree learning)理论利用分位数的描述,可以给每一个训练实例一个合理的加权权重;
  3. 并行和分布式的设计使得学习速度非常快,建模更快速;
  4. XGBoost exploits out-of-core computation 机制让仅使用笔记本就可以处理数以亿计的数据成为可能。
  5. 端到端系统使用最小的集群资源就可以处理大量的数据。

XGB被用于监督学习,监督学习指利用具有多个特征的训练数据xi来预测目标变量yi,在训练数据中yi作为标签是给定的。在正式介绍XGB之前,我们先来回顾一下监督学习的相关知识。

1、监督学习基础理论

1.1、模型和参数

监督学习中的模型指利用给定的xi如何来预测目标yi的数学结构,对于最简单的线性模型,它的模型结构如下:

它是一条组合输入特征权重的直线。预测值根据任务的不同具有不同的解释,如回归和分类。

参数就是我们的模型需要从数据中学习的一些数据,在线性回归问题中,参数就是每一个特征的系数 \theta 。通常,我们使用 \theta 来表示参数。

1.2、目标函数:训练损失+正则化

依据对yi的不同理解,我们有不同的问题,比如回归,分类和排序等,利用训练数据我们需要找到一个方法来学习到最好的参数。因此我们需要定义一个目标函数来衡量模型学习到的参数的好坏。目标函数通常包含两部分:训练损失和正则化。使用数学公式表达如下:

L是训练损失函数, \Omega 是正则项。训练损失函数测量了我们的模型在训练数据上如何学习,例如回归任务的一个常用损失函数是均方误差(MSE):

另一个常用的损失函数是逻辑斯蒂回归中的logistic loss

正则项用于控制模型的复杂度,也就是防止模型过拟合。听上去有点抽象,那么来看看下面这个例子吧。

左上角描绘的是用户随着时间的变化对某话题的感兴趣程度的变化,如果使用step function来建模,可以看到右上角的模型基本上拟合到每一个数据点,然而也可以看到它太复杂了,也就是模型复杂度太高;而对于左下角模型,它虽然比较简单,但是很多数据都没有拟合到;最后看看右下角的模型,它简单,而且基本拟合到所有数据点。因此我们说右下角的模型是最好的,对于一个机器学习的模型的通用原则是:简单并且准确。模型往往需要在简单和准确之中做一个折中,这种折中也成为偏差-方差的折中(bias-variance tradeoff)。

2、树提升模型简介

2.1、正则化的学习目标

对于给定的数据集,n个实例,m个特征,

树集成模型(下图所示)使用K个函数的累加和来预测输出。

这里

是所有回归树(CART)函数空间,里面的q表示每颗树的结构,它将实例映射到相应的叶子节点的索引;T表示一棵树的叶子节点个数;每一个fk相对应一个独立的树结构q和叶子节点权重w。与决策树不同的是,每一个回归树在每一个叶子节点上包含了连续的分值,wi表示第i个叶子节点的得分。在上图给定的例子中,我们使用树的决策规则来将小男孩分类到对应的叶子节点,然后将所有分到的叶子节点所对应的分值相加,最后得到小男孩的最终得分2.9,因此,相较于老爷爷,小男孩玩电脑游戏的可能性更大。

在上述例子中,我们学习到了两棵树,并且每颗树的决策变量不同,且他们具有决策先后顺序,那么这些决策(函数)是如何学习到的呢?我们通过最小化下面的目标函数来学习的:

这里l是一个可微的凸损失函数,测量预测值和目标值的不同。 \Omega 是k颗树的正则项,用于抑制模型的复杂度防止过拟合。当正则项的参数是0时,上述目标函数就是一个传统的梯度树提升模型。

这里有几个疑问:

  1. 每一颗树的分支依据是如何确定的?(比如先分age,再分性别)
  2. 每一颗树的分支分到哪里为止?(比如is male?下面还要不要分支?)
  3. 每棵树的叶子节点的权重分值是如何确定的?(为什么有的是2,有的是0.9,有的是-1)
  4. 树的颗数是如何确定的,多少颗树是最合适的?

带着以上几个疑问我们继续。

2.2、梯度树提升

上述目标函数的参数本身是函数,这样使用传统的优化方法是不能优化到最优值的。相反,模型的训练时采用加法的形式来训练的,形式上,使用 \bar{y}_i^{(t)} 作为第i个实例在第t词迭代中的预测值,我们需要添加ft来最小化下面的目标函数:

这意味着我们通过2.1节中的目标函数贪婪的添加ft来最大程度的改善我们的模型。对于上式,我们通常使用二阶近似解来快速的优化目标:

它们是损失函数的一阶和二阶导。移除常数项,仅需优化下面的目标:

定义 I_j=\{i|q(X_i)=j\} 作为叶子节点j上面的实例集合,我们可以重写上式:

对于固定的树结构q(X),我们可以叶子节点j的最优权重 w_j^* :

计算这棵树的最优值

这个公式也可以作为得分函数来测量树结构q的质量(也就是学习的这棵树对总体结果有没有提升),下图展示了如何计算一棵树的分值

树的计算分值月底,说明这个树的结构越好。
由于训练数据可能有很多特征,构建一棵树可能有许多种不同的构建形式,我们不可能枚举所有可能的树结构q来一一计算它的分值。贪心算法从一个单独树叶开始迭代的增加分支。假设 I_LI_R 是分割之后节点的左侧和右侧实例集合,令 I=I_L\cup I_R ,那么在节点分割后的损失减少量为:

这个公式通常用于在实践中评估候选分裂节点是不是应该分裂。

2.3 收缩和列采样

在防止模型过拟合方面,除了使用正则化项,收缩和列采样也经常使用。收缩规模在树提升的每一步迭代中通过因子 \eta 逐步增加收缩权重,这和随机梯度下降的学习率相似。收缩技术降低了每一个单个的树和叶子节点对之后要学习的树结构的影响。列采样在随机森林中被使用,它除了能防止过拟合还能加块并行算法的计算速度。

3、分支节点分裂算法

3.1、 Basic Exact Greedy Algorithm
在树学习中,一个关键问题是如何找到每一个特征上的分裂点,比如在本文的例子中,age的分裂节点是15岁,而不是其他年纪。为了找到最佳分裂节点,分裂算法枚举特征上所有可能的分裂点,然后计算得分,这种算法称为 exact greedy algorithm,单机版本的XGBoost支持这种 exact greedy algorithm,算法如下所示:

为了有效率的找到最佳分裂节点,算法必须先将该特征的所有取值进行排序,之后按顺序取分裂节点计算 L_{split}

3.2、近似算法

exact greedy algorithm使用贪婪算法非常有效的找到分裂节点,但是当数据量很大时,数据不可能一次性的全部读入到内存中,或者在分布式计算中,这样不可能事先对所有值进行排序,且无法使用所有数据来计算分裂节点之后的树结构得分。为解决这个问题,近似算法被应用进来。近似算法首先按照特征取值的统计分布的一些百分位点确定一些候选分裂点,然后算法将连续的值映射到 buckets中,然后汇总统计数据,并根据聚合统计数据在候选节点中找到最佳节点。

近似算法有两个变体, global variant和 local variant。

3.3、 加权分位数(Weighted Quantile Sketch)

在近似算法中的重要步骤中是如何确定候选分裂点。通常特征取值的百分位被用于生成候选分裂点。更进一步的我们可以令多集合

表示第k个特征的每个训练样本的二阶梯度统计。我们可以定义一个排序函数:

表示特征值k小于z的实例比例。目标就是寻找候选分裂点集 \{s_{k1},s_{k2},...s_{kl}\} 。因此

这里 \epsilon 是近似因子,这意味着有大概 1/\epsilon 个候选点。这里每个数据点的权重为 h_i

3.4、稀疏感知分割

在很多现实业务数据中,训练数据x可能很稀疏。造成这个问题得原因可能是:存在大量缺失值,太多0统计值,one-hot-encoding所致。算法能够处理稀疏模式数据非常重要,XGB在树节点中添加默认划分方向的方法来解决这个问题,如下图所示:

当有缺失值时,系统将实例分到默认方向的叶子节点。每个分支都有两个默认方向,最佳的默认方向可以从训练数据中学习到。算法如下:

论文中给出了他们的算法在稀疏数据中的处理速度,那是相当的快的

4、参考资料

1、 Tianqi Chen, Carlos Guestrin论文《 XGBoost: A Scalable Tree Boosting System》
2、XGBoost官方tutorials
编辑于 2017-12-03

文章被以下专栏收录