如何使用路径遍历rpart对象的树结构以手动清除某些节点?

我在使用rpart构建分类树。我希望基于叶节点的某些标准开发自己的修剪函数。例如,如果某个叶节点在某些标准上表现不佳(在我这里是参数估计的稳定性),我想在树结构中向上查找该叶节点的父节点(即使这个节点不是终端节点)。为此,我想使用路径遍历树,我需要获取叶节点及其父节点,以便在必要时向上遍历树。

让我们看一个例子:

fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis)> fitn= 81 node), split, n, loss, yval, (yprob) * denotes terminal node1) root 81 17 absent (0.79012346 0.20987654) 2) Start>=8.5 62 6 absent (0.90322581 0.09677419) 4) Start>=14.5 29 0 absent (1.00000000 0.00000000) *5) Start< 14.5 33 6 absent (0.81818182 0.18181818) 10) Age< 55 12 0 absent (1.00000000 0.00000000) *11) Age>=55 21 6 absent (0.71428571 0.28571429) 22) Age>=111 14 2 absent (0.85714286 0.14285714) *23) Age< 111 7 3 present (0.42857143 0.57142857) *3) Start< 8.5 19 8 present (0.42105263 0.57894737) *

通过fit$frame,我可以获取关于叶节点的信息:

fit$frame var n wt dev yval complexity ncompete nsurrogate yval2.V1 yval2.V2 yval2.V3 yval2.V4 yval2.V51 Start 81 81 17 1 0.17647059 2 1 1.00000000 64.00000000 17.00000000 0.79012346 0.209876542 Start 62 62 6 1 0.01960784 2 2 1.00000000 56.00000000 6.00000000 0.90322581 0.096774194 <leaf> 29 29 0 1 0.01000000 0 0 1.00000000 29.00000000 0.00000000 1.00000000 0.000000005 Age 33 33 6 1 0.01960784 2 2 1.00000000 27.00000000 6.00000000 0.81818182 0.1818181810 <leaf> 12 12 0 1 0.01000000 0 0 1.00000000 12.00000000 0.00000000 1.00000000 0.0000000011 Age 21 21 6 1 0.01960784 2 0 1.00000000 15.00000000 6.00000000 0.71428571 0.2857142922 <leaf> 14 14 2 1 0.01000000 0 0 1.00000000 12.00000000 2.00000000 0.85714286 0.1428571423 <leaf> 7 7 3 2 0.01000000 0 0 2.00000000 3.00000000 4.00000000 0.42857143 0.571428573 <leaf> 19 19 8 2 0.01000000 0 0 2.00000000 8.00000000 11.00000000 0.42105263 0.57894737

我可以使用fit$where获取数据表中各行的对应叶节点:

现在我想获取叶节点的父节点。我知道path.rpart可以给我所有为了得到叶节点而进行的分裂。例如,对于叶节点23:

> path.rpart(fit, 23)node number: 23  root Start>=8.5 Start< 14.5 Age>=55 Age< 111

我想得到的是节点23的父节点的路径编号?我该如何进行这种关联?

提前感谢您。


回答:

您不需要关于树的任何信息,因为所有节点都有相同的模式。让我们拟合一个更有趣的树:

(fit <- rpart(Kyphosis ~ Age + Number + Start, data = kyphosis,             cp = .0001, minsplit = 5))# n= 81 # # node), split, n, loss, yval, (yprob)#       * denotes terminal node# #   1) root 81 17 absent (0.79012346 0.20987654)  #     2) Start>=8.5 62  6 absent (0.90322581 0.09677419)  #       4) Start>=14.5 29  0 absent (1.00000000 0.00000000) *#       5) Start< 14.5 33  6 absent (0.81818182 0.18181818)  #        10) Age< 55 12  0 absent (1.00000000 0.00000000) *#        11) Age>=55 21  6 absent (0.71428571 0.28571429)  #          22) Age>=98 16  2 absent (0.87500000 0.12500000) *#          23) Age< 98 5  1 present (0.20000000 0.80000000) *#     3) Start< 8.5 19  8 present (0.42105263 0.57894737)  #       6) Age< 11.5 2  0 absent (1.00000000 0.00000000) *#       7) Age>=11.5 17  6 present (0.35294118 0.64705882)  #        14) Start< 5.5 12  6 absent (0.50000000 0.50000000)  #          28) Age>=130.5 2  0 absent (1.00000000 0.00000000) *#          29) Age< 130.5 10  4 present (0.40000000 0.60000000)  #            58) Age< 93 6  2 absent (0.66666667 0.33333333)  #             116) Number< 4.5 3  0 absent (1.00000000 0.00000000) *#             117) Number>=4.5 3  1 present (0.33333333 0.66666667) *#            59) Age>=93 4  0 present (0.00000000 1.00000000) *#        15) Start>=5.5 5  0 present (0.00000000 1.00000000) *

如果可能,每个节点将被分成两个,并编号为node * 2 + 0:1,所以如果您有一个编号为5的节点,它的子节点将是5 * 2 + 0:1。还要注意,使用这种模式,偶数编号的节点不会有子节点。

因此,给定任何节点编号,我们可以回溯找到父节点:

parent(23)# [1]  1  2  5 11 23## 同一节点的子节点应该有相同的路径identical(head(parent(28), -1), head(parent(29), -1))# [1] TRUEparent <- function(x) {  if (x[1] != 1)    c(Recall(if (x %% 2 == 0L) x / 2 else (x - 1) / 2), x) else x}

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注