【问题标题】:Find the data elements in a data frame that pass the rule for a node in a tree model?在数据框中查找通过树模型中节点规则的数据元素?
【发布时间】:2014-07-18 09:51:08
【问题描述】:

所以我使用 rpart 包创建了一个树模型,我发现了一个有趣的规则,并想知道是否有一种简单的方法可以查看该数据框中的哪些观察结果通过了该规则。

使用 path.rpart 查找它沿树所走的路径似乎非常繁琐,然后手动将这些过滤器输入到数据框中以查找它们。有没有一种方法可以传递树和/或节点以及数据框并返回该帧中以该节点结束的所有元素?

【问题讨论】:

  • 如果你能提供一个可重现的例子,你会得到更好的帮助。

标签: r rpart


【解决方案1】:

我修改了path.rpart 中的代码以返回属于特定节点的数据子集,而不是返回有关该节点的信息。它可以通过单击绘图或传递节点来工作,就像path.rpart 函数一样。这是代码

subset.rpart <- function (tree, df, nodes) {
    if (!inherits(tree, "rpart")) 
        stop("Not a legitimate \"rpart\" object")
    stopifnot(nrow(df)==length(tree$where))
    frame <- tree$frame
    n <- row.names(frame)
    node <- as.numeric(n)

    if (missing(nodes)) {
        xy <- rpart:::rpartco(tree)
        i <- identify(xy, n = 1L, plot = FALSE)
        if(i> 0L) {
             return( df[tree$where==i, ] )
        } else {
            return(df[0,])
        }
    }
    else {
        if (length(nodes <- rpart:::node.match(nodes, node)) == 0L) 
            return(df[0,])
        return ( df[tree$where %in% as.numeric(nodes), ] )
    }
}

我将在包中的一些示例数据上使用它

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

然后要查找特定节点的观察结果,运行

subset.rpart(fit, kyphosis)

并单击绘图上的一个节点。完成后,将返回该节点的所有观察结果。您必须使用与建模相同的data.frame 才能正常工作。除了点击一个点,您还可以通过path.rpart 传递您发现的节点名称

# path.rpart(fit)  
#  node number: 10  ---> looks interesting
#    root
#    Start>=8.5
#    Start< 14.5
#    Age< 55

subset.rpart(fit, kyphosis, 10)
#    Kyphosis Age Number Start
# 14   absent   1      4    12
# 20   absent  27      4     9
# 26   absent   9      5    13
# 37   absent   1      3     9
# 39   absent  20      6     9
# 42   absent  35      3    13
# 57   absent   2      3    13
# 59   absent  51      7     9
# 66   absent  17      4    10
# 69   absent  18      4    11
# 78   absent  26      7    13
# 81   absent  36      4    13

【讨论】:

  • 听起来好像没有内置的,但这看起来应该可以很好地工作。谢谢!
  • 当在训练集中查找观察结果时,这完全符合需要,但是我注意到,如果我尝试通过测试集并找到有趣规则的观察结果,我会收到一个错误,因为测试集的大小与训练集的大小不同。有没有办法将它与不同大小的数据框一起使用?
  • 如果你有一个可重现的例子会很有帮助。
  • 例如,如果原始树是使用 kyphosis 数据帧的子集构建的(类似于 kyphosis[train,],其中 train 是行的随机样本)。然后,当使用 subset.rpart(fit, kyphosis[test,]) 时,其中 test 是不同的行样本,它将返回子集。所以基本上,用一组数据构建树,然后用不同的数据框获取子集。
【解决方案2】:
#' subset of rpart node: return logical index
#' @param tree rpart model
#' @param node which node/leaf?
#' @export
subset_rpart <- function (tree, node) {
  nodes = as.numeric(rownames(tree$frame))
  nodes = log(nodes, 2)
  lower = log(node, 2)
  upper = log(node + 1, 2)
  a = floor(lower)
  lower_ = lower - a
  upper_  = upper - a
  nodes_ = nodes %% 1
  w = which(((nodes_ >= lower_ & nodes_ < upper_) | (nodes_ + 1 < upper_)) & nodes >= lower)
  tree$where %in% w
}



#' subset df by subset_rpart
#' @param tree rpart model
#' @param node node number
#' @param df df
#' @export
subset.rpart = function(tree, node, df){
  df[subset_rpart(tree, node), ]
}

【讨论】:

  • 赞美你的方法!即使对于非终端节点它也能很好地工作,但我不明白为什么!你能解释一下它的作用吗?
猜你喜欢
  • 2020-05-06
  • 2021-06-04
  • 2022-11-18
  • 2013-03-05
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多