2016-10-04 124 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組合來構建基於訓練的規則你實現的樹。

希望這是你在找什麼。