Найти элементы данных во фрейме данных, которые передают правило для узла в древовидной модели?

Поэтому я использовал пакет rpart для создания древовидной модели, и я нашел интересное правило и подумал, есть ли простой способ увидеть, какие наблюдения в этом фрейме данных соответствуют этому правилу.

Кажется очень утомительным использовать path.rpart, чтобы найти путь, по которому он прошел по дереву, и вручную ввести эти фильтры в кадр данных, чтобы найти их. Есть ли способ, где я могу передать дерево и / или узел, а также фрейм данных и вернуть все элементы в этом фрейме, который закончился на этом узле?

 flodel29 мая 2014 г., 03:25
Вы получите лучшую помощь, если сможете привести воспроизводимый пример.

Ответы на вопрос(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), ]
}
Решение Вопроса

Я изменил код в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
 mandroid16 сент. 2014 г., 01:05
Это работает точно так же, как и при поиске наблюдений в обучающем наборе, однако я заметил, что если я попытаюсь пройти набор тестов и найти наблюдения интересного правила, я получу ошибку, так как набор тестов отличается от тренировочный набор. Есть ли способ использовать это с фреймами данных другого размера?
 MrFlick16 сент. 2014 г., 01:07
Было бы полезно, если бы у вас был воспроизводимый пример.
 mandroid05 июн. 2014 г., 20:07
Похоже, что нет встроенного, но похоже, что он должен работать хорошо. Спасибо!
 mandroid19 сент. 2014 г., 20:22
Например, если исходное дерево было построено с подмножеством фрейма данных кифоза (что-то вроде кифоза [поезд], где поезд - случайная выборка строк). Затем при использовании subset.rpart (fit, kyphosis [test,]), где test - это другой образец строк, он вернет подмножество. Таким образом, в основном, чтобы построить дерево с одним набором данных, а затем получить подмножество с другим фреймом данных.

Ваш ответ на вопрос