一、簡介
決策樹分類算法(decision tree)通過樹狀結構對具有某特征屬性的樣本進行分類。其典型算法包括ID3算法、C4.5算法、C5.0算法、CART算法等。每一個決策樹包括根節點(root node),內部節點(internal node)以及葉子節點(leaf node)。
根節點:表示第一個特征屬性,只有出邊沒有入邊,通常用矩形框表示。
內部節點:表示特征屬性,有一條入邊至少兩條出邊,通常用圓圈表示。
葉子節點:表示類別,只有一條入邊沒有出邊,通常用三角表示。

決策樹算法主要用於分類,也可用於回歸,當決策樹的輸出變量是分類變量時,是分類樹;當決策樹輸出變量是連續變量時,是回歸樹。雖然回歸樹的因變量是連續的,但葉節點數是有窮的,因此輸出值也是這個葉節點上觀測值的平均。
二、基本思想
決策樹算法基本思想可以歸納如下:
第一步,對特征空間按照特征屬性進行划分;
第二步,對分類后的子集遞歸第一步。
分類過程看起來很簡單,但是要想得到【完全純凈】的子集,也就是每一個子集中的樣本都屬於同一個分類,還需要一個評價指標對分類效果好壞進行評估——熵。
熵,是系統一種無組織、無序的狀態,廣泛應用於信息論中。熵值越大,表明數據的純度越低。當熵等於0,表明樣本數據都是同一個類別。其計算公式如下:

其中,P(Xi)表示概率,b此處取值為2。熵的單位為比特bite。
信息增益(information gain):代表的是一次划分對數據純度的提升效果,也就是划分以后,熵減少越多,說明增益越大,那么這次划分也就越有價值,增益的計算公式如下:

其中D表示樣本集,假定屬性a有v個可能的取值(離散或連續)。進行最有划分屬性時,比如先找到了屬性a,對a進行評價,接下來對其他屬性重復a的過程,分別得到一個評分,選擇評分最高的那個,即信息增益最大的作為最有划分屬性。簡言之,信息增益就是分割屬性前的熵值與分割后的熵值進行差異比較。
需要注意的是,計算子集的熵之和需要乘上各個子集的權重,權重的計算方法是子集的規模占分割前父集的比重。如,分割前的熵為e,分割子集為a和b,大小分別為m和n,熵分別為e1和e2,則信息增益為e-e1*m/(m+n)-e2*n/(m+n)。
三、ID3算法實現
分類的本質是對特征空間的划分。根據決策樹的基本思想,其算法實現主要有以下三步:
1.選擇特征屬性,樣本分割。
2.計算信息增益,選取最大增益作為決策樹的子節點。
3.遞歸執行上兩步,直至分類完成。
下面將介紹ID3算法在R語言中實現過程。
一組14天天氣數據(指標包括outlook,temperature,humidity,windy),並已知這些天氣是否打球(play)。如果給出新一天的氣象指標數據:sunny,cool,high,TRUE,判斷一下會不會去打球。
| Outlook |
temperature |
humidity |
windy |
play |
| Sunny |
hot |
high |
FALSE |
no |
| Sunny |
hot |
high |
TRUE |
no |
| Overcast |
hot |
high |
FALSE |
yes |
| Rainy |
mild |
high |
FALSE |
yes |
| Rainy |
cool |
normal |
FALSE |
yes |
| Rainy |
cool |
normal |
TRUE |
no |
| Overcast |
cool |
normal |
TRUE |
yes |
| Sunny |
mild |
high |
FALSE |
no |
| Sunny |
cool |
normal |
FALSE |
yes |
| Rainy |
mild |
normal |
FALSE |
yes |
| Sunny |
mild |
normal |
TRUE |
yes |
| Overcast |
mild |
high |
TRUE |
yes |
| Overcast |
hot |
normal |
FALSE |
yes |
| Rainy |
mild |
high |
TRUE |
no |
在沒有給定任何天氣信息時,根據歷史數據,我們只知道新的一天打球的概率是9/14,不打的概率是5/14。此時的熵為:
![]()
屬性有4個:outlook,temperature,humidity,windy。我們首先要決定哪個屬性作為樹的根節點。
統計在不同天氣狀況下打球和不打球的次數:
| outlook |
temperature |
humidity |
windy |
play |
|||||||||
| yes |
no |
yes |
no |
yes |
no |
yes |
no |
yes |
no |
||||
| sunny |
2 |
3 |
hot |
2 |
2 |
high |
3 |
4 |
FALSE |
6 |
2 |
9 |
5 |
| overcast |
4 |
0 |
mild |
4 |
2 |
normal |
6 |
1 |
TRUR |
3 |
3 |
||
| rainy |
3 |
2 |
cool |
3 |
1 |
||||||||
代碼:
##決策樹模型之ID3算法
#從粘貼板讀取表格數據
weather <- read.table("clipboard",T)
#查看數據結構
str(weather)
#將windy指標轉換成因子型
weather$windy <- as.factor(weather$windy)
#未分割前信息熵
q <- matrix(table(weather$play),nrow = 1,dimnames = list('play',unique(weather$play)))/
sum(matrix(table(weather$play),nrow = 1))
e <- -sum(q*log2(q))
#計算各特征屬性的信息熵
myfun <- function(x,y){
t <- table(x,y)
m <- matrix(t,nrow = length(levels(x)),2,dimnames = list(levels(x),levels(y)))
#權重計算
n <- apply(m,1,sum)/sum(m)
#分割后各子集的熵
freq <- -rowSums((m/rowSums(m))*log2(m/rowSums(m)))
#分割后的最終熵
entropy <- sum(n*freq,na.rm = T)
return(entropy)
}
#計算信息增益information gain
y <- weather[,5]
gain <- vector()
for (i in 1:(length(weather)-1)) {
x <- weather[,i]
gain[i] <- e-myfun(x,y)
}
names(gain) <- colnames(weather[,1:4])
gain
運行結果:

根據各特征屬性的信息增益比較得到,outlook信息增益最大,即熵變化越大,所以決策樹的根節點應選擇outlook。

接下來選擇各子節點N1,N2,N3的特征屬性。
用屬性outlook划分樣本后,三個屬性值sunny,overcast,rainy把樣本划分為三部分,在每一部分下分別計算gain(temperature)、gain(humidity)、gain(windy)
代碼:
#選擇子節點特征屬性
level <- levels(weather$outlook)
son_gain <- data.frame()
for(j in 1:length(level)){
son_q <- matrix(table(weather[weather$outlook==level[j],]$play),nrow = 1,
dimnames = list('play',unique(weather$play)))/
sum(matrix(table(weather[weather$outlook==level[j],]$play),nrow = 1))
son_e[j]<- -sum(son_q*log2(son_q))
}
for (j in 1:length(level)) {
for (i in 1:length(level)) {
sl <- weather[weather$outlook==level[j],]
son_x <- sl[,i+1]
son_y <- sl[,5]
son_gain[j,i] <- son_e[j]-myfun(x=son_x,y=son_y)
}
}
colnames(son_gain) <- colnames(weather[,-c(1,5)])
rownames(son_gain) <- level
son_gain
信息增益結果:

根據上述結果,在Sunny分支上,humidity的信息增益最大,即熵減少得越快,因此應當將humidity作為子節點N1處的特征屬性。


此時,humidity=normal以及humidity=high最終得到的分類結果均為同一中類別,無需在humidity節點下進行再分類,該節點為葉子節點。
同樣在rainy分支下的子節點N3應選擇windy。且在該節點下無需再進行分類。


在overcast分支下,所有的樣本都屬於同一個分類,因此該節點為葉子節點。

最終的分類樹為:

