【问题标题】:XGBoost - Poisson distribution with varying exposure / offsetXGBoost - 具有不同曝光/偏移的泊松分布
【发布时间】:2016-06-10 04:36:47
【问题描述】:

我正在尝试使用 XGBoost 对不等长曝光期生成的数据的索赔频率进行建模,但无法让模型正确处理曝光。我通常会通过将 log(exposure) 设置为偏移量来做到这一点 - 你能在 XGBoost 中做到这一点吗?

(此处发布了类似的问题:xgboost, offset exposure?

为了说明这个问题,下面的 R 代码生成了一些带有字段的数据:

  • x1, x2 - 因子(0 或 1)
  • 暴露 - 观察数据的政策期限长度
  • 频率 - 每单位曝光的平均索赔数
  • 索赔 - 观察到的索赔数量 ~Poisson(frequency*exposure)

目标是使用 x1 和 x2 预测频率 - 真实模型是:如果 x1 = x2 = 1,频率 = 2,否则频率 = 1。

暴露不能用于预测频率,因为它在政策开始时是未知的。我们可以使用它的唯一方法是:预期索赔数量 = 频率 * 曝光。

代码尝试通过以下方式使用 XGBoost 进行预测:

  1. 将曝光设置为模型矩阵中的权重
  2. 将日志(曝光)设置为偏移量

在下面,我展示了如何处理树 (rpart) 或 gbm 的情况。

set.seed(1)
size<-10000
d <- data.frame(
  x1 = sample(c(0,1),size,replace=T,prob=c(0.5,0.5)),
  x2 = sample(c(0,1),size,replace=T,prob=c(0.5,0.5)),
  exposure = runif(size, 1, 10)*0.3
)
d$frequency <- 2^(d$x1==1 & d$x2==1)
d$claims <- rpois(size, lambda = d$frequency * d$exposure)

#### Try to fit using XGBoost
require(xgboost)
param0 <- list(
  "objective"  = "count:poisson"
  , "eval_metric" = "logloss"
  , "eta" = 1
  , "subsample" = 1
  , "colsample_bytree" = 1
  , "min_child_weight" = 1
  , "max_depth" = 2
)

## 1 - set weight in xgb.Matrix

xgtrain = xgb.DMatrix(as.matrix(d[,c("x1","x2")]), label = d$claims, weight = d$exposure)
xgb = xgb.train(
  nrounds = 1
  , params = param0
  , data = xgtrain
)

d$XGB_P_1 <- predict(xgb, xgtrain)

## 2 - set as offset in xgb.Matrix
xgtrain.mf  <- model.frame(as.formula("claims~x1+x2+offset(log(exposure))"),d)
xgtrain.m  <- model.matrix(attr(xgtrain.mf,"terms"),data = d)
xgtrain  <- xgb.DMatrix(xgtrain.m,label = d$claims)

xgb = xgb.train(
  nrounds = 1
  , params = param0
  , data = xgtrain
)

d$XGB_P_2 <- predict(model, xgtrain)

#### Fit a tree
require(rpart)
d[,"tree_response"] <- cbind(d$exposure,d$claims)
tree <- rpart(tree_response ~ x1 + x2,
              data = d,
              method = "poisson")

d$Tree_F <- predict(tree, newdata = d)

#### Fit a GBM

gbm <- gbm(claims~x1+x2+offset(log(exposure)), 
           data = d,
           distribution = "poisson",
           n.trees = 1,
           shrinkage=1,
           interaction.depth=2,
           bag.fraction = 0.5)

d$GBM_F <- predict(gbm, newdata = d, n.trees = 1, type="response")

【问题讨论】:

    标签: r offset poisson xgboost


    【解决方案1】:

    至少使用 R 中的 glm 函数,使用 family=poisson(link='log') 建模 count ~ x1 + x2 + offset(log(exposure)) 等效于使用 family=poisson(link='log')weight=exposure 建模 I(count/exposure) ~ x1 + x2。也就是说,通过曝光来标准化您的计数以获得频率,并以曝光为权重对频率进行建模。当使用glm 进行泊松回归时,您的估计系数在这两种情况下应该是相同的。使用示例数据集亲自尝试

    我不确定objective='count:poisson' 对应的是什么,但我希望将您的目标变量设置为频率(计数/曝光)并使用曝光作为xgboost 中的权重,这将是当曝光为变化无常。

    【讨论】:

    • 感谢 Vinh。这是我尝试过的选项之一,但在简单的情况下似乎没有按预期工作。我相信我现在已经找到了解决方案并将其发布在这里。
    【解决方案2】:

    我现在已经弄清楚了如何使用 setinfo 将 base_margin 属性更改为偏移量(作为线性预测器),即:

    setinfo(xgtrain, "base_margin", log(d$exposure))
    

    【讨论】:

    • 这对 xgboost 来说足够了吗?我的意思是,如果你指定了base_margin,你还需要在xgb.DMatrix 中指定权重吗?谢谢!
    • base_margin:基本边距是 Xgboost 将从中提升的基本预测;您如何建议,base_margin 将作为传统意义上的泊松问题的偏移量?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2018-02-10
    相关资源
    最近更新 更多