2015-10-24 2 views
2

Я пытаюсь построить дерево регрессии, сгенерированное с помощью rpart, с использованием partykit. Предположим, что используемая формула - y ~ x1 + x2 + x3 + ... + xn. То, что я хотел бы получить, - это дерево с ящиками в терминальных узлах с меткой сверху, в которой перечислены 10-й, 50-й и 90-й проценты распределения значений y для наблюдений, назначенных каждому узлу, то есть над прямоугольником, представляющим каждый терминал, я хотел бы отобразить метку типа «10-й процентиль = 200 долларов, средний = $ 247, 90-й процентиль = 292 доллара».partykit: Отображение значений процентиля конечных узлов над ящиками терминала терминала

Код ниже создает желаемое дерево:

library("rpart") 
fit <- rpart(Price ~ Mileage + Type + Country, cu.summary) 
library("partykit") 
tree.2 <- as.party(fit) 

Следующий код создает концевые участки, но без требуемых этикеток на концевых узлах:

plot(tree.2, type = "simple", terminal_panel = node_boxplot(tree.2, 
    col = "black", fill = "lightgray", width = 0.5, yscale = NULL, 
    ylines = 3, cex = 0.5, id = TRUE)) 

Если я могу отображать среднее у -значение для узла, тогда должно быть достаточно просто увеличить метку с процентилями, поэтому мой первый шаг должен отображать над каждым терминальным узлом только его среднее значение y.

Я знаю, что могу получить среднее у-значения в пределах узла (здесь узел # 12) с кодом, например, как это:

colMeans(tree.2[12]$fitted[2]) 

Так что я попытался создать формулу и использовать параметр mainlab boxplot панель-производящая функция для генерации метки, содержащей это значит:

labf <- function(node) colMeans(node$fitted[2]) 
plot(tree.2, type = "simple", terminal_panel = node_boxplot(tree.2, 
    col = "black", fill = "lightgray", width = 0.5, yscale = NULL, 
    ylines = 3, cex = 0.5, id = TRUE, mainlab = tf)) 

к сожалению, это генерирует сообщение об ошибке:

Error in mainlab(names(obj)[nid], sum(wn)) : unused argument (sum(wn)). 

Но, кажется, это находится на правильном пути, так как если я использую:

plot(tree.2, type = "simple", terminal_panel = node_boxplot(tree.2, 
    col = "black", fill = "lightgray", width = 0.5, yscale = NULL, 
    ylines = 3, cex = 0.5, id = TRUE, mainlab = colMeans(tree.2$fitted[2]))) 

тогда я получаю правильное среднее значение у-у корневого узла отображается. Я был бы признателен за помощь в исправлении ошибки, описанной выше, чтобы показать средние значения y для каждого отдельного терминального узла. Оттуда, это должно быть легко добавить в другие процентили и форматировать вещи красиво.

+0

Не могли бы вы попытаться создать воспроизводимую версию проблемы? Тогда я попытаюсь взглянуть на него. –

+0

Несомненно. Спасибо @AchimZeileis! В приведенном ниже коде используется набор данных Consumer Reports, который поставляется с RPART. 'подходят <- rpart (Цена ~ Пробег + Тип + Страна, cu.summary)' ' пар (XPD = TRUE) участок (подходит, сжатие = TRUE)' ' текст (подходит, use.n = TRUE) '' tree.2 <-as.party (подходит) '' участок (tree.2) ' Это будет генерировать дерево участок с присуща рефлективными, вербальными на терминал узлов. То, что я пытаюсь сделать, это поместить среднее (а затем и некоторые другие процентили) над каждым из терминальных узлов в метке. Поэтому вместо «Node 4 (n = 21)» самый левый терминал будет иметь метку, обозначающую что-то вроде «mean = 7629.048» – djr99

ответ

2

В принципе, вы на правильном пути. Но если mainlab должен быть функцией, это не функция node, а id и nobs, см. ?node_boxplot. Кроме того, вы можете вычислить таблицу средств (или некоторые квантили) легко для всех терминальных узлов с использованием данных fitted для всего дерева:

tab <- tapply(tree.2$fitted[["(response)"]], 
    factor(tree.2$fitted[["(fitted)"]], levels = 1:length(tree.2)), 
    FUN = mean) 

Тогда вы можете подготовить это для построения округления/форматирование:

tab <- format(round(tab, digits = 3)) 
tab 
##   1   2   3   4   5   6 
## "  NA" "  NA" "  NA" " 7629.048" "  NA" "12241.552" 
##   7   8   9   10   11   12 
## "14846.895" "22317.727" "  NA" "  NA" "17607.444" "21499.714" 
##   13 
## "27646.000" 

И для добавления этого в дисплей, написать свою собственную вспомогательную функцию для mainlab:

mlab <- function(id, nobs) paste("Mean =", tab[id]) 
plot(tree.2, tp_args = list(mainlab = mlab)) 

enter image description here

+0

Спасибо @AchimZeileis! Это решило мою проблему, и я смог расширить пример, который вы предоставили, чтобы включить процентили. Я очень ценю помощь и подробный пример кода. Есть ли способ аналогичного изменения меток для ребер (например, для замены запятых символами новой строки) с помощью аргумента ep_args? Я нашел параметр «split», но не вижу его влияния. Установка justmin = 3 предотвращает наложение красных меток, но они все еще довольно длинные Кроме того, что такое 'nobs'? Число наблюдений? Я не могу найти детали этого параметра. Еще раз большое спасибо! – djr99

+0

В настоящее время символы новой строки вместо запятых не поддерживаются, вам придется взломать для вас свою версию 'edge_simple'. Я постараюсь подумать об этом при работе над следующей версией 'partykit'. Что касается «дворян»: это означает «количество наблюдений», как в функции экстрактора '? Nobs'. Вероятно, это должно быть документировано лучше. –

+0

Еще раз спасибо! Я считаю, что «partykit» невероятно полезен. – djr99

Смежные вопросы