微信公眾號:碼農充電站pro
個人主頁:https://codeshellme.github.io
1,什麼是決策樹?
決策樹是一種機器學習演算法,我們可以使用決策樹來處理分類問題。決策樹的決策(分類)過程可以用一個倒著的樹形結構來形象的表達出來,因此得名決策樹。
比如我們根據天氣是否晴朗和是否颳風來決定是否去踢球?當天氣晴朗並且不颳風的時候,我們才去踢球。
此時,就可以將這個決策過程用一個樹形結構來表示,如下:
這就是一顆最簡單的決策樹,我們可以用它來判斷是否要去踢球。最上方是樹的根節點,最下方是樹的葉子節點。方框裡是判斷的過程,橢圓形中是決策的結果。
當然,實際的使用過程中,判斷條件並不會這麼簡單,也不會讓我們自己手動畫圖。實際應用中,我們會讓程式自動的,從一堆樣本資料集中構造出這顆決策樹,這個程式自動構建決策樹的過程就是機器學習的過程。
最終構造出來的這棵決策樹就是機器學習的結果,叫做模型。最後,我們可以向模型中輸入一些屬性條件,讓模型給出我們判斷結果。
2,如何構建決策樹?
比如我們有如下資料集:
序號 | 條件:天氣晴朗? | 條件:是否颳風? | 結果:去踢球嗎? |
---|---|---|---|
1 | 是 | 否 | 去 |
2 | 是 | 是 | 不去 |
3 | 否 | 是 | 不去 |
4 | 否 | 否 | 不去 |
可以看到這個表格中有4 行(第一行表頭不算),4 列資料。
一般在機器學習中,最後一列稱為目標(target),前邊的列都稱為特徵(features)。
我們要根據這個資料集,來構建一顆決策樹,那如何構建呢?
首先,需要確定使用哪個屬性作為第一個判斷條件,是先判斷天氣晴朗,還是先判斷是否颳風?也就是,讓天氣晴朗作為樹的根節點,還是讓是否颳風作為樹的根節點?
解決這個問題需要用到資訊熵和資訊純度的概念,我們先來看什麼是資訊熵。
3,什麼是資訊熵?
1948 年,克勞德·香濃在他的論文“通訊的數學原理”中提到了資訊熵(一般用H 表示),度量資訊熵的單位是位元。
就是說,資訊量的多少是可以量化的。一條資訊量的多少與資訊的不確定性有關,可以認為,資訊量就等於不確定性的多少(資訊的不確定度)。
資訊熵的計算公式如下:
該公式的含義是:
- 待分類的事物可以分在多個分類中,這裡的
n
就是分類的數目。 H(X)
表示熵,數學含義是,所有類別包含的資訊期望值。-㏒p(Xì)
表示符號的資訊值,p(Xì)
是選擇該分類的概率。- 公式中的
log
一般以2 為底。
總之,就是要知道,資訊量的多少是可以用數學公式計算出來的,用資訊理論中的專業術語就叫做資訊熵。資訊熵越大,資訊量也就越大。
3.1,計算資訊熵
那麼我們就來計算一下上面表格資料的資訊熵。我們只關注“結果”那一列:
結果:去踢球嗎? |
---|
去 |
不去 |
不去 |
不去 |
根據表格,我們可以知道,所有的分類共有2 種,也就是“去” 和“不去”,“去”出現了1 次,“不去”出現了3 次。
分別計算“去” 和“不去” 出現的概率:
P(去) = 1 / 4 = 0.25
P(不去) = 3 / 4 = 0.75
然後,根據熵的計算公式來計算“去”和“不去” 的資訊熵,其中log 以2 為底:
H(去) = 0.25 * log 0.25 = -0.5
H(不去) = 0.74 * log 0.75 = -0.31127812445913283
所以,整個表格含有的資訊量就是:
H(表格) = -(H(去) + H(不去)) = 0.81127812445913283
3.2,用程式碼實現資訊熵的計算
將計算資訊熵的過程用Python
程式碼實現,如下:
import math
# 本函式用於計算一組資料的資訊熵
# data_set 是一個列表,代表一組資料
# data_set 的元素data 也是一個列表
def calc_ent(data_set):
labels = {} # 用於統計每個label 的數量
for data in data_set:
label = data[-1] # 只用最後一個元素做計算
if label not in labels:
labels[label] = 0
labels[label] += 1
ent = 0 # 熵
n = len(data_set) # 資料條數
# 計算資訊熵
for label in labels:
prob = float(labels[label]) / n # label 的概率
ent -= prob * math.log(prob, 2) # 根據資訊熵公式計算
return ent
下面用該函式來計算表格的資訊熵:
# 將表格轉化為 python 列表
# "yes" 表示"去"
# "no" 表示"不去"
data_set = [['yes'], ['no'], ['no'], ['no']]
ent = calc_ent(data_set)
print(ent) # 0.811278124459
可見,用程式碼計算出來的結果是 0.811278124459,跟我們手算的結果 0.81127812445913283 是一樣的(保留的小數位數不同)。
4,什麼是資訊純度?
資訊的純度與資訊熵成反比:
- 資訊熵越大,資訊量越大,資訊越雜亂,純度越低。
- 資訊熵越小,資訊量越小,資訊越規整,純度越高。
經典的“不純度”演算法有三種,分別是:
- 資訊增益,即
ID3 演算法
,Information Divergence
,該演算法由Ross Quinlan
於1975 年提出,可用於生成二叉樹或多叉樹。- ID3 演算法會選擇資訊增益最大的屬性來作為屬性的劃分。
- 資訊增益率,即
C4.5 演算法
,是Ross Quinlan
在ID3 演算法的基礎上改進而來,可用於生成二叉樹或多叉樹。 - 基尼不純度,即
CART 演算法
,Classification and Regression Trees
,中文為分類迴歸樹。- 即可用於分類數,又可用於迴歸樹。分類樹用基尼係數做判斷,迴歸樹用偏差做判斷。
- 基尼係數本身反應了樣本的不確定度。
- 當基尼係數越小的時候,樣本之間的差異性越小,不確定程度越低。
CART 演算法
會選擇基尼係數最小的屬性作為屬性的劃分。
資訊增益是其中最簡單的一種演算法,後兩者都是由它衍生而來。本篇文章中,我們只詳細介紹資訊增益。
基尼係數是經濟學中用來衡量一個國家收入差距的常用指標。當基尼係數大於
0.4
的時候,說明財富差異較大。基尼係數在0.2-0.4
之間說明分配合理,財富差距不大。
5,什麼是資訊增益?
資訊增益就是,在根據某個屬性劃分資料集的前後,資訊量發生的變化。
資訊增益的計算公式如下:
該公式的含義:
- 簡寫就是:
G = H(父節點) - H(所有子節點)
- 也就是:父節點的資訊熵減去所有子節點的資訊熵。
- 所有子節點的資訊熵會按照子節點在父節點中的出現的概率來計算,這叫做歸一化資訊熵。
資訊增益的目的在於,將資料集劃分之後帶來的純度提升,也就是資訊熵的下降。如果資料集在根據某個屬性劃分之後,能夠獲得最大的資訊增益,那麼這個屬性就是最好的選擇。
所以,我們想要找到根節點,就需要計算每個屬性作為根節點時的資訊增益,那麼獲得資訊增益最大的那個屬性,就是根節點。
5.1,計算資訊增益
為了方便看,我將上面那個表格放在這裡:
序號 | 條件:天氣晴朗? | 條件:是否颳風? | 結果:去踢球嗎? |
---|---|---|---|
1 | 是 | 否 | 去 |
2 | 是 | 是 | 不去 |
3 | 否 | 是 | 不去 |
4 | 否 | 否 | 不去 |
我們已經知道了,資訊增益等於按照某個屬性劃分前後的資訊熵之差。
這個表格劃分之前的資訊熵我們已經知道了,就是我們在上面計算的結果:
H(表格) = 0.81127812445913283
。
接下來,我們計算按照“天氣晴朗”劃分的資訊增益。按照“天氣晴朗”劃分後有兩個表格。
表格1,“天氣晴朗”的值為“是”:
序號 | 條件:天氣晴朗? | 條件:是否颳風? | 結果:去踢球嗎? |
---|---|---|---|
1 | 是 | 否 | 去 |
2 | 是 | 是 | 不去 |
分類共有2 種,也就是“去” 和“不去”,“去”出現了1 次,“不去”出現了1 次。
所以,“去” 和“不去” 出現的概率均為0.5:
P(去) = P(不去) = 1 / 2 = 0.5
然後,“去”和“不去” 的資訊熵,其中log 以2 為底:
H(去) = H(不去) = 0.5 * log 0.5 = -0.5
所以,表格1 含有的資訊量就是:
H(表格1) = -(H(去) + H(不去)) = 1
表格2,“天氣晴朗”的值為“否”:
序號 | 條件:天氣晴朗? | 條件:是否颳風? | 結果:去踢球嗎? |
---|---|---|---|
3 | 否 | 是 | 不去 |
4 | 否 | 否 | 不去 |
所有的分類只有1 種,是“不去”。所以:
P(不去) = 1
然後,“不去” 的資訊熵,其中log 以2 為底:
H(不去) = 1 * log 1 = 0
所以,表格2 含有的資訊量就是:
H(表格2) = 0
總資料共有4 份:
- 表格1 中有2 份,概率為 2/4 = 0.5
- 表格2 中有2 份,概率為 2/4 = 0.5
所以,最終按照“天氣晴朗”劃分的資訊增益為:
G(天氣晴朗) = H(表格) - (0.5*H(表格1) + 0.5*H(表格2)) = H(表格) - 0.5 = 0.31127812445913283。
5.2,ID3 演算法的缺點
當我們計算的資訊增益多了,你會發現,ID3 演算法傾向於選擇取值比較多的屬性作為(根)節點。
但是有的時候,某些屬性並不會影響結果(或者對結果的影響不大),那此時使用ID3 選擇的屬性就不恰當了。
為了改進ID3 演算法的這種缺點,C4.5 演算法應運而生。
C4.5 演算法對ID3 演算法的改進點包括:
- 採用資訊增益率,而不是資訊增益,避免ID3 演算法有傾向於選擇取值多的屬性的缺點。
- 加入了剪枝技術,防止ID3 演算法中過擬合情況的出現。
- 對連續的屬性進行離散化的處理,使得C4.5 演算法可以處理連續屬性的情況,而ID3 只能處理離散型資料。
- 處理缺失值,C4.5 也可以針對資料集不完整的情況進行處理。
當然C4.5 演算法也並不是沒有缺點,由於 C4.5演算法需要對資料集進行多次掃描,所以演算法效率相對較低。這裡不再展開討論C4.5 演算法。
下篇會介紹如何用決策樹來解決實際問題。
歡迎關注作者公眾號,獲取更多技術乾貨。