R从ctree(partykit)中提取内部节点信息和分裂
R Extracting inner node information and splits from ctree (partykit)
您好,我目前正在尝试使用 partykit 中的 ctree 提取存储在 R 中常量派对对象中的一些内部节点信息,但我发现导航对象有点困难,我能够显示关于情节的信息,但我不确定如何提取信息 - 我认为它需要 nodeapply 或 partykit 中的其他功能?
library(partykit)
irisct <- ctree(Species ~ .,data = iris)
plot(irisct, inner_panel = node_barplot(irisct))
Plot with inner node details
绘制函数可以访问所有信息,但我正在寻找类似于以下内容的文本输出:
Example output
您需要的大部分信息都可以轻松访问。
我将展示如何获取信息,但让您格式化
信息变成漂亮的table.
请注意,您的树结构 irisct
只是每个节点的列表。
length(irisct)
[1] 7
每个节点都有一个字段data
,其中包含使其下降的点
在树中这么远,所以你可以获得节点处的观察数量
通过计算行数。
dim(irisct[4]$data)
[1] 54 5
nrow(irisct[4]$data)
[1] 54
或者一次完成所有操作以获得 table 2
NObs = sapply(1:7, function(n) { nrow(irisct[n]$data) })
NObs
[1] 150 50 100 54 46 8 46
节点数据的第一列是class(物种),
所以你可以得到每个 class 的计数和每个 class 的概率
在一个节点
table(irisct[4]$data[1])
setosa versicolor virginica
0 49 5
table(irisct[4]$data[1]) / NObs[4]
setosa versicolor virginica
0.00000000 0.90740741 0.09259259
你的table3中的拆分信息有点尴尬。仍然,
您只需打印出所需内容的文本版本
顶级节点
irisct[1]
Model formula:
Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
Fitted party:
[1] root
| [2] Petal.Length <= 1.9: setosa (n = 50, err = 0.0%)
| [3] Petal.Length > 1.9
| | [4] Petal.Width <= 1.7
| | | [5] Petal.Length <= 4.8: versicolor (n = 46, err = 2.2%)
| | | [6] Petal.Length > 4.8: versicolor (n = 8, err = 50.0%)
| | [7] Petal.Width > 1.7: virginica (n = 46, err = 2.2%)
Number of inner nodes: 3
Number of terminal nodes: 4
保存输出以供解析和显示
TreeSplits = capture.output(print(irisct[1]))
主要技巧(如@G5W 先前指出的那样)是获取 party
对象的 [id]
子集,然后提取数据(通过 $data
或使用data_party()
函数)包含响应。我建议首先构建一个具有绝对频率的 table,然后从中计算相对频率和边际频率。使用 irisct
对象可以通过
获得普通的 table
tab <- sapply(1:length(irisct), function(id) {
y <- data_party(irisct[id])
y <- y[["(response)"]]
table(y)
})
tab
## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## setosa 50 50 0 0 0 0 0
## versicolor 50 0 50 49 45 4 1
## virginica 50 0 50 5 1 4 45
然后我们可以为一个漂亮的 table
对象添加一些格式:
colnames(tab) <- 1:length(irisct)
tab <- as.table(tab)
names(dimnames(tab)) <- c("Species", "Node")
然后使用prop.table()
和margin.table()
来计算我们感兴趣的频率。as.data.frame()
方法从table
布局转换为"long" data.frame
:
as.data.frame(prop.table(tab, 1))
## Species Node Freq
## 1 setosa 1 0.500000000
## 2 versicolor 1 0.251256281
## 3 virginica 1 0.322580645
## 4 setosa 2 0.500000000
## 5 versicolor 2 0.000000000
## 6 virginica 2 0.000000000
## 7 setosa 3 0.000000000
## 8 versicolor 3 0.251256281
## 9 virginica 3 0.322580645
## 10 setosa 4 0.000000000
## 11 versicolor 4 0.246231156
## 12 virginica 4 0.032258065
## 13 setosa 5 0.000000000
## 14 versicolor 5 0.226130653
## 15 virginica 5 0.006451613
## 16 setosa 6 0.000000000
## 17 versicolor 6 0.020100503
## 18 virginica 6 0.025806452
## 19 setosa 7 0.000000000
## 20 versicolor 7 0.005025126
## 21 virginica 7 0.290322581
as.data.frame(margin.table(tab, 2))
## Node Freq
## 1 1 150
## 2 2 50
## 3 3 100
## 4 4 54
## 5 5 46
## 6 6 8
## 7 7 46
并且拆分信息可以通过(仍未导出).list.rules.party()
函数获取。您只需要请求 all 个节点 ID(默认仅使用终端节点 ID):
partykit:::.list.rules.party(irisct, i = nodeids(irisct))
## 1
## ""
## 2
## "Petal.Length <= 1.9"
## 3
## "Petal.Length > 1.9"
## 4
## "Petal.Length > 1.9 & Petal.Width <= 1.7"
## 5
## "Petal.Length > 1.9 & Petal.Width <= 1.7 & Petal.Length <= 4.8"
## 6
## "Petal.Length > 1.9 & Petal.Width <= 1.7 & Petal.Length > 4.8"
## 7
## "Petal.Length > 1.9 & Petal.Width > 1.7"
您好,我目前正在尝试使用 partykit 中的 ctree 提取存储在 R 中常量派对对象中的一些内部节点信息,但我发现导航对象有点困难,我能够显示关于情节的信息,但我不确定如何提取信息 - 我认为它需要 nodeapply 或 partykit 中的其他功能?
library(partykit)
irisct <- ctree(Species ~ .,data = iris)
plot(irisct, inner_panel = node_barplot(irisct))
Plot with inner node details
绘制函数可以访问所有信息,但我正在寻找类似于以下内容的文本输出: Example output
您需要的大部分信息都可以轻松访问。 我将展示如何获取信息,但让您格式化 信息变成漂亮的table.
请注意,您的树结构 irisct
只是每个节点的列表。
length(irisct)
[1] 7
每个节点都有一个字段data
,其中包含使其下降的点
在树中这么远,所以你可以获得节点处的观察数量
通过计算行数。
dim(irisct[4]$data)
[1] 54 5
nrow(irisct[4]$data)
[1] 54
或者一次完成所有操作以获得 table 2
NObs = sapply(1:7, function(n) { nrow(irisct[n]$data) })
NObs
[1] 150 50 100 54 46 8 46
节点数据的第一列是class(物种), 所以你可以得到每个 class 的计数和每个 class 的概率 在一个节点
table(irisct[4]$data[1])
setosa versicolor virginica
0 49 5
table(irisct[4]$data[1]) / NObs[4]
setosa versicolor virginica
0.00000000 0.90740741 0.09259259
你的table3中的拆分信息有点尴尬。仍然, 您只需打印出所需内容的文本版本 顶级节点
irisct[1]
Model formula:
Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
Fitted party:
[1] root
| [2] Petal.Length <= 1.9: setosa (n = 50, err = 0.0%)
| [3] Petal.Length > 1.9
| | [4] Petal.Width <= 1.7
| | | [5] Petal.Length <= 4.8: versicolor (n = 46, err = 2.2%)
| | | [6] Petal.Length > 4.8: versicolor (n = 8, err = 50.0%)
| | [7] Petal.Width > 1.7: virginica (n = 46, err = 2.2%)
Number of inner nodes: 3
Number of terminal nodes: 4
保存输出以供解析和显示
TreeSplits = capture.output(print(irisct[1]))
主要技巧(如@G5W 先前指出的那样)是获取 party
对象的 [id]
子集,然后提取数据(通过 $data
或使用data_party()
函数)包含响应。我建议首先构建一个具有绝对频率的 table,然后从中计算相对频率和边际频率。使用 irisct
对象可以通过
tab <- sapply(1:length(irisct), function(id) {
y <- data_party(irisct[id])
y <- y[["(response)"]]
table(y)
})
tab
## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## setosa 50 50 0 0 0 0 0
## versicolor 50 0 50 49 45 4 1
## virginica 50 0 50 5 1 4 45
然后我们可以为一个漂亮的 table
对象添加一些格式:
colnames(tab) <- 1:length(irisct)
tab <- as.table(tab)
names(dimnames(tab)) <- c("Species", "Node")
然后使用prop.table()
和margin.table()
来计算我们感兴趣的频率。as.data.frame()
方法从table
布局转换为"long" data.frame
:
as.data.frame(prop.table(tab, 1))
## Species Node Freq
## 1 setosa 1 0.500000000
## 2 versicolor 1 0.251256281
## 3 virginica 1 0.322580645
## 4 setosa 2 0.500000000
## 5 versicolor 2 0.000000000
## 6 virginica 2 0.000000000
## 7 setosa 3 0.000000000
## 8 versicolor 3 0.251256281
## 9 virginica 3 0.322580645
## 10 setosa 4 0.000000000
## 11 versicolor 4 0.246231156
## 12 virginica 4 0.032258065
## 13 setosa 5 0.000000000
## 14 versicolor 5 0.226130653
## 15 virginica 5 0.006451613
## 16 setosa 6 0.000000000
## 17 versicolor 6 0.020100503
## 18 virginica 6 0.025806452
## 19 setosa 7 0.000000000
## 20 versicolor 7 0.005025126
## 21 virginica 7 0.290322581
as.data.frame(margin.table(tab, 2))
## Node Freq
## 1 1 150
## 2 2 50
## 3 3 100
## 4 4 54
## 5 5 46
## 6 6 8
## 7 7 46
并且拆分信息可以通过(仍未导出).list.rules.party()
函数获取。您只需要请求 all 个节点 ID(默认仅使用终端节点 ID):
partykit:::.list.rules.party(irisct, i = nodeids(irisct))
## 1
## ""
## 2
## "Petal.Length <= 1.9"
## 3
## "Petal.Length > 1.9"
## 4
## "Petal.Length > 1.9 & Petal.Width <= 1.7"
## 5
## "Petal.Length > 1.9 & Petal.Width <= 1.7 & Petal.Length <= 4.8"
## 6
## "Petal.Length > 1.9 & Petal.Width <= 1.7 & Petal.Length > 4.8"
## 7
## "Petal.Length > 1.9 & Petal.Width > 1.7"