Как указать разделение дерева решений в программировании на R?

Я пытаюсь применить здесь дерево решений. Дерево решений заботится о разбиении на каждом узле. Но на первом узле я хочу разделить свое дерево на основе «Возраст». Как мне заставить это.?

library(party)    
fit2 <- ctree(Churn ~ Gender + Age + LastTransaction + Payment.Method + spend + marStat, data = tsdata)

person Yogesh    schedule 04.10.2016    source источник


Ответы (3)


В ctree() нет встроенной опции для этого. Самый простой способ сделать это «вручную» — это просто:

  1. Изучите дерево только с Age в качестве объясняющей переменной и maxdepth = 1, чтобы создать только одно разделение.

  2. Разделите данные, используя дерево из шага 1, и создайте поддерево для левой ветви.

  3. Разделите данные, используя дерево из шага 1, и создайте поддерево для правой ветви.

Это делает то, что вы хотите (хотя обычно я бы не рекомендовал этого делать...).

Если вы используете реализацию ctree() из partykit, вы также можете снова объединить эти три дерева в одно дерево для визуализации, прогнозов и т. д. Это требует небольшого взлома, но все же выполнимо.

Я проиллюстрирую это с помощью данных iris и принудительно разделю переменную Sepal.Length, которая иначе не использовалась бы в дереве. Выучить три дерева выше легко:

library("partykit")
data("iris", package = "datasets")
tr1 <- ctree(Species ~ Sepal.Length,     data = iris, maxdepth = 1)
tr2 <- ctree(Species ~ Sepal.Length + ., data = iris,
  subset = predict(tr1, type = "node") == 2)
tr3 <- ctree(Species ~ Sepal.Length + ., data = iris,
  subset = predict(tr1, type = "node") == 3)

Обратите внимание, однако, что важно использовать формулу с Sepal.Length + ., чтобы убедиться, что переменные во фрейме модели упорядочены одинаково во всех деревьях.

Далее следует самый технический шаг: нам нужно извлечь необработанную структуру node из всех трех деревьев, исправить узлы id, чтобы они были в правильной последовательности, а затем объединить все в один узел:

fixids <- function(x, startid = 1L) {
  id <- startid - 1L
  new_node <- function(x) {
    id <<- id + 1L
    if(is.terminal(x)) return(partynode(id, info = info_node(x)))
    partynode(id,
      split = split_node(x),
      kids = lapply(kids_node(x), new_node),
      surrogates = surrogates_node(x),
      info = info_node(x))
  }

  return(new_node(x))   
}
no <- node_party(tr1)
no$kids <- list(
  fixids(node_party(tr2), startid = 2L),
  fixids(node_party(tr3), startid = 5L)
)
no
## [1] root
## |   [2] V2 <= 5.4
## |   |   [3] V4 <= 1.9 *
## |   |   [4] V4 > 1.9 *
## |   [5] V2 > 5.4
## |   |   [6] V4 <= 4.7
## |   |   |   [7] V4 <= 3.6 *
## |   |   |   [8] V4 > 3.6 *
## |   |   [9] V4 > 4.7
## |   |   |   [10] V5 <= 1.7 *
## |   |   |   [11] V5 > 1.7 *

И, наконец, мы создаем фрейм модели соединения, содержащий все данные, и объединяем его с новым деревом соединений. Добавлена ​​некоторая информация о подогнанных узлах и ответе, чтобы иметь возможность превратить дерево в constparty для хорошей визуализации и прогнозов. Информацию об этом см. в разделе vignette("partykit", package = "partykit"):

d <- model.frame(Species ~ Sepal.Length + ., data = iris)
tr <- party(no, 
  data = d,
  fitted = data.frame(
    "(fitted)" = fitted_node(no, data = d),
    "(response)" = model.response(d),
    check.names = FALSE),
  terms = terms(d),
)
tr <- as.constparty(tr)

И тогда мы закончили и можем визуализировать наше комбинированное дерево с принудительным первым разделением:

plot(tr)

комбинированное дерево

person Achim Zeileis    schedule 05.10.2016

На каждой итерации дерево решений будет выбирать наилучшую переменную для разделения (либо на основе прироста информации / индекса Джини, для CART, либо на основе критерия хи-квадрат, как для условного дерева вывода). Если у вас есть лучшая переменная-предиктор, которая разделяет классы больше, чем это может сделать предиктор Age, то эта переменная будет выбрана первой.

Я думаю, исходя из ваших требований, вы можете сделать следующие несколько вещей:

(1) Неконтролируемый: дискретизируйте переменную возраста (создайте ячейки, например, 0-20, 20-40, 40-60 и т. д., в соответствии с вашими знаниями предметной области) и подмножьте данные для каждой из возрастных ячеек, затем обучите отдельное решение дерево на каждом из этих сегментов.

(2) Под наблюдением: продолжайте отбрасывать другие переменные-предикторы, пока возраст не будет выбран первым. Теперь вы получите дерево решений, в котором в качестве первой переменной выбран возраст. Используйте правила для возраста (например, возраст > 36 и возраст ‹ = 36), созданные деревом решений, чтобы разделить данные на 2 части. По каждой из частей изучите полное дерево решений со всеми переменными по отдельности.

(3) Контролируемый ансамбль: вы можете использовать классификатор Randomforest, чтобы увидеть, насколько важна ваша переменная Age.

person Sandipan Dey    schedule 04.10.2016

Вы можете использовать комбинацию rpart и partykit для выполнения такой операции.

Обратите внимание, что если вы используете ctree для обучения DT, а затем используете функцию data_party для извлечения данных из другого узла, единственными переменными, включенными в извлеченный набор данных, будут только обучающие переменные, в вашем случае Возраст.

Мы должны использовать rpart на первом этапе для обучения модели с выбранной переменной, потому что есть способ использовать rpart для обучения DT таким образом, что вы можете сохранить все свои переменные в извлеченном наборе данных, не помещая эти переменные в качестве обучающих переменных:

library(rpart)
fit2 <- rpart(Churn ~ . -(Gendere + LastTransaction + Payment.Method + spend + marStat) , data = tsdata, maxdepth = 1)

Используя этот метод, вашей единственной обучающей переменной будет возраст, и вы можете преобразовать свое дерево rpart в partykit, извлечь данные из другого узла и отчаянно обучать их:

library(partykit)
fit2party <- as.party(fit2)
dataset1 <- data_party(fit2party, id = 2)
dataset2 <- data_party(fit2party, id = 3)

Теперь у вас есть два набора данных, разделенных на основе возраста, со всеми переменными, которые вы хотите использовать для обучения DT в будущем, вы можете построить DT на основе этих подмножеств, как считаете нужным, используя rpart или ctree.

Позже вы можете использовать комбинацию partynode и partysplit для построения дерева на основе достигнутых вами правил обучения.

Надеюсь, это то, что вы ищете.

person Richard Li    schedule 20.06.2017