DART 提升器

XGBoost 主要结合了大量回归树和较小的学习率。在这种情况下,早期添加的树影响显著,而后期添加的树影响较小。

Vinayak 和 Gilad-Bachrach 提出了一种新方法,将深度神经网络领域的 dropout 技术添加到提升树中,并在某些情况下报告了更好的结果。

这是对新的树提升器 dart 的说明。

原始论文

Rashmi Korlakai Vinayak, Ran Gilad-Bachrach. “DART: Dropouts meet Multiple Additive Regression Trees.” [PMLR, arXiv].

特性

  • 通过丢弃树来解决过拟合。

    • 可能会避免生成琐碎的树(用于修正微小误差)。

由于训练中引入的随机性,预计会有以下几点差异

  • 训练可能比 gbtree 慢,因为随机 dropout 阻止了预测缓冲区的利用。

  • 由于随机性,提前停止可能不稳定。

工作原理

  • 在第 \(m\) 轮训练中,假设选中 \(k\) 棵树被丢弃。

  • \(D = \sum_{i \in \mathbf{K}} F_i\) 为被丢弃树的叶子得分,令 \(F_m = \eta \tilde{F}_m\) 为新树的叶子得分。

  • 目标函数如下

\[\mathrm{Obj} = \sum_{j=1}^n L \left( y_j, \hat{y}_j^{m-1} - D_j + \tilde{F}_m \right) + \Omega \left( \tilde{F}_m \right).\]
  • \(D\)\(F_m\) 存在过冲,因此使用比例因子

\[\hat{y}_j^m = \sum_{i \not\in \mathbf{K}} F_i + a \left( \sum_{i \in \mathbf{K}} F_i + b F_m \right) .\]

参数

提升器 dart 继承自 gbtree 提升器,因此它支持 gbtree 支持的所有参数,例如 eta, gamma, max_depth 等。

附加参数如下所述

  • sample_type: 采样算法类型。

    • uniform: (默认) 均匀选择被丢弃的树。

    • weighted: 根据权重比例选择被丢弃的树。

  • normalize_type: 归一化算法类型。

    • tree: (默认) 新树与每棵被丢弃的树具有相同的权重。

    \[\begin{split}a \left( \sum_{i \in \mathbf{K}} F_i + \frac{1}{k} F_m \right) &= a \left( \sum_{i \in \mathbf{K}} F_i + \frac{\eta}{k} \tilde{F}_m \right) \\ &\sim a \left( 1 + \frac{\eta}{k} \right) D \\ &= a \frac{k + \eta}{k} D = D , \\ &\quad a = \frac{k}{k + \eta}\end{split}\]
    • forest: 新树与被丢弃树的总和(森林)具有相同的权重。

    \[\begin{split}a \left( \sum_{i \in \mathbf{K}} F_i + F_m \right) &= a \left( \sum_{i \in \mathbf{K}} F_i + \eta \tilde{F}_m \right) \\ &\sim a \left( 1 + \eta \right) D \\ &= a (1 + \eta) D = D , \\ &\quad a = \frac{1}{1 + \eta} .\end{split}\]
  • rate_drop: dropout 比率。

    • 范围: [0.0, 1.0]

  • skip_drop: 跳过 dropout 的概率。

    • 如果跳过 dropout,则新树的添加方式与 gbtree 相同。

    • 范围: [0.0, 1.0]

示例脚本

import xgboost as xgb
# read in data
dtrain = xgb.DMatrix('demo/data/agaricus.txt.train?format=libsvm')
dtest = xgb.DMatrix('demo/data/agaricus.txt.test?format=libsvm')
# specify parameters via map
param = {'booster': 'dart',
         'max_depth': 5, 'learning_rate': 0.1,
         'objective': 'binary:logistic',
         'sample_type': 'uniform',
         'normalize_type': 'tree',
         'rate_drop': 0.1,
         'skip_drop': 0.5}
num_round = 50
bst = xgb.train(param, dtrain, num_round)
preds = bst.predict(dtest)