欢迎光临
我们一直在努力

【HistGBM 系列②】梯度提升的数学框架与二阶优化

【HistGBM 系列②】梯度提升的数学框架与二阶优化

文章目录

  • 【HistGBM 系列②】梯度提升的数学框架与二阶优化
    • 前言
    • 一、问题形式化
      • 1.1 监督学习的函数估计视角
      • 1.2 加性模型假设
    • 二、Friedman 的梯度提升框架
      • 2.1 核心困境
      • 2.2 Friedman 的解法:函数空间的梯度下降
      • 2.3 为什么这等价于梯度下降
      • 2.4 以 MSE 为例验证
      • 2.5 以 MAE 为例看框架的通用性
    • 三、Friedman 通用算法
    • 四、XGBoost 的二阶优化方法
      • 4.1 为什么需要二阶信息
      • 4.2 二阶泰勒展开
      • 4.3 去掉常数项
      • 4.4 按叶节点重组目标函数
      • 4.5 最优叶权重:闭式解推导
      • 4.6 分裂增益公式
    • 五、常见损失函数的

      (

      g

      i

      ,

      h

      i

      )

      (g_i, h_i)

      (gi,hi) 计算

      • 5.1 回归损失
      • 5.2 二分类损失
      • 5.3 Quantile Loss(分位数回归)
      • 5.4 梯度计算的关键性质
    • 六、

      (

      g

      i

      ,

      h

      i

      )

      (g_i, h_i)

      (gi,hi) 在 HistGBM 中的作用

      • 6.1 直方图的存储内容
      • 6.2 直方图相减的前提
      • 6.3 一图总结
    • 七、一阶 vs 二阶:一个直观的数值例子
    • 八、小结

系列导航

  • 【系列①】从决策树到梯度提升——GBDT 原理精讲
  • 【系列②】梯度提升的数学框架与二阶优化(本篇)
  • 【系列③】直方图加速——HistGBM 的核心创新
  • 【系列④】HistGradientBoostingRegressor 深度解析
  • 【系列⑤】调参实战与生产部署

前言

第一篇我们建立了从 CART 回归树到 GBDT 的完整认知,留下了一个悬念:对于 MSE 损失,伪残差恰好等于普通残差,那换了别的损失函数呢?

这正是 Friedman(2001)梯度提升框架的核心贡献:把 Boosting 的迭代过程统一为函数空间中的梯度下降。不管你用什么损失函数——MSE、MAE、Huber、Logistic Loss——算法结构完全不变,只需更换"梯度"的计算方式。

本篇将进一步引入 XGBoost(Chen & Guestrin, 2016)的二阶泰勒展开优化:不仅用一阶梯度告诉你"该往哪个方向走",还用二阶梯度(Hessian)告诉你"这一步迈多大最合适"。这两个统计量

(

g

i

,

h

i

)

(g_i, h_i)

(gi,hi) 正是 HistGBM 直方图的组成部分——理解它们对理解第三篇直方图加速至关重要。

本篇目标:

  • 掌握 Friedman 梯度提升框架的完整数学推导
  • 理解为什么 Boosting 可以看作"函数空间的梯度下降"
  • 推导 XGBoost 的二阶泰勒展开、最优叶权重公式和分裂增益公式
  • 理解

    (

    g

    i

    ,

    h

    i

    )

    (g_i, h_i)

    (gi,hi) 统计量的含义及其在 HistGBM 中的作用


  • 一、问题形式化

    1.1 监督学习的函数估计视角

    给定训练数据

    {

    (

    x

    i

    ,

    y

    i

    )

    }

    i

    =

    1

    n

    \\{(x_i, y_i)\\}_{i=1}^n

    {(xi,yi)}i=1n,我们希望找到一个函数

    F

    (

    x

    )

    F(x)

    F(x) 来近似

    y

    y

    y

    x

    x

    x 之间的真实映射关系。

    F

    =

    arg

    min

    F

    i

    =

    1

    n

    L

    (

    y

    i

    ,

    F

    (

    x

    i

    )

    )

    F^* = \\arg\\min_F \\sum_{i=1}^n L(y_i, F(x_i))

    F=argFmini=1nL(yi,F(xi))

    其中

    L

    (

    y

    ,

    F

    (

    x

    )

    )

    L(y, F(x))

    L(y,F(x)) 是可微的损失函数,度量预测值

    F

    (

    x

    )

    F(x)

    F(x) 与真实值

    y

    y

    y 之间的差异。

    常见损失函数一览:

    损失函数公式特点适用场景
    Squared Error (MSE)

    1

    2

    (

    y

    F

    )

    2

    \\frac{1}{2}(y-F)^2

    21(yF)2

    对异常值敏感,梯度与残差成正比 普通回归(无异常值)
    Absolute Error (MAE) $ y-F $
    Huber Loss $\\begin{cases} \\frac{1}{2}(y-F)^2 & y-F \\leq\\delta \\ \\delta
    Logistic Loss

    log

    (

    1

    +

    e

    y

    F

    )

    \\log(1+e^{-y\\cdot F})

    log(1+eyF)

    二分类标准损失 二分类
    Quantile Loss

    {

    α

    (

    y

    F

    )

    y

    >

    F

    (

    1

    α

    )

    (

    F

    y

    )

    y

    F

    \\begin{cases} \\alpha(y-F) & y>F \\\\ (1-\\alpha)(F-y) & y\\leq F \\end{cases}

    {α(yF)(1α)(Fy)y>FyF

    可预测任意分位数 预测区间估计

    1.2 加性模型假设

    GBDT 假设模型

    F

    (

    x

    )

    F(x)

    F(x) 由 M 棵树的输出加性叠加而成:

    F

    M

    (

    x

    )

    =

    m

    =

    1

    M

    h

    m

    (

    x

    )

    F_M(x) = \\sum_{m=1}^{M} h_m(x)

    FM(x)=m=1Mhm(x)

    其中每棵

    h

    m

    (

    x

    )

    h_m(x)

    hm(x) 是一棵 CART 回归树,属于树函数空间

    H

    \\mathcal{H}

    H

    这是一个"弱学习器的加权和"模型——单棵树能力有限(弱学习器),叠加起来就形成了强大的预测能力。


    二、Friedman 的梯度提升框架

    2.1 核心困境

    如果我们想把

    F

    (

    x

    )

    F(x)

    F(x) 当作一个"参数"来优化,一个直接的思路是对

    F

    F

    F 做梯度下降:

    F

    m

    (

    x

    )

    =

    F

    m

    1

    (

    x

    )

    η

    i

    L

    (

    y

    i

    ,

    F

    (

    x

    i

    )

    )

    F

    F_m(x) = F_{m-1}(x) – \\eta \\cdot \\frac{\\partial \\sum_i L(y_i, F(x_i))}{\\partial F}

    Fm(x)=Fm1(x)ηFiL(yi,F(xi))

    但问题来了:

    F

    (

    x

    )

    F(x)

    F(x) 是一个函数,不是有限维参数向量。在全体训练样本上,

    F

    F

    F 的"参数"是它在每个

    x

    i

    x_i

    xi 处的取值——共 n 个"参数"。而且,梯度只在训练点

    (

    x

    i

    ,

    y

    i

    )

    (x_i, y_i)

    (xi,yi) 处有定义——对于未见过的新

    x

    x

    x,梯度没有意义。

    2.2 Friedman 的解法:函数空间的梯度下降

    第一步:在训练点上计算负梯度

    第 m 轮迭代时,对每个训练样本计算损失函数对当前预测值的负梯度:

    r

    i

    m

    =

    [

    L

    (

    y

    i

    ,

    F

    (

    x

    i

    )

    )

    F

    (

    x

    i

    )

    ]

    F

    =

    F

    m

    1

    ,

    i

    =

    1

    ,

    2

    ,

    ,

    n

    r_{im} = -\\left[\\frac{\\partial L(y_i, F(x_i))}{\\partial F(x_i)}\\right]_{F = F_{m-1}}, \\quad i = 1, 2, \\ldots, n

    rim=[F(xi)L(yi,F(xi))]F=Fm1,i=1,2,,n

    这个

    r

    i

    m

    r_{im}

    rim 被称为伪残差(pseudo-residual),它告诉你:为了让第 i 个样本的损失下降,

    F

    (

    x

    i

    )

    F(x_i)

    F(xi) 应该往哪个方向调整。

    第二步:用一棵树来"插值"梯度

    负梯度只在 n 个训练点上定义了值,但我们需要的是能对任何新 x 做预测的函数。怎么办?

    训练一棵回归树

    h

    m

    (

    x

    )

    h_m(x)

    hm(x),用

    {

    (

    x

    i

    ,

    r

    i

    m

    )

    }

    i

    =

    1

    n

    \\{(x_i, r_{im})\\}_{i=1}^n

    {(xi,rim)}i=1n 作为训练数据——让树去拟合这些负梯度值。直观理解:树"学会了"梯度在特征空间中的分布规律,可以对训练集之外的 x 也给出一个梯度方向的估计。

    第三步:更新模型

    F

    m

    (

    x

    )

    =

    F

    m

    1

    (

    x

    )

    +

    η

    h

    m

    (

    x

    )

    F_m(x) = F_{m-1}(x) + \\eta \\cdot h_m(x)

    Fm(x)=Fm1(x)+ηhm(x)

    η

    \\eta

    η 是学习率(shrinkage),控制每步的"步长"。

    2.3 为什么这等价于梯度下降

    考虑参数化模型的梯度下降更新:

    θ

    m

    =

    θ

    m

    1

    η

    θ

    L

    (

    θ

    m

    1

    )

    \\theta_m = \\theta_{m-1} – \\eta \\cdot \\nabla_\\theta L(\\theta_{m-1})

    θm=θm1ηθL(θm1)

    对于 GBDT,"参数"是在每个训练点处的预测值

    {

    F

    (

    x

    1

    )

    ,

    F

    (

    x

    2

    )

    ,

    ,

    F

    (

    x

    n

    )

    }

    \\{F(x_1), F(x_2), \\ldots, F(x_n)\\}

    {F(x1),F(x2),,F(xn)}。在每个点上的梯度分量是

    L

    F

    (

    x

    i

    )

    \\frac{\\partial L}{\\partial F(x_i)}

    F(xi)L,所以:

    (

    F

    m

    (

    x

    1

    )

    F

    m

    (

    x

    2

    )

    F

    m

    (

    x

    n

    )

    )

    =

    (

    F

    m

    1

    (

    x

    1

    )

    F

    m

    1

    (

    x

    2

    )

    F

    m

    1

    (

    x

    n

    )

    )

    +

    η

    (

    r

    1

    m

    r

    2

    m

    r

    n

    m

    )

    \\begin{pmatrix} F_m(x_1) \\\\ F_m(x_2) \\\\ \\vdots \\\\ F_m(x_n) \\end{pmatrix} = \\begin{pmatrix} F_{m-1}(x_1) \\\\ F_{m-1}(x_2) \\\\ \\vdots \\\\ F_{m-1}(x_n) \\end{pmatrix} + \\eta \\cdot \\begin{pmatrix} -r_{1m} \\\\ -r_{2m} \\\\ \\vdots \\\\ -r_{nm} \\end{pmatrix}

    Fm(x1)Fm(x2)Fm(xn)

    =

    Fm1(x1)Fm1(x2)Fm1(xn)

    +η

    r1mr2mrnm

    h

    m

    (

    x

    )

    h_m(x)

    hm(x) 并非完美拟合这些

    r

    i

    m

    r_{im}

    rim——树是有限深度的,只能近似。树将负梯度"约束"为一个结构化的函数(分段常数),这赋予了两个好处:

  • 泛化:有了树的约束,模型不会只记住训练点上的梯度值,而是学到梯度在特征空间中的规律
  • 正则化:浅树(max_depth=3~6)天然限制了每轮修正的"自由度"
  • 2.4 以 MSE 为例验证

    对于 MSE 损失

    L

    (

    y

    ,

    F

    )

    =

    1

    2

    (

    y

    F

    )

    2

    L(y, F) = \\frac{1}{2}(y – F)^2

    L(y,F)=21(yF)2

    r

    i

    m

    =

    [

    1

    2

    (

    y

    i

    F

    )

    2

    F

    ]

    F

    =

    F

    m

    1

    =

    [

    (

    y

    i

    F

    m

    1

    (

    x

    i

    )

    )

    ]

    =

    y

    i

    F

    m

    1

    (

    x

    i

    )

    r_{im} = -\\left[\\frac{\\partial \\frac{1}{2}(y_i – F)^2}{\\partial F}\\right]_{F=F_{m-1}} = -[-(y_i – F_{m-1}(x_i))] = y_i – F_{m-1}(x_i)

    rim=[F21(yiF)2]F=Fm1=[(yiFm1(xi))]=yiFm1(xi)

    伪残差 = 普通残差。这就是为什么 GBDT 有时被通俗地称为"拟合残差的树模型"——对 MSE 而言确实如此。

    2.5 以 MAE 为例看框架的通用性

    对于 MAE 损失

    L

    (

    y

    ,

    F

    )

    =

    y

    F

    L(y, F) = |y – F|

    L(y,F)=yF

    r

    i

    m

    =

    [

    y

    i

    F

    F

    ]

    F

    =

    F

    m

    1

    =

    sign

    (

    y

    i

    F

    m

    1

    (

    x

    i

    )

    )

    r_{im} = -\\left[\\frac{\\partial |y_i – F|}{\\partial F}\\right]_{F=F_{m-1}} = \\text{sign}(y_i – F_{m-1}(x_i))

    rim=[FyiF]F=Fm1=sign(yiFm1(xi))

    伪残差变为 +1 或 -1(取决于预测是高是低),不再是残差值本身。但算法结构完全不变——这正是梯度提升"框架"的威力。


    三、Friedman 通用算法

    基于以上推导,Friedman 的通用梯度提升算法如下:

    算法:Generic Gradient Boosting Machine(Friedman 2001)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    输入:训练集 {(x_i, y_i)}_{i=1}^n
    可微损失函数 L(y, F)
    迭代次数 M
    学习率 η

    1. 初始化常数值预测:
    F_0(x) = argmin_γ Σ_{i=1}^n L(y_i, γ)
    (常见:MSE 时取均值,MAE 时取中位数)

    2. For m = 1 to M:
    a. 计算伪残差(负梯度):
    r_{im} = -[∂L(y_i, F(x_i)) / ∂F(x_i)]_{F=F_{m-1}}, i=1,…,n

    b. 用回归树拟合 {(x_i, r_{im})}:
    {R_{jm}}_{j=1}^{J_m} = J_m 个叶节点区域

    c. 对每个叶节点 j,计算最优预测值(一维线搜索):
    γ_{jm} = argmin_γ Σ_{x_i∈R_{jm}} L(y_i, F_{m-1}(x_i) + γ)

    d. 更新模型:
    F_m(x) = F_{m-1}(x) + η · Σ_{j=1}^{J_m} γ_{jm} · 1[x∈R_{jm}]

    3. 输出:F_M(x)

    📌 注意步骤 2c:Friedman 原始方案在每个叶节点上做一个一维线搜索来找最优 γ。这理论上更精确,但计算量大。XGBoost 和 HistGBM 用一个更聪明的方法——二阶泰勒展开——直接用闭式解替代线搜索。这就引出了下一节的核心内容。


    四、XGBoost 的二阶优化方法

    4.1 为什么需要二阶信息

    Friedman 的一阶框架有一个不够优雅的地方:步骤 2c 的线搜索需要在每个叶节点上求一个最优化子问题。

    能不能直接算出最优叶权重,省去线搜索?

    这就需要用二阶泰勒展开来近似损失函数——不仅知道梯度的方向(一阶),还知道曲率(二阶),从而直接算出最优步长。

    4.2 二阶泰勒展开

    在第 t 轮迭代,当前模型为

    y

    ^

    i

    (

    t

    1

    )

    =

    F

    t

    1

    (

    x

    i

    )

    \\hat{y}_i^{(t-1)} = F_{t-1}(x_i)

    y^i(t1)=Ft1(xi),我们要找一个新树

    f

    t

    f_t

    ft 使得:

    L

    (

    t

    )

    =

    i

    =

    1

    n

    L

    (

    y

    i

    ,

    y

    ^

    i

    (

    t

    1

    )

    +

    f

    t

    (

    x

    i

    )

    )

    +

    Ω

    (

    f

    t

    )

    \\mathcal{L}^{(t)} = \\sum_{i=1}^n L(y_i, \\hat{y}_i^{(t-1)} + f_t(x_i)) + \\Omega(f_t)

    L(t)=i=1nL(yi,y^i(t1)+ft(xi))+Ω(ft)

    y

    ^

    i

    (

    t

    1

    )

    \\hat{y}_i^{(t-1)}

    y^i(t1) 处对损失函数做二阶泰勒展开:

    L

    (

    y

    i

    ,

    y

    ^

    (

    t

    1

    )

    +

    f

    t

    )

    L

    (

    y

    i

    ,

    y

    ^

    (

    t

    1

    )

    )

    +

    g

    i

    f

    t

    (

    x

    i

    )

    +

    1

    2

    h

    i

    f

    t

    2

    (

    x

    i

    )

    L(y_i, \\hat{y}^{(t-1)} + f_t) \\approx L(y_i, \\hat{y}^{(t-1)}) + g_i \\cdot f_t(x_i) + \\frac{1}{2} h_i \\cdot f_t^2(x_i)

    L(yi,y^(t1)+ft)L(yi,y^(t1))+gift(xi)+21hift2(xi)

    其中:

    g

    i

    =

    L

    (

    y

    i

    ,

    y

    ^

    )

    y

    ^

    y

    ^

    =

    y

    ^

    i

    (

    t

    1

    )

    — 一阶梯度(等同于 Friedman 的负伪残差,取负号)

    g_i = \\frac{\\partial L(y_i, \\hat{y})}{\\partial \\hat{y}} \\Big|_{\\hat{y}=\\hat{y}_i^{(t-1)}} \\quad \\text{— 一阶梯度(等同于 Friedman 的负伪残差,取负号)}

    gi=y^L(yi,y^)

    y^=y^i(t1)— 一阶梯度(等同于 Friedman 的负伪残差,取负号)

    h

    i

    =

    2

    L

    (

    y

    i

    ,

    y

    ^

    )

    y

    ^

    2

    y

    ^

    =

    y

    ^

    i

    (

    t

    1

    )

    — 二阶梯度(Hessian,度量损失函数的曲率)

    h_i = \\frac{\\partial^2 L(y_i, \\hat{y})}{\\partial \\hat{y}^2} \\Big|_{\\hat{y}=\\hat{y}_i^{(t-1)}} \\quad \\text{— 二阶梯度(Hessian,度量损失函数的曲率)}

    hi=y^22L(yi,y^)

    y^=y^i(t1)— 二阶梯度(Hessian,度量损失函数的曲率)

    💡 为什么二阶更好? 一阶只告诉你"该往哪个方向走",二阶告诉你"曲率有多陡"——如果

    h

    i

    h_i

    hi 很大(损失函数曲率大),意味着该点附近的梯度变化剧烈,应该走小步;如果

    h

    i

    h_i

    hi 很小(损失函数平坦),可以走大步。

    4.3 去掉常数项

    常数项

    L

    (

    y

    i

    ,

    y

    ^

    (

    t

    1

    )

    )

    L(y_i, \\hat{y}^{(t-1)})

    L(yi,y^(t1)) 不依赖

    f

    t

    f_t

    ft,可以去掉。加上正则项后,近似目标函数为:

    L

    ~

    (

    t

    )

    =

    i

    =

    1

    n

    [

    g

    i

    f

    t

    (

    x

    i

    )

    +

    1

    2

    h

    i

    f

    t

    2

    (

    x

    i

    )

    ]

    +

    Ω

    (

    f

    t

    )

    \\tilde{\\mathcal{L}}^{(t)} = \\sum_{i=1}^n \\left[g_i f_t(x_i) + \\frac{1}{2} h_i f_t^2(x_i)\\right] + \\Omega(f_t)

    L~(t)=i=1n[gift(xi)+21hift2(xi)]+Ω(ft)

    正则项:

    Ω

    (

    f

    t

    )

    =

    γ

    T

    +

    1

    2

    λ

    j

    =

    1

    T

    w

    j

    2

    \\Omega(f_t) = \\gamma T + \\frac{1}{2}\\lambda \\sum_{j=1}^T w_j^2

    Ω(ft)=γT+21λj=1Twj2

    其中:

    • T

      T

      T:树的叶节点数量

    • w

      j

      w_j

      wj:第

      j

      j

      j 个叶节点的权重(输出值)

    • γ

      \\gamma

      γ:新增一个叶节点的复杂度代价(类似剪枝强度)

    • λ

      \\lambda

      λ:叶节点权重的 L2 正则化系数

    🎯 两个正则化参数的区别:

    γ

    \\gamma

    γ 控制"树可以长多大"(结构复杂度),

    λ

    \\lambda

    λ 控制"每个预测值可以多大"(权重约束)。HistGBM 和 sklearn 的 l2_regularization 对应

    λ

    \\lambda

    λ

    4.4 按叶节点重组目标函数

    一棵树将样本分配到了

    T

    T

    T 个叶节点。定义

    I

    j

    =

    {

    i

    x

    i

    叶节点

    j

    }

    I_j = \\{i \\mid x_i \\in \\text{叶节点} j\\}

    Ij={ixi叶节点j} 为被分配到第

    j

    j

    j 个叶节点的样本索引集合。

    由于

    f

    t

    (

    x

    i

    )

    =

    w

    q

    (

    x

    i

    )

    f_t(x_i) = w_{q(x_i)}

    ft(xi)=wq(xi)(即样本

    x

    i

    x_i

    xi 的输出值等于其所在叶节点的权重),目标函数改写为:

    L

    ~

    (

    t

    )

    =

    j

    =

    1

    T

    [

    (

    i

    I

    j

    g

    i

    )

    G

    j

    w

    j

    +

    1

    2

    (

    i

    I

    j

    h

    i

    +

    λ

    )

    H

    j

    +

    λ

    w

    j

    2

    ]

    +

    γ

    T

    \\tilde{\\mathcal{L}}^{(t)} = \\sum_{j=1}^T \\left[ \\underbrace{\\left(\\sum_{i \\in I_j} g_i\\right)}_{G_j} w_j + \\frac{1}{2} \\underbrace{\\left(\\sum_{i \\in I_j} h_i + \\lambda\\right)}_{H_j + \\lambda} w_j^2 \\right] + \\gamma T

    L~(t)=j=1T

    Gj

    iIjgi

    wj+21Hj+λ

    iIjhi+λ

    wj2

    +γT

    定义两个关键的聚合统计量:

    G

    j

    =

    i

    I

    j

    g

    i

    — 叶节点 j 的一阶梯度和

    G_j = \\sum_{i \\in I_j} g_i \\quad \\text{— 叶节点 j 的一阶梯度和}

    Gj=iIjgi— 叶节点 j 的一阶梯度和

    H

    j

    =

    i

    I

    j

    h

    i

    — 叶节点 j 的二阶梯度和

    H_j = \\sum_{i \\in I_j} h_i \\quad \\text{— 叶节点 j 的二阶梯度和}

    Hj=iIjhi— 叶节点 j 的二阶梯度和

    4.5 最优叶权重:闭式解推导

    对每个叶节点

    j

    j

    j,它的子目标函数(只含

    w

    j

    w_j

    wj 的部分)是:

    L

    j

    (

    w

    j

    )

    =

    G

    j

    w

    j

    +

    1

    2

    (

    H

    j

    +

    λ

    )

    w

    j

    2

    \\mathcal{L}_j(w_j) = G_j w_j + \\frac{1}{2}(H_j + \\lambda) w_j^2

    Lj(wj)=Gjwj+21(Hj+λ)wj2

    这是一个关于

    w

    j

    w_j

    wj 的二次函数!对

    w

    j

    w_j

    wj 求导并令其为零:

    L

    j

    w

    j

    =

    G

    j

    +

    (

    H

    j

    +

    λ

    )

    w

    j

    =

    0

    \\frac{\\partial \\mathcal{L}_j}{\\partial w_j} = G_j + (H_j + \\lambda) w_j = 0

    wjLj=Gj+(Hj+λ)wj=0

    最优叶权重(闭式解):

    w

    j

    =

    G

    j

    H

    j

    +

    λ

    \\boxed{w_j^* = -\\frac{G_j}{H_j + \\lambda}}

    wj=Hj+λGj

    这个公式值得多看几眼:

    • 分子

      G

      j

      G_j

      Gj:该叶节点所有样本的一阶梯度之和。如果样本的预测偏低(

      g

      i

      >

      0

      g_i > 0

      gi>0,即

      y

      ^

      <

      y

      \\hat{y} < y

      y^<y),

      G

      j

      G_j

      Gj 为正,则

      w

      j

      w_j^*

      wj 为负——权重向下拉,提高预测值。

    • 分母

      H

      j

      +

      λ

      H_j + \\lambda

      Hj+λ:二阶梯度之和 + 正则化。

      H

      j

      H_j

      Hj 越大(曲率越大),步长越小(更谨慎);

      λ

      \\lambda

      λ 越大,步长也越小(更强的正则化收缩)。

    代入目标函数,得到该树结构下的最优目标值(用于衡量树结构有多好):

    L

    ~

    (

    t

    )

    (

    q

    )

    =

    1

    2

    j

    =

    1

    T

    G

    j

    2

    H

    j

    +

    λ

    +

    γ

    T

    \\boxed{\\tilde{\\mathcal{L}}^{(t)}(q) = -\\frac{1}{2} \\sum_{j=1}^T \\frac{G_j^2}{H_j + \\lambda} + \\gamma T}

    L~(t)(q)=21j=1THj+λGj2+γT

    4.6 分裂增益公式

    有了结构评分函数,我们就可以精确地评估一个分裂有多好。

    分裂前,父节点的"分数"是:

    Score

    parent

    =

    1

    2

    (

    G

    L

    +

    G

    R

    )

    2

    H

    L

    +

    H

    R

    +

    λ

    +

    γ

    ×

    1

    \\text{Score}_{\\text{parent}} = -\\frac{1}{2} \\frac{(G_L + G_R)^2}{H_L + H_R + \\lambda} + \\gamma \\times 1

    Scoreparent=21HL+HR+λ(GL+GR)2+γ×1

    分裂后,左右子节点的"分数"之和是:

    Score

    children

    =

    1

    2

    [

    G

    L

    2

    H

    L

    +

    λ

    +

    G

    R

    2

    H

    R

    +

    λ

    ]

    +

    γ

    ×

    2

    \\text{Score}_{\\text{children}} = -\\frac{1}{2} \\left[ \\frac{G_L^2}{H_L + \\lambda} + \\frac{G_R^2}{H_R + \\lambda} \\right] + \\gamma \\times 2

    Scorechildren=21[HL+λGL2+HR+λGR2]+γ×2

    分裂增益 = Score(分裂后) − Score(分裂前):

    Gain

    =

    1

    2

    [

    G

    L

    2

    H

    L

    +

    λ

    +

    G

    R

    2

    H

    R

    +

    λ

    (

    G

    L

    +

    G

    R

    )

    2

    H

    L

    +

    H

    R

    +

    λ

    ]

    γ

    \\boxed{\\text{Gain} = \\frac{1}{2} \\left[ \\frac{G_L^2}{H_L + \\lambda} + \\frac{G_R^2}{H_R + \\lambda} – \\frac{(G_L + G_R)^2}{H_L + H_R + \\lambda} \\right] – \\gamma}

    Gain=21[HL+λGL2+HR+λGR2HL+HR+λ(GL+GR)2]γ

    🎯 这就是 HistGBM 直方图要计算的公式:给定左右子节点的

    (

    G

    L

    ,

    H

    L

    )

    (G_L, H_L)

    (GL,HL)

    (

    G

    R

    ,

    H

    R

    )

    (G_R, H_R)

    (GR,HR),就能算出分裂增益。而直方图中每个 bin 恰好存储的就是

    (

    G

    b

    ,

    H

    b

    )

    (G_b, H_b)

    (Gb,Hb) 的累加值。


    五、常见损失函数的

    (

    g

    i

    ,

    h

    i

    )

    (g_i, h_i)

    (gi,hi) 计算

    不同损失函数的

    (

    g

    i

    ,

    h

    i

    )

    (g_i, h_i)

    (gi,hi) 不同。下表列出了几种常见损失函数的具体形式:

    5.1 回归损失

    Squared Error(MSE):

    L

    (

    y

    ,

    y

    ^

    )

    =

    1

    2

    (

    y

    y

    ^

    )

    2

    L(y, \\hat{y}) = \\frac{1}{2}(y – \\hat{y})^2

    L(y,y^)=21(yy^)2

    g

    i

    =

    y

    ^

    i

    y

    i

    h

    i

    =

    1

    g_i = \\hat{y}_i – y_i \\qquad h_i = 1

    gi=y^iyihi=1

    💡 注意

    h

    i

    =

    1

    h_i = 1

    hi=1 恒为常数——MSE 是二次函数,曲率处处相同。这也是为什么传统的残差拟合就能做得很好:二阶信息没有提供额外的"曲率差异"。

    Absolute Error(MAE):

    L

    (

    y

    ,

    y

    ^

    )

    =

    y

    y

    ^

    L(y, \\hat{y}) = |y – \\hat{y}|

    L(y,y^)=yy^

    g

    i

    =

    sign

    (

    y

    ^

    i

    y

    i

    )

    h

    i

    =

    0

    g_i = \\text{sign}(\\hat{y}_i – y_i) \\qquad h_i = 0

    gi=sign(y^iyi)hi=0

    ⚠️

    h

    i

    =

    0

    h_i = 0

    hi=0 是问题所在——

    H

    j

    H_j

    Hj 可能为 0,导致

    w

    j

    =

    G

    j

    /

    λ

    w_j^* = -G_j / \\lambda

    wj=Gj/λ,完全依赖

    λ

    \\lambda

    λ 来防止除零。

    Huber Loss:在

    δ

    \\delta

    δ 以内用 MSE,以外用 MAE

    g

    i

    =

    {

    y

    ^

    i

    y

    i

    y

    ^

    i

    y

    i

    δ

    δ

    sign

    (

    y

    ^

    i

    y

    i

    )

    y

    ^

    i

    y

    i

    >

    δ

    g_i = \\begin{cases} \\hat{y}_i – y_i & |\\hat{y}_i – y_i| \\leq \\delta \\\\ \\delta \\cdot \\text{sign}(\\hat{y}_i – y_i) & |\\hat{y}_i – y_i| > \\delta \\end{cases}

    gi={y^iyiδsign(y^iyi)y^iyiδy^iyi>δ

    h

    i

    =

    {

    1

    y

    ^

    i

    y

    i

    δ

    0

    y

    ^

    i

    y

    i

    >

    δ

    h_i = \\begin{cases} 1 & |\\hat{y}_i – y_i| \\leq \\delta \\\\ 0 & |\\hat{y}_i – y_i| > \\delta \\end{cases}

    hi={10y^iyiδy^iyi>δ

    5.2 二分类损失

    Binary Log Loss:

    L

    (

    y

    ,

    y

    ^

    )

    =

    y

    log

    (

    σ

    (

    y

    ^

    )

    )

    (

    1

    y

    )

    log

    (

    1

    σ

    (

    y

    ^

    )

    )

    L(y, \\hat{y}) = -y\\log(\\sigma(\\hat{y})) – (1-y)\\log(1-\\sigma(\\hat{y}))

    L(y,y^)=ylog(σ(y^))(1y)log(1σ(y^)),其中

    σ

    \\sigma

    σ 为 sigmoid 函数

    g

    i

    =

    σ

    (

    y

    ^

    i

    )

    y

    i

    h

    i

    =

    σ

    (

    y

    ^

    i

    )

    (

    1

    σ

    (

    y

    ^

    i

    )

    )

    g_i = \\sigma(\\hat{y}_i) – y_i \\qquad h_i = \\sigma(\\hat{y}_i) \\cdot (1 – \\sigma(\\hat{y}_i))

    gi=σ(y^i)yihi=σ(y^i)(1σ(y^i))

    💡 分类任务中

    h

    i

    1

    h_i \\neq 1

    hi=1,二阶信息包含了概率预测的不确定性。当

    σ

    (

    y

    ^

    i

    )

    0.5

    \\sigma(\\hat{y}_i) \\approx 0.5

    σ(y^i)0.5(不确定),

    h

    i

    0.25

    h_i \\approx 0.25

    hi0.25 最大;当

    σ

    (

    y

    ^

    i

    )

    0

    \\sigma(\\hat{y}_i) \\approx 0

    σ(y^i)0

    1

    1

    1(确定),

    h

    i

    0

    h_i \\approx 0

    hi0

    5.3 Quantile Loss(分位数回归)

    g

    i

    =

    {

    α

    if 

    y

    i

    >

    y

    ^

    i

    α

    1

    if 

    y

    i

    y

    ^

    i

    g_i = \\begin{cases} \\alpha & \\text{if } y_i > \\hat{y}_i \\\\ \\alpha – 1 & \\text{if } y_i \\leq \\hat{y}_i \\end{cases}

    gi={αα1if yi>y^iif yiy^i

    h

    i

    =

    0

    h_i = 0

    hi=0

    训练多个分位数的模型(如 α=0.1, 0.5, 0.9),可以得到预测区间,量化预测的不确定性。scikit-learn 的 HistGradientBoostingRegressor(loss='quantile', quantile=0.9) 正是基于此。

    5.4 梯度计算的关键性质

    性质说明

    (

    g

    i

    ,

    h

    i

    )

    (g_i, h_i)

    (gi,hi) 只依赖当前预测值和真实标签

    每轮迭代开始时即可计算,完全独立于树的构建过程

    h

    i

    0

    h_i \\geq 0

    hi0(对大多数凸损失函数)

    二阶导非负,

    H

    j

    +

    λ

    >

    0

    H_j + \\lambda > 0

    Hj+λ>0 保证分母不为零

    MSE 下

    h

    i

    =

    1

    h_i = 1

    hi=1

    退化为一阶方法,验证框架的一致性

    六、

    (

    g

    i

    ,

    h

    i

    )

    (g_i, h_i)

    (gi,hi) 在 HistGBM 中的作用

    6.1 直方图的存储内容

    HistGBM 的直方图中,每个 bin 存储的不是原始特征值的计数,而是该 bin 内所有样本的梯度统计量:

    Hist

    (

    k

    ,

    b

    )

    =

    (

    i

    :

    x

    i

    k

    bin

    b

    g

    i

    ,

    i

    :

    x

    i

    k

    bin

    b

    h

    i

    ,

    {

    i

    :

    x

    i

    k

    bin

    b

    }

    )

    \\text{Hist}(k, b) = \\left( \\sum_{i: x_{ik} \\in \\text{bin}_b} g_i,\\quad \\sum_{i: x_{ik} \\in \\text{bin}_b} h_i,\\quad |\\{i: x_{ik} \\in \\text{bin}_b\\}| \\right)

    Hist(k,b)=(i:xikbinbgi,i:xikbinbhi,{i:xikbinb})

    有了

    (

    G

    ,

    H

    )

    (G, H)

    (G,H),就可以用分裂增益公式直接评估任何分裂点的效果——这正是第三篇要详细展开的核心。

    6.2 直方图相减的前提

    父节点直方图 = 左子节点直方图 + 右子节点直方图——这个"线性可加性"是因为

    (

    g

    i

    ,

    h

    i

    )

    (g_i, h_i)

    (gi,hi) 在分裂前已经算好,它们对当前迭代是固定的常数。所以:

    G

    right

    =

    G

    parent

    G

    left

    ,

    H

    right

    =

    H

    parent

    H

    left

    G_{\\text{right}} = G_{\\text{parent}} – G_{\\text{left}}, \\quad H_{\\text{right}} = H_{\\text{parent}} – H_{\\text{left}}

    Gright=GparentGleft,Hright=HparentHleft

    6.3 一图总结

    梯度计算(每轮迭代开始时)
    ╔══════════════════════════════════════╗
    ║ 当前预测 F_{m-1}(x_i) ║
    ║ ↓ ║
    ║ 计算 g_i = ∂L/∂F, h_i = ∂²L/∂F² ║
    ║ ↓ ║
    ║ (g_i, h_i) 作为固定统计量 ║
    ║ 输送给直方图构建 ║
    ╚══════════════════════════════════════╝

    直方图构建(第三篇详述)
    ╔══════════════════════════════════════╗
    ║ 对每个 bin b: ║
    ║ G_b = Σ_{i∈bin_b} g_i ║
    ║ H_b = Σ_{i∈bin_b} h_i ║
    ║ ↓ ║
    ║ 分裂增益 = f(G_L, H_L, G_R, H_R) ║
    ╚══════════════════════════════════════╝

    最优叶权重(本篇公式)
    ╔══════════════════════════════════════╗
    ║ w_j* = -G_j / (H_j + λ) ║
    ║ 叶节点输出 = η · w_j* ║
    ╚══════════════════════════════════════╝


    七、一阶 vs 二阶:一个直观的数值例子

    假设一个叶节点中有三个样本,当前预测值都是

    y

    ^

    =

    2.0

    \\hat{y} = 2.0

    y^=2.0

    样本真实值 y损失函数

    g

    i

    g_i

    gi

    h

    i

    h_i

    hi

    A 5.0 MSE 2.0 – 5.0 = -3.0 1
    B 3.0 MSE 2.0 – 3.0 = -1.0 1
    C 1.0 MSE 2.0 – 1.0 = 1.0 1

    一阶方法(传统 GBDT):叶节点输出 = 三个残差的均值 =

    (

    3.0

    1.0

    +

    1.0

    )

    /

    3

    =

    1.0

    (-3.0 – 1.0 + 1.0) / 3 = -1.0

    (3.01.0+1.0)/3=1.0

    二阶方法(XGBoost/HistGBM):

    G

    j

    =

    3.0

    1.0

    +

    1.0

    =

    3.0

    G_j = -3.0 – 1.0 + 1.0 = -3.0

    Gj=3.01.0+1.0=3.0

    H

    j

    =

    1

    +

    1

    +

    1

    =

    3

    H_j = 1 + 1 + 1 = 3

    Hj=1+1+1=3

    w

    j

    =

    3.0

    3

    +

    0

    =

    1.0

    (与一阶一致,因为 MSE 下 

    h

    i

    =

    1

    w_j^* = -\\frac{-3.0}{3 + 0} = 1.0 \\quad \\text{(与一阶一致,因为 MSE 下 } h_i=1 \\text{)}

    wj=3+03.0=1.0(与一阶一致,因为 MSE  hi=1

    引入 L2 正则化(

    λ

    =

    1.0

    \\lambda = 1.0

    λ=1.0):

    w

    j

    =

    3.0

    3

    +

    1

    =

    0.75

    w_j^* = -\\frac{-3.0}{3 + 1} = 0.75

    wj=3+13.0=0.75

    正则化将权重从 1.0 收缩到 0.75——防止模型对某几个样本"过度反应"。

    现在换成二分类任务(LogLoss):

    样本预测概率真实标签

    g

    i

    g_i

    gi

    h

    i

    h_i

    hi

    D 0.9 (很确定是正类) 1 0.9 – 1 = -0.1 0.9×0.1 = 0.09
    E 0.5 (不确定) 0 0.5 – 0 = 0.5 0.5×0.5 = 0.25

    注意

    h

    D

    =

    0.09

    h_D = 0.09

    hD=0.09(几乎确定,曲率小),

    h

    E

    =

    0.25

    h_E = 0.25

    hE=0.25(最不确定,曲率大)。二阶信息自然地给不确定样本更大的影响权重——没有一阶方法可以做这种区分。


    八、小结

    本篇完成了梯度提升理论的完整数学搭建:

    层次内容核心公式
    Friedman 框架 Boosting = 函数空间的梯度下降

    r

    i

    m

    =

    L

    /

    F

    r_{im} = -\\partial L / \\partial F

    rim=L/F

    伪残差 负梯度方向,替代普通残差(MSE 时两者等价)

    r

    i

    m

    r_{im}

    rim 随损失函数而变

    二阶泰勒展开 用 Hessian 捕捉曲率信息

    L

    g

    i

    f

    t

    +

    1

    2

    h

    i

    f

    t

    2

    \\mathcal{L} \\approx g_i f_t + \\frac{1}{2} h_i f_t^2

    Lgift+21hift2

    最优叶权重 二次函数的闭式解

    w

    j

    =

    G

    j

    /

    (

    H

    j

    +

    λ

    )

    w_j^* = -G_j / (H_j + \\lambda)

    wj=Gj/(Hj+λ)

    分裂增益 量化分裂好坏的标准

    Gain

    =

    1

    2

    [

    G

    L

    2

    /

    (

    H

    L

    +

    λ

    )

    +


    ]

    γ

    \\text{Gain} = \\frac{1}{2}[G_L^2/(H_L+\\lambda) + \\dots] – \\gamma

    Gain=21[GL2/(HL+λ)+]γ

    直方图统计量 直方图 bin 中存储的内容

    (

    G

    b

    ,

    H

    b

    )

    =

    (

    g

    i

    ,

    h

    i

    )

    (G_b, H_b) = (\\sum g_i, \\sum h_i)

    (Gb,Hb)=(gi,hi)

    关键洞察:

    • (

      g

      i

      ,

      h

      i

      )

      (g_i, h_i)

      (gi,hi) 是贯通整个 HistGBM 系统的"血液"——每轮迭代开始时计算一次,然后被直方图聚合、被增益公式使用、被叶权重公式使用

    • 二阶信息的价值在 MSE 场景下不显著(

      h

      i

      =

      1

      h_i=1

      hi=1 为常数),但在分类、分位数回归等任务中提供了额外的曲率信息

    • 理解

      (

      g

      i

      ,

      h

      i

      )

      (g_i, h_i)

      (gi,hi) 是理解下一篇直方图加速的必要前提

    下一篇将把这些数学公式与工程实现对接——直方图分箱如何将 n 个样本压缩为 B 个 bin,如何构建梯度直方图,以及直方图相减技巧如何将分裂速度提升数千倍。


    参考资料

  • Friedman, J. H. (2001). Greedy function approximation: A gradient boosting machine. Annals of Statistics, 29(5), 1189–1232. — 梯度提升框架的奠基性论文
  • Chen, T., & Guestrin, C. (2016). XGBoost: A scalable tree boosting system. KDD 2016. — 二阶泰勒展开、最优叶权重和分裂增益公式的原始推导
  • Ke, G., Meng, Q., Finley, T., et al. (2017). LightGBM: A highly efficient gradient boosting decision tree. NeurIPS 2017. — 直方图方法和 Leaf-wise 生长的核心论文
  • Bishop, C. M. (2006). Pattern Recognition and Machine Learning. Springer. — 损失函数和优化理论的极好参考
  • XGBoost 官方文档:模型介绍
  • LightGBM 官方优化特性文档
  • 赞(0)
    未经允许不得转载:171主机测评 » 【HistGBM 系列②】梯度提升的数学框架与二阶优化
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址