我是R的新手,我正在使用party:ctree
库尝试分类决策树。一切似乎都很好。我得到了预期的结果和一个很好描述的情节。
现在,如果我想从拟合的摘要中提取结果,我将遍历每个节点并提取信息。幸运的是,这已经由@baydoganm here编写。我想扩展此代码并将结果写入dataframe
而不是打印它。
可重现的代码:
library(party)
ct <- ctree(Species ~ ., data = iris)
traverse <- function(treenode){
if(treenode$terminal){
bas=paste(treenode$nodeID,treenode$prediction)
print(bas) #here the results are printed
return(0)
}
traverse(treenode$left)
traverse(treenode$right)
}
traverse(ct@tree) #function call
这很好用,我在控制台上获得输出。现在,如果我想将结果写入数据框,我将遇到问题。
到目前为止我尝试过:尝试使用可变闭包()写入列表。但不知道如何让它发挥作用。
l <- list()
count = 0
traverse1 <- function(treenode,l){
if((treenode$terminal == T)){
count <<- count + 1
print(count)
node = c(treenode$nodeID)
pred = c(treenode$prediction)
l[[count]] <- data.frame(node,pred) #write results in the dataframe
}
traverse1(treenode$left,l)
traverse1(treenode$right,l)
}
test <- traverse1(ct@tree,l)# function call
我只获得上次调用函数的结果,其余为null
答案 0 :(得分:2)
智能方式:使用assign()
在全球环境中撰写:
require(party)
ct <- ctree(Species ~ ., data = iris)
tt <- NULL
traverse <- function(treenode){
if(treenode$terminal){
bas=paste(treenode$nodeID,treenode$prediction)
assign("tt", c(tt, bas), envir = .GlobalEnv)
print(bas) #here the results are printed
return(0)
}
traverse(treenode$left)
traverse(treenode$right)
}
traverse(ct@tree) #function call
data.frame(node.id = unlist(lapply(str_split(tt, " "), function(x) x[[1]]))
, prediction = unlist(lapply(str_split(tt, " "), function(x) x[[2]])))
脏话:使用sink()
保存您的打印输出。
sink(file = "test.csv", append = T)
traverse(ct@tree) #function call
sink()
tt <- read.csv("test.csv", header = F)
答案 1 :(得分:2)
如果您使用ctree()
软件包中新的改进的partykit
实施方案,那么它在fitted
组件中包含您需要的所有信息:
library("partykit")
ct <- ctree(Species ~ ., data = iris)
head(fitted(ct))
## (fitted) (weights) (response)
## 1 2 1 setosa
## 2 2 1 setosa
## 3 2 1 setosa
## 4 2 1 setosa
## 5 2 1 setosa
## 6 2 1 setosa
因此,对于分类树,您可以使用xtabs()
(或table()
)轻松构建响应的绝对频率表。对于回归树,tapply()
可以很容易地用于获取资金,中位数等。
在这种情况下,让我们以表格形式查看绝对频率和相对频率:
tab <- xtabs(~ `(fitted)` + `(response)`, data = fitted(ct))
tab
## (response)
## (fitted) setosa versicolor virginica
## 2 50 0 0
## 5 0 45 1
## 6 0 4 4
## 7 0 1 45
ptab <- prop.table(tab, 1)
ptab
## (response)
## (fitted) setosa versicolor virginica
## 2 1.00000000 0.00000000 0.00000000
## 5 0.00000000 0.97826087 0.02173913
## 6 0.00000000 0.50000000 0.50000000
## 7 0.00000000 0.02173913 0.97826087
获取频率表tab
的另一种途径是:table(predict(ct, type = "node"), iris$Species)
。
如果你想将这些中的任何一个变成一个数据框,那么as.data.frame()
就可以正常工作(可能加上一些重新标记的变量......):
as.data.frame(ptab)
## X.fitted. X.response. Freq
## 1 2 setosa 1.00000000
## 2 5 setosa 0.00000000
## 3 6 setosa 0.00000000
## 4 7 setosa 0.00000000
## 5 2 versicolor 0.00000000
## 6 5 versicolor 0.97826087
## 7 6 versicolor 0.50000000
## 8 7 versicolor 0.02173913
## 9 2 virginica 0.00000000
## 10 5 virginica 0.02173913
## 11 6 virginica 0.50000000
## 12 7 virginica 0.97826087