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

时间:2016-10-04 05:35:30

标签: r machine-learning split tree party

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

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

3 个答案:

答案 0 :(得分:9)

ctree()中没有内置选项可以执行此操作。 “手动”执行此操作的最简单方法是:

  1. 了解仅使用Age作为解释变量和maxdepth = 1的树,以便仅创建一个拆分。

  2. 使用步骤1中的树拆分数据,并为左侧分支创建子树。

  3. 使用步骤1中的树拆分数据,并为右侧分支创建子树。

  4. 这可以满足您的需求(虽然我通常不建议这样做......)。

    如果您使用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)
    

    combined tree

答案 1 :(得分:2)

在每次迭代时,决策树将选择用于拆分的最佳变量(基于信息增益/基尼指数,对于CART,或基于卡方检验,如条件推断树)。如果你有更好的预测变量来分类,那么预测变量可以通过预测器Age来完成,那么将首先选择该变量。

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

(1)无监督:将Age变量(根据您的领域知识创建箱子,例如,0-20,20-40,40-60等)和每个年龄箱的数据子集,然后训练每个细分市场都有一个单独的决策树。

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

(3)监督合奏:您可以使用Randomforest分类器来查看您的Age变量的重要性。

答案 2 :(得分:0)

您可以使用 rpart partykit 组合来实现此类操作。

请注意,如果您使用 ctree 来训练DT,那么使用 data_party 函数从不同节点提取数据,提取的数据集中包含的唯一变量将是训练仅限变量,在您的情况下为Age。

我们必须在第一步中使用rpart来训练带有选定变量的模型,因为有一种方法可以使用 rpart 训练DT,这样您就可以将所有变量保留在提取的数据集中将这些变量作为训练变量:

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

使用此方法,您唯一的培训变量是Age,您可以将 rpart 树转换为 partykit 并从不同节点提取数据并拼命训练:< / p>

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

现在您有两个基于Age的数据集拆分,以及将来要用于训练DT的所有变量,您可以根据您认为合适的子集构建DT,使用rpart或ctree。

稍后您可以使用 partynode partysplit 组合根据您实现的培训规则构建树。

希望这就是你要找的东西。