了解 R gbm 包中的树结构

Posted

技术标签:

【中文标题】了解 R gbm 包中的树结构【英文标题】:Understanding tree structure in R gbm package 【发布时间】:2015-09-26 14:12:47 【问题描述】:

我很难理解 R 的 gbm 梯度增强机器包中树的结构。具体来说,查看pretty.gbm.tree 的输出SplitVar 中的索引指向哪些特征

我在一个数据集上训练了一个 GBM,这是我的一棵树的顶部~四分之一——调用 pretty.gbm.tree 的结果:

   SplitVar SplitCodePred LeftNode RightNode MissingNode ErrorReduction Weight   Prediction
0         9  6.250000e+01        1         2          21      0.6634681   5981  0.005000061
1        -1  1.895699e-12       -1        -1          -1      0.0000000   3013  0.018956988
2        31  4.462500e+02        3         4          20      1.0083722   2968 -0.009168477
3        -1  1.388483e-22       -1        -1          -1      0.0000000   1430  0.013884830
4        38  5.500000e+00        5        18          19      1.5748155   1538 -0.030602956
5        24  7.530000e+03        6        13          17      2.8329899    361 -0.078738904
6        41  2.750000e+01        7        11          12      2.2499063    334 -0.064752766
7        28 -3.155000e+02        8         9          10      1.5516610     57 -0.243675567
8        -1 -3.379312e-11       -1        -1          -1      0.0000000     45 -0.337931219
9        -1  1.922333e-10       -1        -1          -1      0.0000000     12  0.109783128
```

LeftNode, RightNodeMissingNode 如何指向不同的行来看,在我看来,索引是基于 0 的。在使用数据样本进行测试并沿着树向下进行预测时,当我认为SplitVar 使用基于1 的索引时,我得到了正确答案。

但是,我构建的许多树中的一棵在SplitVar 列中有一个!这是这棵树:

SplitVar SplitCodePred LeftNode RightNode MissingNode ErrorReduction Weight    Prediction
0         4  1.462500e+02        1         2          21      0.41887   5981  0.0021651262
1        -1  4.117688e-22       -1        -1          -1      0.00000    512  0.0411768781
2         4  1.472500e+02        3         4          20      1.05222   5469 -0.0014870985
3        -1 -2.062798e-11       -1        -1          -1      0.00000     23 -0.2062797579
4         0  4.750000e+00        5         6          19      0.65424   5446 -0.0006222011
5        -1  3.564879e-23       -1        -1          -1      0.00000   4897  0.0035648788
6        28 -3.195000e+02        7        11          18      1.39452    549 -0.0379703437

查看 gbm 树使用的索引的正确方法是什么?

【问题讨论】:

如果您在示例输入中包含一个小的reproducible example 以及您用于生成对象的代码,将会有所帮助。只显示结果并不能让我们很好地了解正在发生的事情。 R 中的向量总是从 1 开始的。未命名的第一列通常是行名而不是​​索引。 【参考方案1】:

使用pretty.gbm.tree 时打印的第一列是在脚本pretty.gbm.tree.R 中分配的row.names。在脚本中,row.names 被分配为row.names(temp) <- 0:(nrow(temp)-1),其中temp 是以data.frame 形式存储的树信息。解释row.names 的正确方法是将其读取为node_id,并将根节点分配为0 值。

在你的例子中:

Id SplitVar SplitCodePred LeftNode RightNode MissingNode ErrorReduction Weight Prediction 0 9 6.250000e+01 1 2 21 0.6634681 5981 0.005000061

表示根节点(行号0表示)被第9个分裂变量分裂(这里分裂变量的编号从0开始,所以分裂变量是训练集中的第10列@ 987654331@)。 SplitCodePred of 6.25 表示所有小于6.25 的点都到LeftNode 1,所有大于6.25 的点都到RightNode 2。此列中缺少值的所有点都分配给MissingNode 21。由于此拆分,ErrorReduction0.6634,根节点中有 5981 (Weight)。 Prediction of 0.005 表示在该点被拆分之前分配给该节点上所有值的值。对于在SplitVarLeftNodeRightNodeMissingNode 中由-1 表示的终端节点(或叶子),Prediction 表示对属于该叶子节点的所有点的预测值调整 (次) 倍 shrinkage

要了解树结构,重要的是要注意树的分裂以深度优先的方式发生。因此,当根节点(节点 id 为 0)被拆分为其左节点和右节点时,将处理左侧,直到在返回并标记右节点之前无法进一步拆分。在您的示例中的两棵树中,RightNode 的值均为 2。这是因为在这两种情况下,LeftNode 都是叶节点。

【讨论】:

只是想指出正好等于 6.25 的点是正确的。 我相信 6.250000e+01 是 62.5,而不是 6.25。

以上是关于了解 R gbm 包中的树结构的主要内容,如果未能解决你的问题,请参考以下文章

gbm 包中的 ROC 分数

数据结构_3

R中的gbm崩溃

二叉树的四种遍历算法实现,没你想得那么难

树及二叉树

R gbm 函数中的权重参数