如何在R编程中指定决策树中的拆分?

Yog*_*esh 3 tree split r machine-learning party

我想在这里应用决策树.决策树负责在每个节点本身进行拆分.但在第一个节点我想根据"年龄"分割我的树.我该怎么强迫呢?

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

Ach*_*eis 9

没有内置选项可以做到这一点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)
Run Code Online (Sandbox Code Playgroud)

但请注意,使用公式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 *
Run Code Online (Sandbox Code Playgroud)

最后,我们建立一个包含所有数据的联合模型框架,并将其与新的关节树相结合.添加了有关拟合节点和响应的一些信息,以便能够将树转换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)
Run Code Online (Sandbox Code Playgroud)

然后我们就完成了,并且可以使用强制的第一次拆分来可视化我们的组合树:

plot(tr)
Run Code Online (Sandbox Code Playgroud)

组合树


San*_*Dey 5

在每次迭代中,决策树都会选择最佳变量进行分割(对于 CART,基于信息增益/基尼指数,对于条件推理树,基于卡方检验)。如果您有更好的预测变量,可以比预测变量 Age 更好地分隔类别,那么将首先选择该变量。

我认为根据您的要求,您可以做以下几件事:

(1) 无监督:离散化年龄变量(根据您的领域知识创建箱,例如 0-20、20-40、40-60 等)并对每个年龄箱的数据进行子集化,然后训练单独的决策每个段上的树。

(2) 监督:继续丢弃其他预测变量,直到首先选择年龄。现在,您将得到一个决策树,其中选择年龄作为第一个变量。使用决策树创建的年龄规则(例如,年龄 > 36 和年龄 <= 36)将数据子集分为 2 部分。在每个部分上分别学习包含所有变量的完整决策树。

(3)Supervised Ensemble:你可以使用Randomforest分类器来看看你的Age变量有多重要。