0.決策樹
決策樹是一種樹型結構,其中每個內部節結點表示在一個屬性上的測試,每一個分支代表一個測試輸出,每個葉結點代表一種類別。
決策樹學習是以實例為基礎的歸納學習
決策樹學習采用的是自頂向下的遞歸方法,其基本思想是以信息熵為度量構造一棵熵值下降最快的樹。到葉子節點的處的熵值為零,此時每個葉結點中的實例都屬於同一類。
1.決策樹學習算法的特點
決策樹算法的最大優點是可以自學習。在學習的過程中,不需要使用者了解過多知識背景,只需要對訓練實例進行較好的標注,就能夠進行學習了。
在決策樹的算法中,建立決策樹的關鍵,即在當前狀態下選擇哪個屬性作為分類依據。根據不同的目標函數,建立決策樹主要有一下三種算法:
- ID3
- C4.5
- CART
主要的區別就是選擇的目標函數不同,ID3使用的是信息增益,C4.5使用信息增益率,CART使用的是Gini系數。
2.信息熵
在信息論與概率統計中,熵(entropy)是表示隨機變量不確定性的度量。設X是一個區有限個值的離散隨機變量,其概率分布為:
則隨機變量X的熵的定義為:
在上述式中,若pi=0,則定義0log0=0,通常,式中的對數以2為底或者以e為底(自然對數),這時熵的單位分別稱作比特(bit)或者納特(nat)。由定義可知,熵只依賴於X的分布,而與X的取值無關,所以也可以將X的熵記作H(p),即:
熵越大,隨機變量的不確定性就越大。從定義可以驗證
當隨機變量確定時,熵的值最小為0,當熵值最大時,隨機變量不確定性最大。
設有隨機變量(X,Y),其聯合概率分布為
條件熵H(Y|X)表示在已知隨機變量X的條件下隨機變量Y的不確定性,隨機變量X給定的條件下隨機變量Y的條件熵H(Y|X),定義為X給定條件下Y的條件概率分布的熵對X的數學期望:
這里,pi=P(X=xi),i=1,2,......,n
當熵和條件熵中的概率是有數據估計(極大似然估計)得到時,所對應的熵與條件熵分別稱為經驗熵和條件經驗熵。此時,如果有0概率,則令0log0=0.
信息增益表示得知特征X的信息而使得類Y的信息的不確定性減少的程度。
特征A對數據集D的信息增益g(D,A),定義為集合D的經驗熵H(D)與特征A的經驗條件熵H(D|A)之差,即:
一般地,熵H(Y)與條件熵H(Y|X)之差稱為互信息。決策樹學習中的信息增益等價於訓練數據集中類與特征的互信息。
3.模型建立
具體的決策樹算法流程,我們在這里就不仔細介紹了,詳細算法可以參閱李航老師的《統計學習方法》一書。
1 import numpy as np 2 import matplotlib.pyplot as plt 3 import matplotlib as mpl 4 from sklearn.tree import DecisionTreeClassifier 5 6 7 def iris_type(s): 8 it = {b'Iris-setosa': 0, b'Iris-versicolor': 1, b'Iris-virginica': 2} 9 return it[s] 10 11 iris_feature = u'花萼長度', u'花萼寬度', u'花瓣長度', u'花瓣寬度' 12 13 if __name__ == "__main__": 14 mpl.rcParams['font.sans-serif'] = [u'SimHei'] 15 mpl.rcParams['axes.unicode_minus'] = False 16 17 path = '../dataSet/iris.data' # 數據文件路徑 18 data = np.loadtxt(path, dtype=float, delimiter=',', converters={4: iris_type}) 19 x_prime, y = np.split(data, (4,), axis=1) 20 21 feature_pairs = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]] 22 plt.figure(figsize=(10, 9), facecolor='#FFFFFF') 23 for i, pair in enumerate(feature_pairs): 24 # 准備數據 25 x = x_prime[:, pair] 26 27 # 決策樹學習 28 clf = DecisionTreeClassifier(criterion='entropy', min_samples_leaf=3) 29 dt_clf = clf.fit(x, y) 30 31 # 畫圖 32 N, M = 500, 500 33 x1_min, x1_max = x[:, 0].min(), x[:, 0].max() 34 x2_min, x2_max = x[:, 1].min(), x[:, 1].max() 35 t1 = np.linspace(x1_min, x1_max, N) 36 t2 = np.linspace(x2_min, x2_max, M) 37 x1, x2 = np.meshgrid(t1, t2) 38 x_test = np.stack((x1.flat, x2.flat), axis=1) 39 40 41 y_hat = dt_clf.predict(x) 42 y = y.reshape(-1) 43 c = np.count_nonzero(y_hat == y) # 統計預測正確的個數 44 print('特征: ', iris_feature[pair[0]], ' + ', iris_feature[pair[1]]) 45 print('\t預測正確數目:', c) 46 print('\t准確率: %.2f%%' % (100 * float(c) / float(len(y)))) 47 48 # 顯示 49 cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF']) 50 cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b']) 51 y_hat = dt_clf.predict(x_test) # 預測值 52 y_hat = y_hat.reshape(x1.shape) 53 plt.subplot(2, 3, i+1) 54 plt.pcolormesh(x1, x2, y_hat, cmap=cm_light) 55 plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', cmap=cm_dark) 56 plt.xlabel(iris_feature[pair[0]], fontsize=14) 57 plt.ylabel(iris_feature[pair[1]], fontsize=14) 58 plt.xlim(x1_min, x1_max) 59 plt.ylim(x2_min, x2_max) 60 plt.grid() 61 plt.suptitle(u'決策樹對鳶尾花數據的兩特征組合的分類結果', fontsize=18) 62 plt.tight_layout(2) 63 plt.subplots_adjust(top=0.92) 64 plt.show()
在書面的代碼中,為了可視化的方便,我們采用特征組合的方式,將鳶尾花的四個兩兩進行組合,分別建立決策樹模型,並對其進行驗證。
DecisionTreeClassifier(criterion='entropy', min_samples_leaf=3)函數為創建一個決策樹模型,其函數的參數含義如下所示:
- criterion:gini或者entropy,前者是基尼系數,后者是信息熵。
- splitter: best or random 前者是在所有特征中找最好的切分點 后者是在部分特征中,默認的”best”適合樣本量不大的時候,而如果樣本數據量非常大,此時決策樹構建推薦”random” 。
- max_features:None(所有),log2,sqrt,N 特征小於50的時候一般使用所有的
- max_depth: int or None, optional (default=None) 設置決策隨機森林中的決策樹的最大深度,深度越大,越容易過擬合,推薦樹的深度為:5-20之間。
- min_samples_split:設置結點的最小樣本數量,當樣本數量可能小於此值時,結點將不會在划分。
- min_samples_leaf: 這個值限制了葉子節點最少的樣本數,如果某葉子節點數目小於樣本數,則會和兄弟節點一起被剪枝。
- min_weight_fraction_leaf: 這個值限制了葉子節點所有樣本權重和的最小值,如果小於這個值,則會和兄弟節點一起被剪枝默認是0,就是不考慮權重問題。
- max_leaf_nodes: 通過限制最大葉子節點數,可以防止過擬合,默認是"None”,即不限制最大的葉子節點數。
- class_weight: 指定樣本各類別的的權重,主要是為了防止訓練集某些類別的樣本過多導致訓練的決策樹過於偏向這些類別。這里可以自己指定各個樣本的權重,如果使用“balanced”,則算法會自己計算權重,樣本量少的類別所對應的樣本權重會高。
- min_impurity_split: 這個值限制了決策樹的增長,如果某節點的不純度(基尼系數,信息增益,均方差,絕對差)小於這個閾值則該節點不再生成子節點。即為葉子節點 。
plt.suptitle(u'決策樹對鳶尾花數據的兩特征組合的分類結果', fontsize=18)設置整個大畫布的標題
plt.tight_layout(2) 調整圖片的布局
plt.subplots_adjust(top=0.92) 自適應,繪圖距頂部的距離為0.92
結果如下:
不同的特征組合的決策樹模型的准確率:
4.決策樹的保存
當我們通過建立好決策樹之后,我們應該怎樣查看建立好的決策樹呢?sklearn已經幫助我們寫好了方法,代碼如下:
1 from sklearn import tree #需要導入的包 2 3 f = open('../dataSet/iris_tree.dot', 'w') 4 tree.export_graphviz(model.get_params('DTC')['DTC'], out_file=f)
當我們運行之后,程序會生成一個.dot的文件,我們能夠通過word打開這個文件,你看到的是樹節點的一些信息,我們通過graphviz工具能夠查看樹的結構: