J48 树 (RWeka) 中的属性及其值
Properties and their values out of J48 tree (RWeka)
如果您运行满足以下条件:
library(RWeka)
data(iris)
res = J48(Species ~., data = iris)
res
将是 class J48
的列表,继承自 Weka_tree
。如果你打印它
R> res
J48 pruned tree
------------------
Petal.Width <= 0.6: setosa (50.0)
Petal.Width > 0.6
| Petal.Width <= 1.7
| | Petal.Length <= 4.9: versicolor (48.0/1.0)
| | Petal.Length > 4.9
| | | Petal.Width <= 1.5: virginica (3.0)
| | | Petal.Width > 1.5: versicolor (3.0/1.0)
| Petal.Width > 1.7: virginica (46.0/1.0)
Number of Leaves : 5
Size of the tree : 9
我想按从右到左的顺序获取属性及其值。所以对于这种情况:
Petal.Width, Petal.Width, Petal.Length, Petal.Length.
我试图将 res 输入到一个因子并输入 运行 命令:
str_extract(paste0(x, collapse=""), perl("(?<=\|)[A-Za-z]+(?=\|)"))
没有成功。
请记住,我们应该忽略左边的字符。
我希望我没有漏掉你的意思,但我假设你想以某种方式创建和存储基于树模型终端节点的规则。就个人而言,我发现模型树构建包(RWeka、party、partykit、rpart)无法让用户在构建模型后创建有用的规则列表。当然,当你的变量和拆分很少时,你可以解释树图。
到目前为止我发现的(我自己使用的)唯一简单可靠的方法是 rpart 包的命令 "path.rpart"。如果你真的想使用 RWeka,解决方案似乎无关紧要,但我会试一试:
library(rpart)
res = rpart(Species ~., data = iris)
res
# n= 150
#
# node), split, n, loss, yval, (yprob)
# * denotes terminal node
#
# 1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)
# 2) Petal.Length< 2.45 50 0 setosa (1.00000000 0.00000000 0.00000000) *
# 3) Petal.Length>=2.45 100 50 versicolor (0.00000000 0.50000000 0.50000000)
# 6) Petal.Width< 1.75 54 5 versicolor (0.00000000 0.90740741 0.09259259) *
# 7) Petal.Width>=1.75 46 1 virginica (0.00000000 0.02173913 0.97826087) *
# capture terminal nodes
terminal_nodes = rownames(res$frame)[res$frame$var =="<leaf>"]
# print rules for the terminal nodes
path.rpart(res ,nodes=terminal_nodes)
# node number: 2
# root
# Petal.Length< 2.45
#
# node number: 6
# root
# Petal.Length>=2.45
# Petal.Width< 1.75
#
# node number: 7
# root
# Petal.Length>=2.45
# Petal.Width>=1.75
# print above rules as list
rules = path.rpart(res ,nodes=terminal_nodes)
listed_rules = unlist(rules)
sapply(rules,"[",-1)
# $`2`
# [1] "Petal.Length< 2.45"
#
# $`6`
# [1] "Petal.Length>=2.45" "Petal.Width< 1.75"
#
# $`7`
# [1] "Petal.Length>=2.45" "Petal.Width>=1.75"
一种方法是将 J48
对象从 RWeka
转换为 party
对象从 partykit
。您只需要 as as.party(res)
,这会为您完成所有解析,returns 一个更易于使用标准化提取函数等的结构。
特别是您可以使用其他关于 ctree
对象等的讨论中给出的所有建议。参见
Get decision tree rule/path pattern for every row of predicted dataset for rpart/ctree package in R
而且我认为以下内容至少可以满足您的部分需求:
library("partykit")
pres <- as.party(res)
partykit:::.list.rules.party(pres)
## 2
## "Petal.Width <= 0.6"
## 5
## "Petal.Width > 0.6 & Petal.Width <= 1.7 & Petal.Length <= 4.9"
## 7
## "Petal.Width > 0.6 & Petal.Width <= 1.7 & Petal.Length > 4.9 & Petal.Width <= 1.5"
## 8
## "Petal.Width > 0.6 & Petal.Width <= 1.7 & Petal.Length > 4.9 & Petal.Width > 1.5"
## 9
## "Petal.Width > 0.6 & Petal.Width > 1.7"
更新:OP 在列表外联系了我一个相关问题,要求提供树的特定打印表示。我在这里包括我的解决方案,以防它对其他人有用。
他想要 ( ) 符号表示层次结构级别以及拆分变量的名称。一种方法是 (1) 提取基础数据的变量名称:
nam <- names(pres$data)
(2) 将树的递归节点结构转为扁平列表(这样在构造想要的字符串时更方便一些):
tr <- as.list(pres$node)
(3a) 初始化字符串:
str <- "("
(3b)递归地在字符串中添加括号and/or变量名:
update_str <- function(x) {
if(is.null(x$kids)) {
str <<- paste(str, ")")
} else {
str <<- paste(str, nam[x$split$varid], "(")
for(i in x$kids) update_str(tr[[i]])
}
}
(3c) 调用递归,从根节点开始:
update_str(tr[[1]])
str
## [1] "( Petal.Width ( ) Petal.Width ( Petal.Length ( ) Petal.Width ( ) ) )"
如果您运行满足以下条件:
library(RWeka)
data(iris)
res = J48(Species ~., data = iris)
res
将是 class J48
的列表,继承自 Weka_tree
。如果你打印它
R> res
J48 pruned tree
------------------
Petal.Width <= 0.6: setosa (50.0)
Petal.Width > 0.6
| Petal.Width <= 1.7
| | Petal.Length <= 4.9: versicolor (48.0/1.0)
| | Petal.Length > 4.9
| | | Petal.Width <= 1.5: virginica (3.0)
| | | Petal.Width > 1.5: versicolor (3.0/1.0)
| Petal.Width > 1.7: virginica (46.0/1.0)
Number of Leaves : 5
Size of the tree : 9
我想按从右到左的顺序获取属性及其值。所以对于这种情况:
Petal.Width, Petal.Width, Petal.Length, Petal.Length.
我试图将 res 输入到一个因子并输入 运行 命令:
str_extract(paste0(x, collapse=""), perl("(?<=\|)[A-Za-z]+(?=\|)"))
没有成功。 请记住,我们应该忽略左边的字符。
我希望我没有漏掉你的意思,但我假设你想以某种方式创建和存储基于树模型终端节点的规则。就个人而言,我发现模型树构建包(RWeka、party、partykit、rpart)无法让用户在构建模型后创建有用的规则列表。当然,当你的变量和拆分很少时,你可以解释树图。
到目前为止我发现的(我自己使用的)唯一简单可靠的方法是 rpart 包的命令 "path.rpart"。如果你真的想使用 RWeka,解决方案似乎无关紧要,但我会试一试:
library(rpart)
res = rpart(Species ~., data = iris)
res
# n= 150
#
# node), split, n, loss, yval, (yprob)
# * denotes terminal node
#
# 1) root 150 100 setosa (0.33333333 0.33333333 0.33333333)
# 2) Petal.Length< 2.45 50 0 setosa (1.00000000 0.00000000 0.00000000) *
# 3) Petal.Length>=2.45 100 50 versicolor (0.00000000 0.50000000 0.50000000)
# 6) Petal.Width< 1.75 54 5 versicolor (0.00000000 0.90740741 0.09259259) *
# 7) Petal.Width>=1.75 46 1 virginica (0.00000000 0.02173913 0.97826087) *
# capture terminal nodes
terminal_nodes = rownames(res$frame)[res$frame$var =="<leaf>"]
# print rules for the terminal nodes
path.rpart(res ,nodes=terminal_nodes)
# node number: 2
# root
# Petal.Length< 2.45
#
# node number: 6
# root
# Petal.Length>=2.45
# Petal.Width< 1.75
#
# node number: 7
# root
# Petal.Length>=2.45
# Petal.Width>=1.75
# print above rules as list
rules = path.rpart(res ,nodes=terminal_nodes)
listed_rules = unlist(rules)
sapply(rules,"[",-1)
# $`2`
# [1] "Petal.Length< 2.45"
#
# $`6`
# [1] "Petal.Length>=2.45" "Petal.Width< 1.75"
#
# $`7`
# [1] "Petal.Length>=2.45" "Petal.Width>=1.75"
一种方法是将 J48
对象从 RWeka
转换为 party
对象从 partykit
。您只需要 as as.party(res)
,这会为您完成所有解析,returns 一个更易于使用标准化提取函数等的结构。
特别是您可以使用其他关于 ctree
对象等的讨论中给出的所有建议。参见
Get decision tree rule/path pattern for every row of predicted dataset for rpart/ctree package in R
而且我认为以下内容至少可以满足您的部分需求:
library("partykit")
pres <- as.party(res)
partykit:::.list.rules.party(pres)
## 2
## "Petal.Width <= 0.6"
## 5
## "Petal.Width > 0.6 & Petal.Width <= 1.7 & Petal.Length <= 4.9"
## 7
## "Petal.Width > 0.6 & Petal.Width <= 1.7 & Petal.Length > 4.9 & Petal.Width <= 1.5"
## 8
## "Petal.Width > 0.6 & Petal.Width <= 1.7 & Petal.Length > 4.9 & Petal.Width > 1.5"
## 9
## "Petal.Width > 0.6 & Petal.Width > 1.7"
更新:OP 在列表外联系了我一个相关问题,要求提供树的特定打印表示。我在这里包括我的解决方案,以防它对其他人有用。
他想要 ( ) 符号表示层次结构级别以及拆分变量的名称。一种方法是 (1) 提取基础数据的变量名称:
nam <- names(pres$data)
(2) 将树的递归节点结构转为扁平列表(这样在构造想要的字符串时更方便一些):
tr <- as.list(pres$node)
(3a) 初始化字符串:
str <- "("
(3b)递归地在字符串中添加括号and/or变量名:
update_str <- function(x) {
if(is.null(x$kids)) {
str <<- paste(str, ")")
} else {
str <<- paste(str, nam[x$split$varid], "(")
for(i in x$kids) update_str(tr[[i]])
}
}
(3c) 调用递归,从根节点开始:
update_str(tr[[1]])
str
## [1] "( Petal.Width ( ) Petal.Width ( Petal.Length ( ) Petal.Width ( ) ) )"