Как получить имя родительского узла в rpart?

Привет, я сейчас пытаюсь извлечь некоторую информацию из родительского узла, хранящуюся в объекте вечеринки, например, ID. На данный момент я могу получить идентификаторы для терминальных узлов, используя:

 fit<-rpart(CommuteDistance ~.,data = Clients)
 pr<-as.party(fit)
 nodeids(pr,terminal=TRUE)

Но как я могу получить родительские идентификаторы? И если возможно, как я могу получить имена узлов?

2 ответа

Поскольку идентификаторы узлов соответствуют хорошему шаблону, вы можете определить родительский идентификатор просто по parent_id = floor(node_id / 2).

Вот минимальный рабочий пример для получения таблицы с сопоставлением идентификаторов узлов их родительским идентификаторам. В нем я использую функцию rownames_to_column из tidyverse, чтобы получить node_ids, а не использовать partykit, но подход будет аналогичным:

      library("rpart")
library("tidyverse")
fit <- rpart(Petal.Length ~ ., data = iris)


get_frame_with_parent <- function(x) {
  frame_with_parent <- 
    x$frame %>%
    tibble::rownames_to_column(var = "node_id") %>%
    mutate(node_id = as.numeric(node_id),
           parent_id = floor(node_id/2))
  frame_with_parent
}
frame_with_parent

Получить имена узлов можно с помощью меток (fit)

Для минимального рабочего примера, объединяющего эти две вещи, чтобы получить таблицу, содержащую идентификаторы узлов, метки узлов, родительские идентификаторы и родительские метки:

      library("rpart")
library("tidyverse")
fit <- rpart(Petal.Length ~ ., data = iris)

get_frame_with_parent <- function(x) {
  frame_with_parent <- 
    x$frame %>%
    mutate(node_label = labels(x)) %>%
    tibble::rownames_to_column(var = "node_id") %>%
    mutate(node_id = as.numeric(node_id),
           parent_id = floor(node_id/2))
  
  frame_with_parent <-
    frame_with_parent %>%
    left_join(
      dplyr::select(frame_with_parent, node_id, node_label),
      by = c("parent_id" = "node_id"),
      suffix = c("", ".y")
    ) %>%
    dplyr::rename(parent_label = node_label.y)
  
  frame_with_parent
}
get_frame_with_parent(fit)

Нет легко доступных функций, чтобы извлечь это удобно. Но нетрудно просто пройти рекурсивный partynode структурировать и получить пользовательские количества, которые вас интересуют. Это также помогает преобразовать рекурсивные partynode в плоский список в первую очередь.

Для воспроизводимого примера рассмотрим следующее rpart дерево и его party представление:

library("rpart")
fit <- rpart(Petal.Length ~ ., data = iris)
library("partykit")
pr <- as.party(fit)

После этого вы можете легко преобразовать в as.list(pr$node) который возвращает всю информацию из рекурсивного partynode состав. В частности это содержит $id каждого узла и $kids Идентификаторы (если есть). Таким образом, мы можем легко извлечь их с sapply() и пользовательская функция:

sapply(as.list(pr$node), function(n) {
  if(is.null(n$kids)) c(n$id, NA, NA) else c(n$id, n$kids)
})
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,]    1    2    3    4    5    6    7    8    9
## [2,]    2   NA    4    5   NA   NA    8   NA   NA
## [3,]    3   NA    7    6   NA   NA    9   NA   NA

В первом столбце показано, что узел 1 имеет двух дочерних узлов, узлы 2 и 3. Узел 2 является терминальным узлом, поскольку у него нет дочерних узлов (второй столбец), в то время как узел 3 снова имеет двух дочерних узлов, узлы 4 и 7 и т. Д.

Другие вопросы по тегам