gpt4 book ai didi

r - 如何重现H2o GBM类概率计算

转载 作者:行者123 更新时间:2023-12-01 04:40:04 25 4
gpt4 key购买 nike

我一直在使用h2o.gbm解决分类问题,并想进一步了解它如何计算类概率。首先,我尝试重新计算只有一棵树的gbm的类概率(通过查看叶子中的观察结果),但是结果非常令人困惑。

让我们假设我的正类变量是“ buy”,而负类变量是“ not_buy”,我有一个训练集“ dt.train”和一个单独的测试集“ dt.test”。

在正常决策树中,通过将叶子中所有类别为“ buy”的观察值除以总数,计算出新数据行(测试数据)的“购买” P(has_bought =“ buy”)的类别概率。叶中的观测值(基于用于生长树的训练数据)。

但是,即使我模拟“正常”决策树(将n.trees设置为1,并将alle sample.rates设置为1),h2o.gbm似乎也做了不同的事情。我认为,最好的方式来说明这种困惑是通过逐步告诉我所做的事情。

步骤1:训练模型

我不在乎过拟合或模型性能。我想让自己的生活尽可能轻松,因此我将n.trees设置为1,并通过设置所有sample.rate参数来确保所有训练数据(行和列)用于每棵树并进行拆分。到1.下面是训练模型的代码。

    base.gbm.model <- h2o.gbm(
x = predictors,
y = "has_bought",
training_frame = dt.train,
model_id = "2",
nfolds = 0,
ntrees = 1,
learn_rate = 0.001,
max_depth = 15,
sample_rate = 1,
col_sample_rate = 1,
col_sample_rate_per_tree = 1,
seed = 123456,
keep_cross_validation_predictions = TRUE,
stopping_rounds = 10,
stopping_tolerance = 0,
stopping_metric = "AUC",
score_tree_interval = 0
)


步骤2:获取训练集的叶子分配

我想做的是使用与训练模型相同的数据,并了解它们最终位于哪个叶子中。H2o为此提供了一个功能,如下所示。

    train.leafs <- h2o.predict_leaf_node_assignment(base.gbm.model, dt.train)


这将返回训练数据中每一行的叶节点分配(例如“ LLRRLL”)。因为只有一棵树,所以此列称为“ T1.C1”,我将其重命名为“ leaf_node”,并将其与训练数据的目标变量“ has_bought”绑定在一起。这导致下面的输出(从这里开始称为“ train.leafs”)。



步骤3:对测试集进行预测

对于测试集,我想预测两件事:


模型本身的预测P(has_bought =“ buy”)
根据模型分配叶节点。

test.leafs <- h2o.predict_leaf_node_assignment(base.gbm.model, dt.test)
test.pred <- h2o.predict(base.gbm.model, dt.test)



找到这个之后,我使用cbind将这两个预测与测试集的目标变量结合在一起。

    test.total <- h2o.cbind(dt.test[, c("has_bought")], test.pred, test.leafs)


结果是下表,从此处称为“ test.total”


不幸的是,我没有足够的代表点来发表两个以上的链接。但是如果您点击“表格“ test.total”并结合使用手册
步骤5中的“概率计算”,它基本上是同一张表
没有“ manual_prob_buy”列。


步骤4:手动预测概率

从理论上讲,我现在应该可以自己预测概率了。我通过编写一个循环来做到这一点,该循环遍历“ test.total”中的每一行。对于每一行,我进行叶子节点分配。

然后,我使用该叶节点分配来过滤表“ train.leafs”,并检查有多少个观测值具有正类(has_bought == 1)(posN),以及叶内总共有多少个观测值(totalN)与测试行相关联。

我执行(标准)计算posN / totalN,并将其作为新列存储在测试行中,称为“ manual_prob_buy”,这应该是该叶子的P(has_bought =“ buy”)概率。因此,落在该叶子中的每个测试行都应具有该概率。
该for循环如下所示。

    for(i in 1:nrow(dt.test)){
leaf <- test.total[i, leaf_node]
totalN <- nrow(train.leafs[train.leafs$leaf_node == leaf])
posN <- nrow(train.leafs[train.leafs$leaf_node == leaf & train.leafs$has_bought == "buy",])
test.total[i, manual_prob_buy := posN / totalN]
}


步骤5:比较概率

这就是我感到困惑的地方。以下是更新后的“ test.total”表,其中“ buy”代表根据模型的概率P(has_bought =“ buy”),而“ manual_prob_buy”代表从步骤4开始手动计算的概率。 ,这些概率应该是相同的,因为我只使用了1棵树,并且将sample.rates设置为1。

表“ test.total”结合手动概率计算


问题

我只是不明白为什么这两个概率不一样。据我所知,我以一种类似于“正常”分类树的方式设置参数。

那么问题来了:有人知道我为什么会发现这些概率之间的差异吗?

我希望有人可以指出我可能做出错误假设的地方。我只是真的希望我做些愚蠢的事情,因为这使我发疯。

谢谢!

最佳答案

我建议您不要将R的h2o.predict()的结果与您自己的手写代码进行比较,而应将其与应该匹配的H2O MOJO进行比较。

在这里查看示例:

http://docs.h2o.ai/h2o/latest-stable/h2o-genmodel/javadoc/overview-summary.html#quickstartmojo

您可以自己运行该简单示例,然后根据您自己的模型和新的数据行对其进行修改以进行预测。

完成此操作后,您可以查看代码并在Java环境中对其进行调试/单步调试,以准确了解预测的计算方式。

您可以在github上找到MOJO预测代码:

https://github.com/h2oai/h2o-3/blob/master/h2o-genmodel/src/main/java/hex/genmodel/easy/EasyPredictModelWrapper.java

关于r - 如何重现H2o GBM类概率计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44735518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com