從這篇開始,我將介紹分類問題,主要介紹決策樹演算法、樸素貝葉斯、支援向量機、BP神經網路、懶惰學習演算法、隨機森林與自適應增強演算法、分類模型選擇和結果評價。總共7篇,歡迎關注和交流。
這篇先介紹分類問題的一些基本知識,然後主要講述決策樹演算法的原理、實現,最後利用決策樹演算法做一個泰坦尼克號船員生存預測應用。
一、分類基本介紹
物以類聚,人以群分,分類問題只古以來就出現我們的生活中。分類是資料探勘中一個重要的分支,在各方面都有著廣泛的應用,如醫學疾病判別、垃圾郵件過濾、垃圾簡訊攔截、客戶分析等等。分類問題可以分為兩類:
- 歸類:歸類是指對離散資料的分類,比如對根據一個人的筆跡判別這個是男還是女,這裡的類別只有兩個,類別是離散的集合空間{男,女}的。
- 預測:預測是指對連續資料的分類,比如預測明天8點天氣的溼度情況,天氣的溼度在隨時變化,8點時的天氣是一個具體值,它不屬於某個有限集合空間。預測也叫回歸分析,在金融領域有著廣泛應用。
雖然對離散資料和連續資料的處理方式有所不同,但其實他們之間相互轉化,比如我們可以根據比較的某個特徵值判斷,如果值大於0.5就認定為男性,小於等於0.5就認為是女性,這樣就轉化為連續處理方式;將天氣溼度值分段處理也就轉化為離散資料。
資料分類分兩個步驟:
- 構造模型,利用訓練資料集訓練分類器;
- 利用建好的分類器模型對測試資料進行分類。
好的分類器具有很好的泛化能力,即它不僅在訓練資料集上能達到很高的正確率,而且能在未見過得測試資料集也能達到較高的正確率。如果一個分類器只是在訓練資料上表現優秀,但在測試資料上表現稀爛,這個分類器就已經過擬合了,它只是把訓練資料記下來了,並沒有抓到整個資料空間的特徵。
二、決策樹分類
決策樹演算法藉助於樹的分支結構實現分類。下圖是一個決策樹的示例,樹的內部結點表示對某個屬性的判斷,該結點的分支是對應的判斷結果;葉子結點代表一個類標。
上表是一個預測一個人是否會購買購買電腦的決策樹,利用這棵樹,我們可以對新記錄進行分類,從根節點(年齡)開始,如果某個人的年齡為中年,我們就直接判斷這個人會買電腦,如果是青少年,則需要進一步判斷是否是學生;如果是老年則需要進一步判斷其信用等級,直到葉子結點可以判定記錄的類別。
決策樹演算法有一個好處,那就是它可以產生人能直接理解的規則,這是貝葉斯、神經網路等演算法沒有的特性;決策樹的準確率也比較高,而且不需要了解背景知識就可以進行分類,是一個非常有效的演算法。決策樹演算法有很多變種,包括ID3、C4.5、C5.0、CART等,但其基礎都是類似的。下面來看看決策樹演算法的基本思想:
- 演算法:GenerateDecisionTree(D,attributeList)根據訓練資料記錄D生成一棵決策樹.
- 輸入:
- 資料記錄D,包含類標的訓練資料集;
- 屬性列表attributeList,候選屬性集,用於在內部結點中作判斷的屬性.
- 屬性選擇方法AttributeSelectionMethod(),選擇最佳分類屬性的方法.
- 輸出:一棵決策樹.
- 過程:
- 構造一個節點N;
- 如果資料記錄D中的所有記錄的類標都相同(記為C類):則將節點N作為葉子節點標記為C,並返回結點N;
- 如果屬性列表為空:則將節點N作為葉子結點標記為D中類標最多的類,並返回結點N;
- 呼叫AttributeSelectionMethod(D,attributeList)選擇最佳的分裂準則splitCriterion;
- 將節點N標記為最佳分裂準則splitCriterion;
- 如果分裂屬性取值是離散的,並且允許決策樹進行多叉分裂:從屬性列表中減去分裂屬性,attributeLsit -= splitAttribute;
- 對分裂屬性的每一個取值j:記D中滿足j的記錄集合為Dj;如果Dj為空:則新建一個葉子結點F,標記為D中類標最多的類,並且把結點F掛在N下;
- 否則:遞迴呼叫GenerateDecisionTree(Dj,attributeList)得到子樹結點Nj,將Nj掛在N下;
- 返回結點N;
演算法的1、2、3步驟都很顯然,第4步的最佳屬性選擇函式會在後面專門介紹,現在只有知道它能找到一個準則,使得根據判斷結點得到的子樹的類別儘可能的純,這裡的純就是隻含有一個類標;第5步根據分裂準則設定結點N的測試表示式。在第6步中,對應構建多叉決策樹時,離散的屬性在結點N及其子樹中只用一次,用過之後就從可用屬性列表中刪掉。比如前面的圖中,利用屬性選擇函式,確定的最佳分裂屬性是年齡,年齡有三個取值,每一個取值對應一個分支,後面不會再用到年齡這個屬性。演算法的時間複雜度是O(k*|D|*log(|D|)),k為屬性個數,|D|為記錄集D的記錄數。
三、屬性選擇方法
屬性選擇方法總是選擇最好的屬性最為分裂屬性,即讓每個分支的記錄的類別儘可能純。它將所有屬性列表的屬性進行按某個標準排序,從而選出最好的屬性。屬性選擇方法很多,這裡我介紹三個常用的方法:資訊增益(Information gain)、增益比率(gain ratio)、基尼指數(Gini index)。
- 資訊增益(Information gain)
資訊增益基於香濃的資訊理論,它找出的屬性R具有這樣的特點:以屬性R分裂前後的資訊增益比其他屬性最大。這裡資訊的定義如下:
其中的m表示資料集D中類別C的個數,Pi表示D中任意一個記錄屬於Ci的概率,計算時Pi=(D中屬於Ci類的集合的記錄個數/|D|)。Info(D)表示將資料集D不同的類分開需要的資訊量。
如果瞭解資訊理論,就會知道上面的資訊Info實際上就是資訊理論中的熵Entropy,熵表示的是不確定度的度量,如果某個資料集的類別的不確定程度越高,則其熵就越大。比如我們將一個立方體A拋向空中,記落地時著地的面為f1,f1的取值為{1,2,3,4,5,6},f1的熵entropy(f1)=-(1/6*log(1/6)+…+1/6*log(1/6))=-1*log(1/6)=2.58;現在我們把立方體A換為正四面體B,記落地時著地的面為f2,f2的取值為{1,2,3,4},f2的熵entropy(1)=-(1/4*log(1/4)+1/4*log(1/4)+1/4*log(1/4)+1/4*log(1/4)) =-log(1/4)=2;如果我們再換成一個球C,記落地時著地的面為f3,顯然不管怎麼扔著地都是同一個面,即f3的取值為{1},故其熵entropy(f3)=-1*log(1)=0。可以看到面數越多,熵值也越大,而當只有一個面的球時,熵值為0,此時表示不確定程度為0,也就是著地時向下的面是確定的。
有了上面關於熵的簡單理解,我們接著講資訊增益。假設我們選擇屬性R作為分裂屬性,資料集D中,R有k個不同的取值{V1,V2,…,Vk},於是可將D根據R的值分成k組{D1,D2,…,Dk},按R進行分裂後,將資料集D不同的類分開還需要的資訊量為:
資訊增益的定義為分裂前後,兩個資訊量只差:
資訊增益Gain(R)表示屬性R給分類帶來的資訊量,我們尋找Gain最大的屬性,就能使分類儘可能的純,即最可能的把不同的類分開。不過我們發現對所以的屬性Info(D)都是一樣的,所以求最大的Gain可以轉化為求最小的InfoR(D)。這裡引入Info(D)只是為了說明背後的原理,方便理解,實現時我們不需要計算Info(D)。舉一個例子,資料集D如下:
記錄ID | 年齡 | 輸入層次 | 學生 | 信用等級 | 是否購買電腦 |
1 | 青少年 | 高 | 否 | 一般 | 否 |
2 | 青少年 | 高 | 否 | 良好 | 否 |
3 | 中年 | 高 | 否 | 一般 | 是 |
4 | 老年 | 中 | 否 | 一般 | 是 |
5 | 老年 | 低 | 是 | 一般 | 是 |
6 | 老年 | 低 | 是 | 良好 | 否 |
7 | 中年 | 低 | 是 | 良好 | 是 |
8 | 青少年 | 中 | 否 | 一般 | 否 |
9 | 青少年 | 低 | 是 | 一般 | 是 |
10 | 老年 | 中 | 是 | 一般 | 是 |
11 | 青少年 | 中 | 是 | 良好 | 是 |
12 | 中年 | 中 | 否 | 良好 | 是 |
13 | 中年 | 高 | 是 | 一般 | 是 |
14 | 老年 | 中 | 否 | 良好 | 否 |
這個資料集是根據一個人的年齡、收入、是否學生以及信用等級來確定他是否會購買電腦,即最後一列“是否購買電腦”是類標。現在我們用資訊增益選出最最佳的分類屬性,計算按年齡分裂後的資訊量:
整個式子由三項累加而成,第一項為青少年,14條記錄中有5條為青少年,其中2(佔2/5)條購買電腦,3(佔3/5)條不購買電腦。第二項為中年,第三項為老年。類似的,有:
可以得出Info年齡(D)最小,即以年齡分裂後,分得的結果中類標最純,此時已年齡作為根結點的測試屬性,根據青少年、中年、老年分為三個分支:
注意,年齡這個屬性用過後,之後的操作就不需要年齡了,即把年齡從attributeList中刪掉。往後就按照同樣的方法,構建D1,D2,D3對應的決策子樹。ID3演算法使用的就是基於資訊增益的選擇屬性方法。
- 增益比率(gain ratio)
資訊增益選擇方法有一個很大的缺陷,它總是會傾向於選擇屬性值多的屬性,如果我們在上面的資料記錄中加一個姓名屬性,假設14條記錄中的每個人姓名不同,那麼資訊增益就會選擇姓名作為最佳屬性,因為按姓名分裂後,每個組只包含一條記錄,而每個記錄只屬於一類(要麼購買電腦要麼不購買),因此純度最高,以姓名作為測試分裂的結點下面有14個分支。但是這樣的分類沒有意義,它沒有任何泛化能力。增益比率對此進行了改進,它引入一個分裂資訊:
增益比率定義為資訊增益與分裂資訊的比率:
我們找GainRatio最大的屬性作為最佳分裂屬性。如果一個屬性的取值很多,那麼SplitInfoR(D)會大,從而使GainRatio(R)變小。不過增益比率也有缺點,SplitInfo(D)可能取0,此時沒有計算意義;且當SplitInfo(D)趨向於0時,GainRatio(R)的值變得不可信,改進的措施就是在分母加一個平滑,這裡加一個所有分裂資訊的平均值:
- 基尼指數(Gini index)
基尼指數是另外一種資料的不純度的度量方法,其定義如下:
其中的m仍然表示資料集D中類別C的個數,Pi表示D中任意一個記錄屬於Ci的概率,計算時Pi=(D中屬於Ci類的集合的記錄個數/|D|)。如果所有的記錄都屬於同一個類中,則P1=1,Gini(D)=0,此時不純度最低。在CART(Classification and Regression Tree)演算法中利用基尼指數構造二叉決策樹,對每個屬性都會列舉其屬性的非空真子集,以屬性R分裂後的基尼係數為:
D1為D的一個非空真子集,D2為D1在D的補集,即D1+D2=D,對於屬性R來說,有多個真子集,即GiniR(D)有多個值,但我們選取最小的那麼值作為R的基尼指數。最後:
我們轉Gini(R)增量最大的屬性作為最佳分裂屬性。
總結
本來打算還講一下實現的,今天要回家,幫家裡收下穀子,本來買的前天的票的,颱風影響京廣線沒走成,先寫到這裡,收拾東西去。9月30回來,再總結一下實現和實踐,並持續後面的話題,歡迎持續關注。
參考文獻:
[1]:HanJiaWei. Data Mining: concept and techniques.