集成学习小结(RF、adaboost、xgboost)

回顾监督学习的一些要素

  • 训练样本:\(x_i\)

  • 模型:给定 \(x_i\) 预测 \(\hat{y}_i\)

  • 参数:需要从数据中学到的 \(\theta = \{w_j|j=1,2,\cdots,d\}\)

  • 目标函数

    \[obj(\theta) = L(\theta)+ \Omega(\theta) \]

    即损失函数和正则化项。优化损失函数以拟合模型不断的逼近原始数据分布,优化正则项防止模型过拟合

    • Loss
      • square loss: \(l(y_i,\hat{y}_i) = (y_i,\hat{y}_i)^2\)
      • logistic loss: \(l(y_i,\hat{y}_i) = y_iln(1+e^{-\hat{y}_i})+(1-y_i)ln(1+e^{y_i})\)
    • Regularization
      • L2: \(\Omega(w) = \lambda||w||^2\)
      • L1: \(\Omega(w) = \lambda||w||_1\)

集成学习(学什么)

bagging boosting
算法 random forest adaboost, GBDT, Xgboost,LightGBM...
采样 有放回的抽取和原始数据大小相同的样本集合 不同模型的采样方式不同(行采样、列采样)
优缺点 高偏差,底方差 高方差,低偏差

bagging

高偏差,底方差

bagging的代表模型随机森林

  • 为什么叫随机森林?随机性体现在两个方面:
    • 数据随机:每次从数据集中,有放回的随机采样和原数据集大小相同的数据
    • 特征随机:树生成时,随机选择部分特征计算增益进行划分(一般取log2d)
  • 随机森林如何计算特征重要性?
    • 袋外数据法
      • 对每一颗决策树,选择相应的袋外数据(out of bag,OOB)计算袋外数据误差,记为errOOB1.
      • 随机对袋外数据OOB所有样本的特征X加入噪声干扰(可以随机改变样本在特征X处的值),再次计算袋外数据误差,记为errOOB2。
      • 假设森林中有N棵树,则特征X的重要性=∑(errOOB2-errOOB1)/N。如果加入随机噪声后,袋外数据准确率大幅度下降(即errOOB2上升),说明这个特征对于样本的预测结果有很大影响,进而说明重要程度比较高。
    • 基尼指数(Gini index)法

boosting

高方差,低偏差

  • 模型:假设有 \(K\) 棵树

    \[\hat{y}_{i}=\sum_{k=1}^{K} f_{k}\left(x_{i}\right), \quad f_{k} \in(\mathcal{F}) \]

  • 参数

    • 每棵树的结构,叶子结点分数
    • 不再是学习权重,而是学习函数(树)\(\theta={f_1,f_2,\cdots,f_K}\)

怎么学习树呢?

Define objective (loss, regularization), and optimize it!!

  • 定义目标函数

    \[O b j=\sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}\right)+\sum_{k=1}^{K} \Omega\left(f_{k}\right) \]

    • 如何定义树的复杂度?
      • 树的深度、结点数量
      • 叶子结点权重
      • ……
  • 对决策树模型,很容易想到下面的信息

    • 使用信息增益选择特征:信息增益对应Loss
    • 剪枝处理:正则化
    • 树的最大深度:对树进行约束
    • 叶子结点值平滑处理:叶子结点权重L2正则化

adaboost

  • 基于误差改变样本权重

    • 分类误差率是误分类样本的权值之和
  • 原始的adaboost只能直接用于二分类

梯度提升(怎么学)

GBDT

用残差的负梯度拟合

\[1. 初始化第0棵树\hat{y}_0 = argmin\sum^mL(y_i,c)\\ 2.迭代生成K棵树:\\ 2.1 计算负梯度\\ 2.2 使用(x_i,r_{ti})拟合回归树\\ 2.3 得到最优树 c_{tj} = argmin\sum_{x_i\in R_{tj}}L(y_i,f_{t-1}(x_i)+c)\\ 2.4 更新分类器f_t(x) = f_{t-1}(x)+\sum^Jc_{tj}I(x_i\in R_{tj})\\ 3.最终分类器 f(x)=f_T(x)=f_0(x)+\sum^T\sum^Jc_{tj}I(x_i\in R_{tj}) \]

Xgboost

我们已经定义了模型和目标函数,知道要去学什么,下面我们看看怎么学?

  • 目标函数:

    \[\sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}\right)+\sum_{k} \Omega\left(f_{k}\right), f_{k} \in \mathcal{F} \]

    在一般的监督学习算法,我们可以使用梯度下降求解找到最优参数。但是现在参数变成树,如何找到最优的一组树

  • Boosting(叠加式训练)

    \[\begin{aligned} \hat{y}_{i}^{(0)} &=0 \\ \hat{y}_{i}^{(1)} &=f_{1}\left(x_{i}\right)=\hat{y}_{i}^{(0)}+f_{1}\left(x_{i}\right) \\ \hat{y}_{i}^{(2)} &=f_{1}\left(x_{i}\right)+f_{2}\left(x_{i}\right)=\hat{y}_{i}^{(1)}+f_{2}\left(x_{i}\right) \\ & \cdots \\ \hat{y}_{i}^{(t)} &=\sum_{k=1}^{t} f_{k}\left(x_{i}\right)=\hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right) \end{aligned} \]

    \(\hat{y}^{(t)}_i\) 表示训练第 \(t\) 棵树后对应的模型,\(\hat{y}_{i}^{(t-1)}\) 表示已经训练好的 \(t-1\) 棵树组成的模型,\(f_{t}(x_{i})\) 代表第 \(t\) 棵树。

    • 如何确定第 \(t\) 棵树?

      • 优化目标函数
    • \(t\) 轮的预测结果为 \(\hat{y}_{i}^{(t)}=\hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right)\)

      训练的目标函数为

      \[\begin{aligned} O b j^{(t)} &=\sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}^{(t)}\right)+\sum_{i=1}^{t} \Omega\left(f_{i}\right) \\ &= \sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right)\right)+ \sum_{i=1}^{t-1} \Omega\left(f_{i}\right) +\Omega\left(f_{t}\right) \\ &= \sum_{i=1}^{n} l\left(y_{i}, \hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right)\right)+\Omega\left(f_{t}\right)+\text {constant } \end{aligned} \]

      因为前 \(t-1\) 棵树已经训练了,树已经确定了,所以复杂度是常数

    • 使用 square loss

      \[\begin{aligned} O b j^{(t)} &=\sum_{i=1}^{n}\left(y_{i}-\left(\hat{y}_{i}^{(t-1)}+f_{t}\left(x_{i}\right)\right)\right)^{2}+\Omega\left(f_{t}\right)+\text {const } \\ &=\sum_{i=1}^{n}\left[2\left(\hat{y}_{i}^{(t-1)}-y_{i}\right) f_{t}\left(x_{i}\right)+f_{t}\left(x_{i}\right)^{2}\right]+\Omega\left(f_{t}\right)+\text {const } \end{aligned} \]

  • 使用泰勒级数近似

    使用二阶展开 \(f(x+\Delta x) \simeq f(x)+f^{\prime}(x) \Delta x+\frac{1}{2} f^{\prime \prime}(x) \Delta x^{2}\)

    考虑函数 \(L(y_i,\hat{y}_{i}^{(t-1)}+f_{t}(x_i)) = f(x+\Delta x)\) ,在 \(\hat{y_i}^{(t-1)}\) 二阶展开

    \[O b j^{(t)} \simeq \sum_{i=1}^{n}\left[l\left(y_{i}, \hat{y}_{i}^{(t-1)}\right)+g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{t}\right)+\text {constant } \]

    其中 \(g_{i}=\partial_{\hat{y}^{(t-1)}} l\left(y_{i}, \hat{y}^{(t-1)}\right), \quad h_{i}=\partial_{\hat{y}^{(t-1)}}^{2} l\left(y_{i}, \hat{y}^{(t-1)}\right)\)

    注意到 \(l(y_{i}, \hat{y}_{i}^{(t-1)}),g_i,h_i\) 都是已知的(因为是前 \(t-1\) 棵树)

    • 如果使用平方损失,就会是这个样子

      \[g_{i}=\partial_{\hat{y}^{(t-1)}}\left(\hat{y}^{(t-1)}-y_{i}\right)^{2}=2\left(\hat{y}^{(t-1)}-y_{i}\right) \\h_{i}=\partial_{\hat{y}^{(t-1)}}^{2}\left(y_{i}-\hat{y}^{(t-1)}\right)^{2}=2 \]

    我们找到可以求解的目标函数了吗?还没有!!\(f_t(x_i)和\Omega(f_t)\) 还没有定义,如何定义?

  • 定义一棵树

    我们用树的目的是什么?根据样本找到合理的预测值 $f_t(x_i) $,如果我们将叶子结点的值作为预测值 \(w\),样本所在的位置记为 \(q(x_i)\):

    \[f_{t}(x_i)=w_{q(x_i)} \]

    对下面的树,\(w=\{2,0.1,-1\}\)

    image-20200422082757187

    image-20200422083346009

    所以 \(x_i\) 分别为小男孩、老奶奶、小女孩。对应的 \(f_t(x_i )\)\(w[q_{(x_1)}]=w[1]=2,\quad w[q_{(x_5)}]=w[3]=-1,\quad w[q_{(x_4)}]=w[2]=0.1\)

    • 可以这样定义树的复杂度

      \[\Omega\left(f_{t}\right)=\gamma T+\frac{1}{2} \lambda \sum_{j=1}^{T} w_{j}^{2} \]

      其中 \(T\) 表示叶子结点数量,后一项是对叶子结点值进行 \(L2\) 正则。上面那棵树的复杂度就可以表示为 \(\Omega\left(f_{t}\right)=\gamma 3+\frac{1}{2} \lambda (4+0.01+1)\)

    同时定义叶子结点的样本集合为 (落在结点 \(j\) 的样本有哪些):

    \[I_{j}=\left\{i | q\left(x_{i}\right)=j\right\} \]

    对应的 \(I_1 = \{小男孩(x_1)\},I_2=\{小女孩(x_4)\},I_3 = \{妈妈,爷爷,奶奶(x_2,x_3,x_5)\}\)。这棵树的目标函数中 \(g_iw_{q(x_i)}\) 可以表示为:

    \[\sum_{i=1}^5 g_iw_{q(x_i)} = g_1w_{q(x_1)}+g_2w_{q(x_2)}+g_3w_{q(x_3)}+g_4w_{q(x_4)}+g_5w_{q(x_5)}\\ = g_1w_{q(x_1)}+g_2w_{q(x_2)}+[g_3+g_4+g_5]w_{q(x_5)}\\ =\sum_{i\in I_1}g_1w_{q(x_1)}+\sum_{i\in I_2}g_2w_{q(x_2)}+\sum_{i\in I_3}g_iw_{q(x_3)}\\ = \sum_{j=1}^3 \left[(\sum_{i\in I_1}g_i)w_{q(x_j)}+(\sum_{i\in I_2}g_i)w_{q(x_j)}+(\sum_{i\in I_3}g_i)w_{q(x_j)} \right] \]

  • 新的目标函数

    将按照样本优化 转化 为按叶子结点优化

    \[\begin{aligned} O b j^{(t)} & \simeq \sum_{i=1}^{n}\left[g_{i} f_{t}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{t}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{t}\right) \\ &=\sum_{i=1}^{n}\left[g_{i} w_{q\left(x_{i}\right)}+\frac{1}{2} h_{i} w_{q\left(x_{i}\right)}^{2}\right]+\gamma T+\lambda \frac{1}{2} \sum_{j=1}^{T} w_{j}^{2} \\ &=\sum_{j=1}^{T}\left[\left(\sum_{i \in I_{j}} g_{i}\right) w_{j}+\frac{1}{2}\left(\sum_{i \in I_{j}} h_{i}+\lambda\right) w_{j}^{2}\right]+\gamma T \\ &= \sum_{j=1}^{T}\left[G_jw_{j}+\frac{1}{2}\left(H_j+\lambda\right) w_{j}^{2}\right]+\gamma T \end{aligned} \]

    \(w\) 看做参数,上面的式子是一元二次方程,\(G_j、H_j\)分别表示对应叶子节点的样本集。\(ax^2+by+c=0\) 大家都很熟悉,在\(x=-\frac{b}{2a}\) 处取最小值,类似的:

    \[w_{j}^{*}=-\frac{G_{j}}{H_{j}+\lambda} \quad O b j=-\frac{1}{2} \sum_{j=1}^{T} \frac{G_{j}^{2}}{H_{j}+\lambda}+\gamma T \]

    现在可以计算这棵树的目标函数了:

    image-20200422092625913

    目标函数的值更小,对应的树的结构更好。

  • 这就结束了吗?不,才刚刚开始

    在上面求解目标函数时,我们假设已知第 \(t\) 棵树的结构了,然后得到了这棵树对应的score。但是,现在我们不知道树的结构,怎么办?我可以根据已有样本,穷举所有可能的树,找到最小的目标函数值,就对应最优的那棵树。但是穷举这件事,还是不太靠谱,计算复杂度太高了...

  • 贪心算法生成树

    回顾决策树方法,我们通过计算信息增益,寻找信息增益最大的特征进行划分,\(g(D,A) = H(D)-H(D|A)\), 信息增益越大就是让熵变化最大,即 \(max(原不确定性-划分后不确定性)\) 。对应的,我们选择新的 \(obj\) 和 旧的 \(obj\) 差异最大的进行划分。

    • 从深度为0开始构建树

    • 对每个结点尝试划分,目标函数将会改变:

      image-20200422095352527

      怎么快速找到划分点?

      • 将样本特征排序,从左至右线性扫描
    • 具体来说,对每个结点,枚举所有的特征

      • 对每个特征,根据特征值将样本排序
      • 排序后,进行线性扫描,确定最佳划分特征
    • 复杂度是多少?

      • \(O(ndKlogn)\)\(d\) 个特征,每个特征排序需要\(O(nlogn)\),树深度为\(K\),需要\(K\)次。
  • 回顾整个过程

    • 每次迭代生成一颗新的树

    • 每次迭代开始,计算:

      \[g_{i}=\partial_{\hat{y}^{(t-1)}} l\left(y_{i}, \hat{y}^{(t-1)}\right), \quad h_{i}=\partial_{\hat{y}^{(t-1)}}^{2} l\left(y_{i}, \hat{y}^{(t-1)}\right) \]

    • 贪心策略生成第 \(t\) 棵树

      \[O b j=-\frac{1}{2} \sum_{j=1}^{T} \frac{G_{j}^{2}}{H_{j}+\lambda}+\gamma T \]

  • 将第\(k\)棵树加入到模型中:

    \(y^{(t)}=y^{(t-1)}+\epsilon f_{t}\left(x_{i}\right)\)\(\epsilon\) 表示学习率

几种模型比较

Xgboost 与 GBDT

  • 目标函数方面:

    • 传统GBDT在优化时只用到一阶导数信息,xgboost则对代价函数进行了二阶泰勒展开,同时用到了一阶和二阶导数。二阶偏导相当于找到了一阶导数的下降方向, 会使梯度下降的更快, 收敛的更快
    • xgboost在代价函数里加入了正则项,用于控制模型的复杂度。正则项里包含了树的叶子节点个数、每个叶子节点上输出的score的L2模的平方和。从Bias-variance tradeoff角度来讲,正则项降低了模型的variance,使学习出来的模型更加简单,防止过拟合,这也是xgboost优于传统GBDT的一个特性。
    • Shrinkage(缩减),相当于学习速率(xgboost中的eta)。xgboost在进行完一次迭代后,会将叶子节点的权重乘上该系数,主要是为了削弱每棵树的影响,让后面有更大的学习空间。实际应用中,一般把eta设置得小一点,然后迭代次数设置得大一点。(补充:传统GBDT的实现也有学习速率)
  • 模型构建方面

    • 传统GBDT以CART作为基分类器,xgboost还支持线性分类器,这个时候xgboost相当于带L1和L2正则化项的逻辑斯蒂回归(分类问题)或者线性回归(回归问题)。(只要函数可一阶和二阶求导。)

    • 列抽样(column subsampling)。xgboost借鉴了随机森林的做法,支持列抽样,不仅能降低过拟合,还能减少计算,这也是xgboost异于传统gbdt的一个特性。

    • 对缺失值的处理。对于特征的值有缺失的样本,xgboost可以自动学习出它的分裂方向。

    • (多线程并行)xgboost工具支持并行。boosting不是一种串行的结构吗?怎么并行的?

      注意xgboost的并行不是tree粒度的并行,xgboost也是一次迭代完才能进行下一次迭代的(第t次迭代的代价函数里包含了前面t-1次迭代的预测值)。xgboost的并行是在特征粒度上的。我们知道,决策树的学习最耗时的一个步骤就是对特征的值进行排序(因为要确定最佳分割点),xgboost在训练之前,预先对数据进行了排序,然后保存为block结构,后面的迭代中重复地使用这个结构,大大减小计算量。这个block结构也使得并行成为了可能,在进行节点的分裂时,需要计算每个特征的增益,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行。

    • 可并行的近似直方图算法。树节点在进行分裂时,我们需要计算每个特征的每个分割点对应的增益,即用贪心法枚举所有可能的分割点。当数据无法一次载入内存或者在分布式情况下,贪心算法效率就会变得很低,所以xgboost还提出了一种可并行的近似直方图算法,用于高效地生成候选的分割点。

xgboost 和 LR

  • xgboost擅长连续值处理,LR擅长离散值处理

  • LR将特征离散化原因?

    • 增强泛化能力
    • 稀疏向量,计算简单
    • 离散后方便特征交叉
  • 缺失值处理

  • one-hot

  • GBDT+LR

    • 为什么建树采用GBDT而非RF?

      且GBDT前面的树,特征分裂主要体现对多数样本有区分度的特征;后面的树,主要体现的是经过前N颗树,残差仍然较大的少数样本。优先选用在整体上有区分度的特征,再选用针对少数样本有区分度的特征,思路更加合理,这应该也是用GBDT的原因

  • adaboost只能用于二分类

LightGBM

  • 直方图差加速
    一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到, 在分裂节点的时候, 计算玩所有左孩子的直方图之后, 直接用父节点的直方图-左孩子的直方图就可以得到右孩子的直方图.

  • 特征并行减少了传输切分结果的步骤

    每个worker上保留完整的数据集,而不是列采样子集(空间换时间)

  • 数据并行

    • 不合并所有局部直方图得到全局直方图。合并无交叉的不同特征的直方图
    • 使用直方图差,减少叶节点传输

references

【1】https://zhuanlan.zhihu.com/p/34534004

【2】https://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf

【3】http://wepon.me/files/gbdt.pdf

【4】李航. 统计学习方法

【5】周志华. 机器学习

【6】http://www.mamicode.com/info-detail-2548410.html

posted @ 2020-08-29 10:54  鱼与鱼  阅读(547)  评论(0编辑  收藏  举报