一、簡介
決策樹分類算法(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分支下,所有的樣本都屬於同一個分類,因此該節點為葉子節點。
最終的分類樹為: