gpt4 book ai didi

r - 如何使用路径爬升rpart对象的树结构以手动清除某些节点?

转载 作者:行者123 更新时间:2023-11-30 08:36:31 24 4
gpt4 key购买 nike

我正在使用 rpart 来构建分类树。我想根据叶节点的一些标准开发自己的剪枝函数。例如,如果一个叶节点不符合某些标准(在我的情况下参数估计的稳定性),我想爬入树结构并获取该叶节点的父节点(即使该节点不是终端) 。为此,我想使用路径遍历树,并且需要获取叶节点及其父节点,以便在必要时爬树。

让我们看一下这个例子:

fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)

> fit
n= 81

node), split, n, loss, yval, (yprob)
* denotes terminal node

1) root 81 17 absent (0.79012346 0.20987654)
2) Start>=8.5 62 6 absent (0.90322581 0.09677419)
4) Start>=14.5 29 0 absent (1.00000000 0.00000000) *
5) Start< 14.5 33 6 absent (0.81818182 0.18181818)
10) Age< 55 12 0 absent (1.00000000 0.00000000) *
11) Age>=55 21 6 absent (0.71428571 0.28571429)
22) Age>=111 14 2 absent (0.85714286 0.14285714) *
23) Age< 111 7 3 present (0.42857143 0.57142857) *
3) Start< 8.5 19 8 present (0.42105263 0.57894737) *

使用 fit$frame 我可以获得有关叶节点的信息:

fit$frame 

var n wt dev yval complexity ncompete nsurrogate yval2.V1 yval2.V2 yval2.V3 yval2.V4 yval2.V5
1 Start 81 81 17 1 0.17647059 2 1 1.00000000 64.00000000 17.00000000 0.79012346 0.20987654
2 Start 62 62 6 1 0.01960784 2 2 1.00000000 56.00000000 6.00000000 0.90322581 0.09677419
4 <leaf> 29 29 0 1 0.01000000 0 0 1.00000000 29.00000000 0.00000000 1.00000000 0.00000000
5 Age 33 33 6 1 0.01960784 2 2 1.00000000 27.00000000 6.00000000 0.81818182 0.18181818
10 <leaf> 12 12 0 1 0.01000000 0 0 1.00000000 12.00000000 0.00000000 1.00000000 0.00000000
11 Age 21 21 6 1 0.01960784 2 0 1.00000000 15.00000000 6.00000000 0.71428571 0.28571429
22 <leaf> 14 14 2 1 0.01000000 0 0 1.00000000 12.00000000 2.00000000 0.85714286 0.14285714
23 <leaf> 7 7 3 2 0.01000000 0 0 2.00000000 3.00000000 4.00000000 0.42857143 0.57142857
3 <leaf> 19 19 8 2 0.01000000 0 0 2.00000000 8.00000000 11.00000000 0.42105263 0.57894737

我可以使用以下命令获取数据表中的行与其所在的相应叶节点的对应关系:fit$where

现在我还想获取叶节点的父节点。我知道 path.rpart 为我提供了为了获得叶节点而完成的所有分割。例如对于叶节点 23:

> path.rpart(fit, 23)

node number: 23
root
Start>=8.5
Start< 14.5
Age>=55
Age< 111

我想要获取的是一条包含23号节点的父节点号的路径?我怎样才能建立这个关联?

提前谢谢您。

最佳答案

您不需要有关树的任何信息,因为所有节点都具有相同的模式。让我们拟合一棵更有趣的树:

(fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis,
cp = .0001, minsplit = 5))

# n= 81
#
# node), split, n, loss, yval, (yprob)
# * denotes terminal node
#
# 1) root 81 17 absent (0.79012346 0.20987654)
# 2) Start>=8.5 62 6 absent (0.90322581 0.09677419)
# 4) Start>=14.5 29 0 absent (1.00000000 0.00000000) *
# 5) Start< 14.5 33 6 absent (0.81818182 0.18181818)
# 10) Age< 55 12 0 absent (1.00000000 0.00000000) *
# 11) Age>=55 21 6 absent (0.71428571 0.28571429)
# 22) Age>=98 16 2 absent (0.87500000 0.12500000) *
# 23) Age< 98 5 1 present (0.20000000 0.80000000) *
# 3) Start< 8.5 19 8 present (0.42105263 0.57894737)
# 6) Age< 11.5 2 0 absent (1.00000000 0.00000000) *
# 7) Age>=11.5 17 6 present (0.35294118 0.64705882)
# 14) Start< 5.5 12 6 absent (0.50000000 0.50000000)
# 28) Age>=130.5 2 0 absent (1.00000000 0.00000000) *
# 29) Age< 130.5 10 4 present (0.40000000 0.60000000)
# 58) Age< 93 6 2 absent (0.66666667 0.33333333)
# 116) Number< 4.5 3 0 absent (1.00000000 0.00000000) *
# 117) Number>=4.5 3 1 present (0.33333333 0.66666667) *
# 59) Age>=93 4 0 present (0.00000000 1.00000000) *
# 15) Start>=5.5 5 0 present (0.00000000 1.00000000) *

如果可能,每个节点将被分成两部分并编号为 node * 2 + 0:1 ,所以如果你有一个编号为 5 的节点,它的子节点将为 5 * 2 + 0:1 。另请注意,使用此模式,偶数编号的节点不会有子节点。

因此,给定任何节点号,我们都可以回溯找到父节点:

parent(23)
# [1] 1 2 5 11 23

## children of the same node should have the same path
identical(head(parent(28), -1), head(parent(29), -1))
# [1] TRUE

parent <- function(x) {
if (x[1] != 1)
c(Recall(if (x %% 2 == 0L) x / 2 else (x - 1) / 2), x) else x
}

关于r - 如何使用路径爬升rpart对象的树结构以手动清除某些节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36086990/

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