1. 程式人生 > >分類-迴歸樹模型(CART)在R語言中的實現

分類-迴歸樹模型(CART)在R語言中的實現

CART模型,即Classification And Regression Trees。它和一般迴歸分析類似,是用來對變數進行解釋和預測的工具,也是資料探勘中的一種常用演算法。如果因變數是連續資料,相對應的分析稱為迴歸樹,如果因變數是分類資料,則相應的分析稱為分類樹。

決策樹是一種倒立的樹結構,它由內部節點、葉子節點和邊組成。其中最上面的一個節點叫根節點。 構造一棵決策樹需要一個訓練集,一些例子組成,每個例子用一些屬性(或特徵)和一個類別標記來描述。構造決策樹的目的是找出屬性和類別間的關係,一旦這種關係找出,就能用它來預測將來未知類別的記錄的類別。這種具有預測功能的系統叫決策樹分類器。其演算法的優點在於:1)可以生成可以理解的規則。2)計算量相對來說不是很大。3)可以處理多種資料型別。4)決策樹可以清晰的顯示哪些變數較重要。

下面以一個例子來講解如何在R語言中建立樹模型。為了預測身體的肥胖程度,可以從身體的其它指標得到線索,例如:腰圍、臀圍、肘寬、膝寬、年齡。

# 首先載入所需軟體包 
> library(rpart) 
> library(maptree)
> library(TH.data)

# 讀入樣本資料 
> data("bodyfat", package="TH.data")  # 原文mboost包中沒有此資料集了,改用TH.data

rpart()函式用法:

rpart(formula, data, weights, subset, na.action = na.rpart, method, model = FALSE, x = FALSE, y = TRUE, parms, control, cost, …)

主要引數說明:
formula:迴歸方程形式:例如 y~x1+x2+x3。
data:資料:包含前面方程中變數的資料框(dataframe)。
na.action:缺失資料的處理辦法:預設辦法是刪除因變數缺失的觀測而保留自變數缺失的觀測。
method:根據樹末端的資料型別選擇相應變數分割方法,本引數有四種取值:連續型 =>“anova”;離散型 =>“class”;計數型(泊松過程) =>“poisson”;生存分析型]“exp”。程式會根據因變數的型別自動選擇方法,但一般情況下最好還是指明本引數,以便讓程式清楚做哪一種樹模型。
parms:用來設定三個引數:先驗概率、損失矩 陣、分類純度的度量方法。
control:

控制每個節點上的最小樣本量、交叉驗證的次數、複雜性參量:即cp:complexity pamemeter,這個引數意味著對每一步拆分,模型的擬合優度必須提高的程度,等等。

# 建立公式 
> formula <- DEXfat~age+waistcirc+hipcirc+elbowbreadth+kneebreadth

# 用rpart命令構建樹模型,結果存在fit變數中 
> fit <- rpart(formula,method='anova',data=bodyfat)

# 直接呼叫fit可以看到結果
> fit
n= 71 

node), split, n, deviance, yval
      * denotes terminal node

 1) root 71 8535.98400 30.78282  
   2) waistcirc< 88.4 40 1315.35800 22.92375  
     4) hipcirc< 96.25 17  285.91370 18.20765 *
     5) hipcirc>=96.25 23  371.86530 26.40957  
      10) waistcirc< 80.75 13  117.60710 24.13077 *
      11) waistcirc>=80.75 10   98.99016 29.37200 *
   3) waistcirc>=88.4 31 1562.16200 40.92355  
     6) hipcirc< 109.9 13  136.29600 35.27846 *
     7) hipcirc>=109.9 18  712.39870 45.00056 *

# 也可以用畫圖方式將結果表達得更清楚一些 
> draw.tree(fit) 

這裡寫圖片描述

建立樹模型要權衡兩方面問題,一個是要擬合得使分組後的變異較小,另一個是要防止過度擬合,而使模型的誤差過大,前者的引數是CP,後者的引數是Xerror。所以要在Xerror最小的情況下,也使CP儘量小。如果認為樹模型過於複雜,我們需要對其進行修剪。

# 首先觀察模型的誤差等資料 
> printcp(fit)

Regression tree:
rpart(formula = formular, data = bodyfat, method = "anova")

Variables actually used in tree construction:
[1] hipcirc   waistcirc

Root node error: 8536/71 = 120.23

n= 71 

        CP nsplit rel error  xerror     xstd
1 0.662895      0   1.00000 1.04709 0.168405
2 0.083583      1   0.33710 0.41940 0.098511
3 0.077036      2   0.25352 0.43022 0.086202
4 0.018190      3   0.17649 0.31948 0.065217
5 0.010000      4   0.15830 0.27572 0.064809


# 呼叫CP(complexity parameter)與xerror的相關圖,一種方法是尋找最小xerror點所對應的CP值,並由此CP值決定樹的大小,另一種方法是利用1SE方法,尋找xerror+SE的最小點對應的CP值。
> plotcp(fit)

這裡寫圖片描述

# 用prune命令對樹模型進行修剪(本例的樹模型不復雜,並不需要修剪) 
pfit=prune(fit,cp=fit$cptable[which.min(fit$cptable[,"xerror"]),"CP"])

# 模型初步解釋:腰圍和臀圍較大的人,肥胖程度較高,而其中腰圍是最主要的因素。 
# 利用模型預測某個人的肥胖程度

> ndata=data.frame(waistcirc=99,hipcirc=110,elbowbreadth=6,kneebreadth=8,
age=60) 
> predict(fit,newdata=ndata) 

# 本文主要參考了Yanchang Zhao的文章:“R and Data Mining: Examples and Case Studies”