将 rpart 规则导出到数据框和 link 规则以训练数据
export rpart rules to a data frame and link rules to train data
我已经用 rpart 训练了一些数据并且有兴趣用树终端节点标记每个观察,
和 link 对应于该终端节点的规则。
我使用以下代码作为示例:
library(rpart)
library(rattle)
fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)
table(fit$where)
rattle::asRules(fit)
我可以通过 fit$where 标记每个观察结果,
标签是:
> table(fit$where)
3 5 7 8 9
29 12 14 7 19
第一个问题:这些标签与rattle::asRules(fit)生成的标签不对应,分别是3,23,22,10,4
如何生成两者之间的映射 table?
第二个问题:asRules 只是打印,而我想将规则放在 table 而不是标准输出中。
我的预期结果:一个数据框在 fit$where 和 asRules 标签之间有一个映射,另一列的规则文本是一个字符串,例如:
Rule number: 4 [Kyphosis=absent cover=29 (36%) prob=0.00]
Start>=8.5
Start>=14.5
如果我们可以将文本解析为单独列中的 ID、统计信息和条件,那就更好了,但不是强制性的。
我找了很多相关的问题和link,但是没有找到最终的答案。
非常感谢,
卡马谢
进度更新 29/01
如果我有规则 ID,我可以通过 path.rpart:
单独提取每个规则
>path.rpart(fit,node=22)
node number: 22
root
Start>=8.5
Start< 14.5
Age>=55
Age>=111
这让我得到了规则作为一个列表,我可以将其转换为一个字符串。
然而,这些 ID 与 'asRules' 功能有关,而不是 'fit$where'...
使用 "partykit" 得到与 "fit$where" 相同的结果:
library("partykit")
> table(predict(as.party(fit), type = "node"))
3 5 7 8 9
29 12 14 7 19
所以,我仍然无法 link 两者之间( asRules IDs 和 fit$where IDs),
我可能遗漏了一些基本的东西,或者有更直接的方法来完成任务。
你能帮忙吗?
可以使用
找到每个fit$where对应的规则号(其实就是叶节点号)
> row.names(fit$frame)[fit$where]
[1] "3" "22" "3" "3" "4" "4" ...
您可能会更接近您想要的输出
> rattle::asRules(fit, TRUE)
R 3 [23%,0.58] Start< 8.5
R 23 [ 9%,0.57] Start>=8.5 Start< 14.5 Age>=55 Age< 111
...
这个值多少钱,毕竟这是我用过的:
[1] 为了在 fit$where 和 asRules 之间对齐标签,我使用了@Graham Williams 的解决方案,
或者首先通过采用@VitoshKa 的函数来获得正确的标签:
[2] 用于在数据框中创建格式良好的规则列表我采用并修改了 Tomáš Greif 的 parse_tree 函数:
https://www.r-bloggers.com/create-sql-rules-from-rpart-model/
你的意思是这样的吗?
library(rpart)
library(rpart.utils)
library(dplyr)
#model
fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)
#dataframe having leaf node's rule and subrule combination
rule_df <- rpart.rules.table(fit) %>%
filter(Leaf==TRUE) %>%
group_by(Rule) %>%
summarise(Subrules = paste(Subrule, collapse=","))
#final dataframe
df <- kyphosis %>%
mutate(Rule = row.names(fit$frame)[fit$where]) %>%
left_join(rule_df, by="Rule")
head(df)
#subrule table
rpart.subrules.table(fit)
输出为:
Kyphosis Age Number Start Rule Subrules
1 absent 71 3 5 3 R1
2 absent 158 3 14 22 L1,R2,R3,L4
3 present 128 4 5 3 R1
4 absent 2 5 1 3 R1
5 absent 1 4 15 4 L1,L2
6 absent 1 2 16 4 L1,L2
子规则定义:
Subrule Variable Value Less Greater
1 L1 Start 8.5 <NA> 8.5
2 L2 Start 14.5 <NA> 14.5
3 L3 Age <NA> 55 <NA>
4 L4 Age 111 <NA> 111
5 R1 Start <NA> 8.5 <NA>
6 R2 Start <NA> 14.5 <NA>
7 R3 Age 55 <NA> 55
8 R4 Age <NA> 111 <NA>
可以这样获取规则(叶子)的数量:
nrules <- as.integer(rownames(fit$frame[fit$frame$var == "<leaf>",]))
您也可以像这样迭代规则:
rules <- lapply(nrules, path.rpart, tree=fit, pretty=0, print.it=FALSE)
另一种选择是使用包 rpart.plot
rules <- rpart.plot::rpart.rules(model, cover=T, nn=T)
我已经用 rpart 训练了一些数据并且有兴趣用树终端节点标记每个观察, 和 link 对应于该终端节点的规则。
我使用以下代码作为示例:
library(rpart)
library(rattle)
fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)
table(fit$where)
rattle::asRules(fit)
我可以通过 fit$where 标记每个观察结果, 标签是:
> table(fit$where)
3 5 7 8 9
29 12 14 7 19
第一个问题:这些标签与rattle::asRules(fit)生成的标签不对应,分别是3,23,22,10,4 如何生成两者之间的映射 table?
第二个问题:asRules 只是打印,而我想将规则放在 table 而不是标准输出中。
我的预期结果:一个数据框在 fit$where 和 asRules 标签之间有一个映射,另一列的规则文本是一个字符串,例如:
Rule number: 4 [Kyphosis=absent cover=29 (36%) prob=0.00]
Start>=8.5
Start>=14.5
如果我们可以将文本解析为单独列中的 ID、统计信息和条件,那就更好了,但不是强制性的。
我找了很多相关的问题和link,但是没有找到最终的答案。
非常感谢, 卡马谢
进度更新 29/01
如果我有规则 ID,我可以通过 path.rpart:
单独提取每个规则>path.rpart(fit,node=22)
node number: 22
root
Start>=8.5
Start< 14.5
Age>=55
Age>=111
这让我得到了规则作为一个列表,我可以将其转换为一个字符串。 然而,这些 ID 与 'asRules' 功能有关,而不是 'fit$where'...
使用 "partykit" 得到与 "fit$where" 相同的结果:
library("partykit")
> table(predict(as.party(fit), type = "node"))
3 5 7 8 9
29 12 14 7 19
所以,我仍然无法 link 两者之间( asRules IDs 和 fit$where IDs), 我可能遗漏了一些基本的东西,或者有更直接的方法来完成任务。
你能帮忙吗?
可以使用
找到每个fit$where对应的规则号(其实就是叶节点号)> row.names(fit$frame)[fit$where]
[1] "3" "22" "3" "3" "4" "4" ...
您可能会更接近您想要的输出
> rattle::asRules(fit, TRUE)
R 3 [23%,0.58] Start< 8.5
R 23 [ 9%,0.57] Start>=8.5 Start< 14.5 Age>=55 Age< 111
...
这个值多少钱,毕竟这是我用过的:
[1] 为了在 fit$where 和 asRules 之间对齐标签,我使用了@Graham Williams 的解决方案, 或者首先通过采用@VitoshKa 的函数来获得正确的标签:
[2] 用于在数据框中创建格式良好的规则列表我采用并修改了 Tomáš Greif 的 parse_tree 函数: https://www.r-bloggers.com/create-sql-rules-from-rpart-model/
你的意思是这样的吗?
library(rpart)
library(rpart.utils)
library(dplyr)
#model
fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)
#dataframe having leaf node's rule and subrule combination
rule_df <- rpart.rules.table(fit) %>%
filter(Leaf==TRUE) %>%
group_by(Rule) %>%
summarise(Subrules = paste(Subrule, collapse=","))
#final dataframe
df <- kyphosis %>%
mutate(Rule = row.names(fit$frame)[fit$where]) %>%
left_join(rule_df, by="Rule")
head(df)
#subrule table
rpart.subrules.table(fit)
输出为:
Kyphosis Age Number Start Rule Subrules
1 absent 71 3 5 3 R1
2 absent 158 3 14 22 L1,R2,R3,L4
3 present 128 4 5 3 R1
4 absent 2 5 1 3 R1
5 absent 1 4 15 4 L1,L2
6 absent 1 2 16 4 L1,L2
子规则定义:
Subrule Variable Value Less Greater
1 L1 Start 8.5 <NA> 8.5
2 L2 Start 14.5 <NA> 14.5
3 L3 Age <NA> 55 <NA>
4 L4 Age 111 <NA> 111
5 R1 Start <NA> 8.5 <NA>
6 R2 Start <NA> 14.5 <NA>
7 R3 Age 55 <NA> 55
8 R4 Age <NA> 111 <NA>
可以这样获取规则(叶子)的数量:
nrules <- as.integer(rownames(fit$frame[fit$frame$var == "<leaf>",]))
您也可以像这样迭代规则:
rules <- lapply(nrules, path.rpart, tree=fit, pretty=0, print.it=FALSE)
另一种选择是使用包 rpart.plot
rules <- rpart.plot::rpart.rules(model, cover=T, nn=T)