2016-10-04 119 views
2

我想在这里应用决策树。决策树负责分解每个节点本身。但在第一个节点,我想根据“年龄”分割我的树。我如何强制这一点。?如何在R编程中的决策树中指定分割?

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

回答

2

在每次迭代,决策树会选择拆分最好的变量(基于信息增益/基尼系数,对于购物车,或者基于卡方检验作为条件推断树)。如果您有更好的预测变量来区分这些类别,而这些预测变量可以通过预测变量Age来完成,那么将首先选择该变量。

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

(1)无监督:离散化时代的变量(创建箱例如,0-20,20-40,40-60等根据您的领域知识),并为每个年龄段设置数据子集,然后在这些段中的每一个上训练一个单独的决策树。

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

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

5

ctree()中没有内置选项。最简单的方法来做到这一点“手动”很简单:

  1. 了解一棵树,只有Age作为解释变量,maxdepth = 1所以,这只是创建了一个单一的分裂。

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

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

这就是你想要的(虽然我通常不会推荐这么做......)。

如果您使用的ctree()实现,您还可以将这三棵树再次合并到一棵树中以进行可视化和预测等。它需要一些黑客行为,但仍然可行。

我将使用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

0

您可以使用软件rpart派对包组合来实现这样的操作。

请注意,如果你使用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) 

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

稍后,可以使用partynodepartysplit组合来构建基于训练的规则你实现的树。

希望这是你在找什么。