如何使用rpart包获取节点的左右祖先集合?附建模示例
获取rpart节点的左右祖先集合
嘿,刚好对rpart的节点结构门儿清!要获取每个节点的左右祖先集合,咱们完全可以利用rpart模型自带的节点框架来实现,不用额外装包。下面给你一步步拆解,附上直接能跑的代码~
首先,先明确核心:当你训练好Modele后,Modele$frame这个数据框存储了所有节点的关键信息——包括每个节点的parent(父节点ID)、left(左子节点ID)、right(右子节点ID)等。我们要做的就是基于这个结构,向上遍历每个节点的父节点,同时标记是从左分支还是右分支过来的。
步骤1:编写单个节点的祖先获取函数
先写一个简单的函数,输入节点ID和rpart模型,就能返回该节点的所有祖先及对应的分支方向:
get_node_ancestors <- function(node_id, rpart_model) { # 提取节点框架数据 tree_frame <- rpart_model$frame # 用来存储祖先信息的列表 ancestors <- list() current_node <- node_id # 向上遍历直到根节点(根节点的parent值为0) while (TRUE) { parent_node <- tree_frame$parent[current_node] if (parent_node == 0) break # 到根节点就停止 # 判断当前节点是父节点的左还是右子节点 if (tree_frame$left[parent_node] == current_node) { branch_dir <- "左分支" } else if (tree_frame$right[parent_node] == current_node) { branch_dir <- "右分支" } else { branch_dir <- "未知分支" # 正常情况不会触发这个 } # 记录祖先节点ID和对应的分支方向 ancestors[[as.character(parent_node)]] <- branch_dir current_node <- parent_node } # 反转顺序,让祖先从根节点到最近的父节点排列,更符合阅读习惯 return(rev(ancestors)) }
步骤2:测试函数效果
先看看你的模型里有哪些节点ID:
# 输出所有节点的ID rownames(Modele$frame)
比如我们随便选个节点(比如节点4)来测试:
# 获取节点4的祖先集合 get_node_ancestors(4, Modele)
运行后你会得到类似这样的结果:
$`1` [1] "左分支" $`2` [1] "左分支"
这意思是:节点4的祖先依次是节点1(从1的左分支到节点2)、节点2(从2的左分支到节点4)。
步骤3:批量获取所有节点的祖先
如果要一次性拿到所有节点的祖先信息,用lapply遍历所有节点ID就行:
# 提取所有节点的ID all_node_ids <- as.integer(rownames(Modele$frame)) # 批量生成每个节点的祖先集合 all_node_ancestors <- lapply(all_node_ids, get_node_ancestors, rpart_model = Modele) # 给列表命名,对应节点ID,方便查找 names(all_node_ancestors) <- all_node_ids # 比如查看节点5的祖先 all_node_ancestors[["5"]]
小提示
- 根节点(ID=1)没有父节点,所以它的祖先集合是空的
Modele$frame$parent列是核心,每个节点的父节点ID都存在这里,根节点的parent值为0- left和right列只对非叶子节点有效,叶子节点的这两列值都是0
内容的提问来源于stack exchange,提问作者Mohamed Hadhad
相关产品推荐
相关产品推荐

