为啥 gbm() 在这个最小示例中给出的结果与 h2o.gbm() 不同?

Posted

技术标签:

【中文标题】为啥 gbm() 在这个最小示例中给出的结果与 h2o.gbm() 不同?【英文标题】:Why does gbm() give different results than h2o.gbm() in this minimal example?为什么 gbm() 在这个最小示例中给出的结果与 h2o.gbm() 不同? 【发布时间】:2017-05-03 23:33:05 【问题描述】:

修补梯度提升,我注意到 R 的 gbm 包在最小示例中产生的结果与 h2o 不同。为什么?


数据

library(gbm)
library(h2o)

h2o.init()

train <- data.frame(
  X1 = factor(c("A", "A", "A", "B", "B")),
  X2 = factor(c("A", "A", "B", "B", "B")),
  Y = c(0, 1, 3, 4, 7)
)
  X1 X2 Y
1  A  A 0
2  A  A 1
3  A  B 3
4  B  B 4
5  B  B 7

gbm

# (gbm, 1 round, mae)
model.gbm <- gbm(
  Y ~ X1 + X2, data = train, distribution="laplace", n.tree = 1, shrinkage = 1, n.minobsinnode=1, bag.fraction=1, 
  interaction.depth = 1, verbose=TRUE
)
train$Pred.mae.gbm1 <- predict(model.gbm, newdata=train, n.trees=model.gbm$n.trees)

# (h2o, 1 round, mae)
model.h2o <- h2o.gbm(
  x=c("X1", "X2"), y="Y", training_frame=as.h2o(train), distribution="laplace", ntrees=1, max_depth=1, 
  learn_rate = 1, min_rows=1
)
train$Pred.mae.h2o1 <- as.data.frame(h2o.predict(model.h2o, as.h2o(train)))$predict

结果

train
  X1 X2 Y Pred.mae.gbm1 Pred.mae.h2o1
1  A  A 0           1.0           0.5
2  A  A 1           1.0           0.5
3  A  B 3           1.0           4.0
4  B  B 4           5.5           4.0
5  B  B 7           5.5           4.0

【问题讨论】:

【参考方案1】:

它们是完全独立的实现,我怀疑是否已经根据您使用它的方式进行了调整或设计(即单个树,min_rows 设置为 1)。在这种情况下,看起来 R 的 gbm 使用其单棵树来正确学习“B”输入,而 h2o.gbm 则专注于“A”输入。

当您开始使用真实数据和真实设置时,可能仍然存在差异。有很多你没有触及的参数(至少有h2o.gbm(),这是我熟悉的那个)。还有一个随机元素:尝试一百个 seed 到 h2o.gbm() 的值,以及在 R 的 gbm 之前的常量 set.seed(),您可能会在其中至少一个上得到相同的结果。

【讨论】:

以上是关于为啥 gbm() 在这个最小示例中给出的结果与 h2o.gbm() 不同?的主要内容,如果未能解决你的问题,请参考以下文章

gbm::interact.gbm 与 dismo::gbm.interactions

在 R 中使用 gbm 进行梯度提升,分布 =“bernoulli”

为啥在这个最小示例中 Trident 不调用 ack() 或 fail()?

这些集合操作是啥,为啥它们会给出不同的结果?

为啥 maxMerge() 给出的结果与 sumMerge() 的 max() 不同?

GBM Bernoulli 不返回带有 NaN 的结果