泊松偏差(xgboost 与 gbm 与回归)

机器算法验证 回归 泊松分布 助推
2022-03-04 07:18:22

我想知道使用 byxgboost工具(极端梯度提升)在泊松回归中哪个是偏差表达式。

根据源码,评价函数为:

struct EvalPoissonNegLogLik : public EvalEWiseBase {

const char *Name() const override {

return "poisson-nloglik";

}

inline bst_float EvalRow(bst_float y, bst_float py) const {

const bst_float eps = 1e-16f;

if (py < eps) py = eps;

return common::LogGamma(y + 1.0f) + py - std::log(py) * y;

}

}

所以偏差(在R中)应该是这样的:

poisson_deviance <- function(y, py, eps) {

mean(LogGamma(y + 1.0f) + pmax(py, eps) - log(pmax(py, eps)) * y);

}

我在这里有两个问题:

1)如何翻译LogGamma成R?我发现几个链接谷歌搜索'loggamma',似乎每种语言都理解这个术语的不同表达。

2)如何处理曝光?我知道我们需要设置为 xgbMatrix 使用:

setinfo(xgbMatrix, "base_margin", log(exposure))

但是在EvalPoissonNegLogLik我再也没有看到偏移量的代码中,所以我推断出我们唯一需要的是添加log(exposure)到预测器:

poisson_deviance <- function(y, py, exposure, eps) {

mean(LogGamma(y + 1.0f) + pmax(py + log(exposure), eps) - log(pmax(py + 

log(exposure), eps)) * y);

}

梯度提升gbmR 包用于泊松回归的偏差公式为:

poisson_deviance <- function(y, py) {mean(y*py - exp(py))}

py(也有上限eps

正如您在本文档的最后一页中看到的:

泊松回归是否使用相同的错误gbmxgboost这种偏差的表达似乎与 中使用的不同xgboost

最后,这里根据 B.5.3 的泊松回归中的偏差公式 应该是:

2 * mean(y * log(y / py) - (y - py))

那是其他不同的公式。

我将不胜感激任何帮助以了解两者的原因gbmxgboost使用其他偏差公式。

1个回答

它没有详细记录,但我已经检查了 xgboost 的源代码,并且我已经为 count:poisson 目标确定了以下内容:

  1. 它使用带有日志链接的泊松可能性。
  2. base_margin参数在线性尺度上,而不是响应尺度上。随着助推轮的进行,新的树也被添加到线性尺度上。
  3. xgboost 泊松负对数似然公式是正确的,但它与泊松偏差略有不同。然而,负对数似然和偏差非常接近,并且渐近等效于因子 2。
  4. 设置base_marginlog(exposure)等同于包括一个log(exposure)偏移项。

关于这些点的更多细节:

LogGamma 是 gamma 函数的对数,是阶乘的连续扩展。具体来说,Γ(n)=(n1)!对于整数n. 因此,LogGamma(y + 1) = factorial(y). LogGamma 项表示log(y!)完全泊松对数似然中的术语。(该术语通常从对数似然表达式中省略,因为它不影响优化。)

根据斯特林的近似,log(y!)ylog(y)y. 用这个近似值替换 LogGamma,并替换py=exp(p)(即用对数链接的平均值替换线性预测器)产生y * log(y / py) - (y - py). 这几乎是标准的泊松偏差,只是它缺少因子 2。

您为 GBM 找到的公式不是标准的泊松偏差,尽管它与加法(y 相关)常数相同。令人困惑的是py,您的 GBM 公式中的实际上是线性比例预测,而不是响应比例,而在其他公式py中是响应,即 y 的预测平均值。

您不需要添加log(exposure)到目标公式。您需要做的就是设置base_margin=log(exposure)这确保了提升序列中的第一个和项是log(exposure)随后的增强轮增加了更多项,但初始偏移量永远不会被删除或更改。