1204.机器学习-集成学习-2.Boosting-6.NGBoost

回归模型常只吐一个数:房价预测 320 万。业务还想问「大概有多不确定」——是窄分布的 320,还是方差很大的 320。经典 GBDT/XGBoost/LightGBM/CatBoost 默认优化点估计(或分类概率的标量输出),要完整条件分布,需要换目标。

自然梯度提升(Natural Gradient Boosting,NGBoost,约 2019)把提升对象从「一个预测值」改成分布的参数(如正态的均值与尺度),并用自然梯度稳定多参数更新,从而得到 $P(y\mid x)$ 而不只是 $\hat y(x)$。

段末注释:NGBoost 仍属 Boosting,但优化的是评分规则下的分布参数;发表晚于 CatBoost/LightGBM。后文沿用 NGBoost。

配图目录:./1204.机器学习-集成学习-2.Boosting-6.NGBoost/


1. 一句话定位

维度 一句话
学习范式 监督学习;概率提升(约 2019)
输入 → 输出 特征 $\mathbf{x}$ → 条件分布参数(进而可采样、取分位数、算区间)
在优化什么 多参数 Boosting + 自然梯度,最小化合适评分规则(如对数分数)

出现背景:Duan 等,NGBoost: Natural Gradient Boosting for Probabilistic Prediction(arXiv 2019;ICML 2020)。当时主流 GBDT 实现擅长点预测,条件分布与不确定性估计不统一;NGBoost 把提升对象改为分布参数,并用自然梯度稳定多参数训练。

图 1 点估计 vs 输出整段条件分布

比喻:普通 Boosting 在改「答案写多少」;NGBoost 在改「答案服从的那条钟形曲线长什么样」——既抬均值,也收/放宽度。


2. 直觉:发展坐标上的位置

AdaBoost → GBDT → XGBoost → CatBoost → LightGBM → NGBoost

前五代多在「点预测 / 分类分数」上打磨速度与类别;NGBoost 转向不确定性:同一套树型弱学习器,分别(或联合)提升分布的各个参数。


3. 核心链路

  1. 选定分布族(如 Normal)与评分规则(如对数似然 / 对数分数)。
  2. 当前模型给出整组参数 $\theta(x)$;对正态常用 $(\mu(x),\rho(x))$,其中 $\rho=\log\sigma$,从而 $\sigma(x)=e^{\rho(x)}$。
  3. 对每个样本算参数空间上的得分,再经 Fisher 信息得到自然梯度 $\tilde u(x)$(比普通梯度更适合多参数联立更新)。
  4. 每一个分布参数各拟合一棵(或一组)基学习器,沿自然梯度方向更新该参数函数;多轮叠加。

正态、最大化对数似然时,自然梯度有干净形式(教学常用):

$$
\tilde u_{\mu}=y-\mu,\qquad
\tilde u_{\rho}=\frac12\left(-1+\frac{(y-\mu)^2}{\sigma^2}\right).
$$

(普通得分是 $\partial\mathcal{L}/\partial\mu=(y-\mu)/\sigma^2$ 等;乘 Fisher 逆之后才得到上式。手算跟自然梯度,与 NGBoost 主路径一致。)

读输出:得到的是分布,不是单个数;点估计取均值/中位数,区间取分位数。
模块化:可换分布、评分规则、基学习器(实现以库为准)。


4. 手算完整实例:联立提升 $\mu$ 与 $\log\sigma$(2 轮)

A. 问题与原始表

假设 ( y\mid x\sim\mathcal{N}(\mu(x),\sigma(x)^2) )。与只吐 (\hat y) 的 GBDT 不同:每轮要同时改位置(预测的y值)尺度(概率分布、置信度)(经 (\rho=\log\sigma)),才能得到条件分布。

(i) (x) (y)
1 0 0
2 1 2
3 2 2

补充核心公式(正态分布自然梯度)
损失函数为负对数似然 (\text{NLL}=-\log p(y|\mu,\sigma))。对于 (\mu) 和 (\rho=\log\sigma),自然梯度(经费雪信息矩阵调整后)简化为:
[
\tilde g_{\mu}=y-\mu,\qquad \tilde g_{\rho}=\frac{1}{2}\left(\frac{(y-\mu)^2}{\sigma^2}-1\right)
]
后续所有 ( \tilde u_\mu, \tilde u_\rho ) 均依此式计算,无需记忆复杂矩阵求逆。


B. 初始化

[
\mu_0=\bar y=\frac{0+2+2}{3}=\frac43,\qquad
\sigma_0^2=\frac1n\sum_i(y_i-\mu_0)^2=\frac89,\qquad
\sigma_0=\sqrt{\frac89}\approx0.943,\qquad
\rho_0=\log\sigma_0\approx-0.059.
]

起步时 (\mu_0,\rho_0) 对所有 (x) 相同(常数函数)。学习率 (\nu=1)。
弱学习器为 stump(单层决策树):相邻 (x) 中点形成候选 (\tau\in{0.5,,1.5});对每个候选,按阈值分叶

$$
\mathrm{leaf}(x)=\begin{cases}
\text{左叶}, & x<\tau \
\text{右叶}, & x\ge\tau
\end{cases}
$$


C. 训练过程(补充:第二轮“双候选同为0”的显式说明)

第 1 轮:在 ((\mu_0,\sigma_0)) 上算自然梯度。

(i) x y (y-\mu_0) ((y-\mu_0)^2/\sigma_0^2) (\tilde u_{\mu}) (\tilde u_{\rho})
1 0 0 (-\frac43) 2 (-\frac43) (+0.5)
2 1 2 (+\frac23) 0.5 (+\frac23) (-0.25)
3 2 2 (+\frac23) 0.5 (+\frac23) (-0.25)

对某个候选 (\tau),叶子内部预测值 (\Delta) 取该叶内所有样本自然梯度的均值。拟合残差 = 左叶内各样本 ((\tilde u-\Delta)^2) 之和 + 右叶内各样本 ((\tilde u-\Delta)^2) 之和((\mu) 与 (\rho) 两路相加)。
以候选 (\tau=1.5) 为例(左叶含样本1,2;右叶含样本3):

  • 左叶 (\tilde u_\mu) 均值 = ((-4/3 + 2/3)/2 = -1/3),(\tilde u_\rho) 均值 = ((0.5 + (-0.25))/2 = 0.125)。
  • 左叶残差:
    样本1:((-4/3+1/3)^2 + (0.5-0.125)^2 = 1 + 0.1406);
    样本2:((2/3+1/3)^2 + (-0.25-0.125)^2 = 1 + 0.1406)。
  • 右叶仅样本3,残差为 0。
  • 总残差 (= (1+0.1406)+(1+0.1406)+0 = 2.2812)(与表中 2.281 吻合)。
    同理,(\tau=0.5) 时左右叶内梯度完全相同,总残差为 0。故选择 (\tau=0.5)。

候选比较:

候选 (\tau) 左叶 右叶 拟合后 (\sum(\tilde u-\Delta)^2)
(0.5) (t_1) (t_2,t_3) (\mathbf{0})(最优)
(1.5) (t_1,t_2) (t_3) (2.281)

故 (\tau_1^*=0.5)(不是 (1.5)):(0.5) 把「(y=0)」与「两个 (y=2)」切开,两叶内自然梯度已各自相同;(1.5) 却把冲突的 (t_1,t_2) 捆在左叶,残差大。

  • 左叶:(\Delta\mu_1=-\frac43),(\Delta\rho_1=+0.5)
  • 右叶:(\Delta\mu_1=\frac23),(\Delta\rho_1=-0.25)
(i) (\mu_1) (\rho_1) (\sigma_1)
1 (\frac43-\frac43=0) (\approx-0.059+0.5=+0.441) (\approx1.554)
2 (\frac43+\frac23=2) (\approx-0.059-0.25=-0.309) (\approx0.734)
3 (2) 同右 (\approx0.734)

平均 NLL:约 (1.360\to0.860)。均值已分别贴到各点的 (y);右叶尺度收窄,左叶因单点且起步方差大,(\sigma) 暂放宽。


第 2 轮:在 ((\mu_1,\sigma_1)) 上重算自然梯度;重新枚举 (\tau)(不沿用「拍脑袋」,即使上轮已是 (0.5) 也要再比)。

(i) (\mu_1) (\sigma_1) (\tilde u_{\mu}) (\tilde u_{\rho})
1 (0) (\approx1.554) (0) (-0.5)
2 (2) (\approx0.734) (0) (-0.5)
3 (2) (\approx0.734) (0) (-0.5)

此时 (\tilde u_{\mu}) 全 (0),(\tilde u_{\rho}) 全 (-0.5)。

补充关键说明:对于 (\tau=0.5),左叶{1}均值为 ((-0.5)),右叶{2,3}均值也为 ((-0.5)),总残差 = 0。
对于 (\tau=1.5),左叶{1,2}均值 ((-0.5)),右叶{3}均值也为 ((-0.5)),总残差同样 = 0。
两候选拟合残差同为 0,因此树结构不唯一;本例按惯例取首个最优切分 (\tau_2^*=0.5)(与 (\tau=1.5) 在此轮完全等价)。

(\Delta\mu_2=0),(\Delta\rho_2=-0.5)(左右叶相同)。

(i) (\mu_2) (\sigma_2=\sigma_1,e^{-0.5})
1 (0) (\approx0.943)
2 (2) (\approx0.445)
3 (2) (\approx0.445)

平均 NLL:约 (0.860\to0.360)。本轮只收尺度:全局乘 (e^{-0.5}),右叶不确定性继续下降。


D. 可部署对象(补充:显式存储结构)

训练完成后,部署时不需要存储庞大的表格,只需存储三部分:

  1. 初始值:(\mu_0 = 4/3),(\rho_0 = -0.059)。
  2. 第1轮树((T_1)):切分阈值 (\tau=0.5)。
    • 左叶((x<0.5)):((\Delta\mu, \Delta\rho) = (-4/3,\ +0.5))
    • 右叶((x\ge0.5)):((\Delta\mu, \Delta\rho) = (2/3,\ -0.25))
  3. 第2轮树((T_2)):切分阈值 (\tau=0.5)。
    • 左叶((x<0.5)):((\Delta\mu, \Delta\rho) = (0,\ -0.5))
    • 右叶((x\ge0.5)):((\Delta\mu, \Delta\rho) = (0,\ -0.5))

即得到可部署的判定规则:

[
\mu_2(x)=\mu_0+\sum_{m=1}^{2} \Delta\mu_m(x),\qquad
\rho_2(x)=\rho_0+\sum_{m=1}^{2} \Delta\rho_m(x),\qquad
\sigma_2(x)=\exp(\rho_2(x)).
]


E. 预测 / 推断(补充:逐树遍历的详细步骤)

新样本 (x=2)(训练内)

  • 初始:(\mu=4/3,\ \rho=-0.059)。
  • (T_1):(2\ge0.5) 入右叶,累加 ((+2/3,\ -0.25)) → (\mu=2,\ \rho=-0.309)。
  • (T_2):(2\ge0.5) 入右叶,累加 ((0,\ -0.5)) → (\mu=2,\ \rho=-0.809)。
  • 最终:(\sigma=\exp(-0.809)\approx0.445),90% 分位约 (2+1.282\times0.445\approx2.57)。

新样本 (x=0.5)(边界注意)

  • 规则为 (x<\tau) 左叶,否则右叶。(0.5<0.5) 为假 → 两棵树均入右叶
  • (T_1):累加 ((+2/3,\ -0.25));(T_2):累加 ((0,\ -0.5))。
  • 最终:(\mu=2,\ \sigma\approx0.445)(与 (t_2,t_3) 同分布)。

新样本 (x=0.2)(左叶)

  • (T_1) 入左叶:累加 ((-4/3,\ +0.5));(T_2) 入左叶:累加 ((0,\ -0.5))。
  • 最终:(\mu=4/3-4/3=0),(\rho=-0.059+0.5-0.5=-0.059),(\sigma\approx0.943)。
  • 含义:左侧只有 (y=0) 一个训练点,尺度保留接近全局起步量级,不确定性高于右侧两个一致的 (y=2)。

本例为凸显梯度流动方向,设学习率 (\nu=1) 且省略了每轮的步长线搜索(Line Search)。实际 ngboost 库中,每轮会通过 scipy 优化器自动寻找最优步长,并配合更小的学习率(如 0.1)及更多树(如 500 棵)来防止过拟合,但底层“计算自然梯度 → 训练多变量树 → 累加更新”的迭代逻辑与本例完全一致。*

段末注释:完整库内还可能对多参数做更稳的自然梯度与线搜索;数字约三位小数。要点:$\mu,\sigma$ 由数据初始化;每轮比较候选阈值;两参数都用自然梯度更新。

5. 适用 / 不适用

维度 判定 要求或边界 具体例子
特征 适用 中等维表格;分布假设说得通 住院天数、手术时长:数值临床特征
特征 不适用 原始图像端到端;或 $y$ 明显多峰却硬套单峰正态 双峰房价(学区/非学区)却固定 Normal
训练目标 适用 要 $P(y\mid x)$、区间、校准不确定性 库存:预测需求分布再定安全库存
训练目标 不适用 只要排个序/点 AUC,且极致速度 CTR 排行榜只看 AUC,用 LightGBM/XGB 更合适
训练数据 适用 有标签连续(或合适离散)响应;样本量够估尺度 数千至数万带 $y$ 的回归样本
训练数据 不适用 $y$ 噪声定义混乱;样本少到 $\sigma$ 估不稳 50 条样本还解释「精确 95% 区间」

6. 优缺点与常见坑

优点:直接概率预测;接口相对清晰;与 sklearn 风格接近。
缺点:速度与竞赛点分常不如 XGB/LGBM/CatBoost;分布族选错会系统偏;生态与部署工具链弱于「三巨头」。

:用点估计 RMSE 唯一选模,丢掉区间质量;忽略校准;把 NGBoost 当默认表格冠军。


7. 最小可运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
"""NGBoost:回归输出正态条件分布,打印均值与分位数。"""
from ngboost import NGBRegressor
from ngboost.distns import Normal
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split

X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)

ngb = NGBRegressor(Dist=Normal, n_estimators=200, verbose=False, random_state=42)
ngb.fit(X_train, y_train)

y_dists = ngb.pred_dist(X_test)
print("mean[:5]:", y_dists.mean()[:5])
print("90% quantile[:5]:", y_dists.ppf(0.9)[:5])

说明:公开数据集示例,与上文正态均值手算表无关。

重要配置参数(ngboost.NGBRegressor / NGBClassifier

参数(库内常用名) 训练中的作用与影响 参考起点 / 常用范围 配置指导
Dist 输出分布族(如 Normal);决定要估哪些参数、如何读分位数 连续目标常先 Normal 分布选错 → 分位数/校准会系统性偏;先诊断残差形态再换族
n_estimators 提升轮数;过多易过拟合且更慢 100~500;看验证 NLL/CRPS 概率任务用恰当评分早停,不要只看 RMSE
learning_rate 自然梯度步长;过大训练不稳 常偏小(如 0.01~0.1 量级,以库默认/文档为准) 不稳先降 lr;再考虑加轮数
minibatch_frac 每轮样本比例;<1 加速并加噪声 大数据可 <1;小数据可 1.0 与方差估计稳定性权衡;过小可能估歪尺度参数
Base(基学习器) 默认树等;复杂度影响分布参数拟合能力 先用库默认 先调分布与轮数/lr,再动基学习器深度

8. 和近邻算法怎么挑

需求 更优先考虑
教学改权重 AdaBoost
残差框架 GBDT
通用点预测强基线 XGBoost
类别多、有序防泄漏 CatBoost
海量行要快 LightGBM
条件分布 / 预测区间 NGBoost

9. 小结

  • NGBoost = Boosting 分布参数 + 自然梯度
  • 需要不确定性时再用;点预测竞赛默认仍看 XGB/LGBM/CatBoost。
  • 最易踩的坑:分布族与评分规则不匹配数据,却只看点 RMSE

参考文献

  1. Duan T. et al. NGBoost: Natural Gradient Boosting for Probabilistic Prediction. ICML 2020(arXiv:1910.03225 2019).
  2. NGBoost 文档 / GitHub
-------------本文结束感谢您的阅读-------------