決策樹 (decision tree)

內容學習於 ApacheCN github node

定義:

  分類決策樹模型是一種描述對實例進行分類的樹形結構。決策樹由結點(node)和有向邊(directed edge)組成。結點有兩種類型:內部結點(internal node)和葉結點(leaf node)。內部結點表示一個特徵或屬性(features),葉結點表示一個類(labels)。git

  用決策樹對須要測試的實例進行分類:從根節點開始,對實例的某一特徵進行測試,根據測試結果,將實例分配到其子結點;這時,每個子結點對應着該特徵的一個取值。如此遞歸地對實例進行測試並分配,直至達到葉結點。最後將實例分配到葉結點的類中。github

原理: 

決策樹 須知概念

信息熵 & 信息增益算法

熵(entropy): 熵指的是體系的混亂的程度,在不一樣的學科中也有引伸出的更爲具體的定義,是各領域十分重要的參量。apache

信息論(information theory)中的熵(香農熵): 是一種信息的度量方式,表示信息的混亂程度,也就是說:信息越有序,信息熵越低。例如:火柴有序放在火柴盒裏,熵值很低;相反,熵值很高。app

信息增益(information gain): 在劃分數據集先後信息發生的變化稱爲信息增益。ide

 

決策樹算法特色

優勢:計算複雜度不高,輸出結果易於理解,數據有缺失也能跑,能夠處理不相關特徵。
缺點:容易過擬合。
適用數據類型:數值型和標稱型。函數

如何構造一個決策樹?

def createBranch():
'''
此處運用了迭代的思想。 感興趣能夠搜索 迭代 recursion, 甚至是 dynamic programing。
'''
檢測數據集中的全部數據的分類標籤是否相同:
If so return 類標籤
Else:
尋找劃分數據集的最好特徵(劃分以後信息熵最小,也就是信息增益最大的特徵)
劃分數據集
建立分支節點
for 每一個劃分的子集
調用函數 createBranch (建立分支的函數)並增長返回結果到分支節點中
return 分支節點學習

 

 1 from math import log
 2 
 3 def createDataSet():
 4     dataSet = [
 5         [1, 1, 'yes'],
 6         [1, 1, 'yes'],
 7         [1, 0, 'no'],
 8         [0, 1, 'no'],
 9         [0, 1, 'no'],
10     ]
11     labels = ['no surfacing', 'flippers']
12     return dataSet, labels
13 
14 
15 def calcShannonEnt(dataSet):
16     # 參與計算的數據量
17     numEntries = len(dataSet)
18     # 分類標籤出現的次數
19     labelCounts = {}
20     for foo in dataSet:
21         currentLabel = foo[-1]
22         # 分類寫入字典,不存在則建立,並記錄當前類別的次數
23         if currentLabel not in labelCounts.keys():
24             labelCounts[currentLabel] = 0
25         labelCounts[currentLabel] += 1
26     # 對於 label 標籤的佔比,求出 label 標籤的香農熵
27     shannonEnt = 0.0
28     for key in labelCounts:
29         # 計算每一個標籤出現的頻率
30         prob = labelCounts[key] / numEntries
31         # 計算香農熵,以 2 爲底求對數
32         shannonEnt -= prob * log(prob, 2)
33     return shannonEnt
34 
35 def splitDataSet(dataSet, index, value):
36     retDataSet = []
37     for featVec in dataSet:
38         # 除去 index 列爲 value 的數據集
39         if featVec[index] == value:
40             # 取 index 列前的數據列
41             reducedFeatVec = featVec[:index]
42             # 取 index 列後的數據列
43             reducedFeatVec.extend(featVec[index + 1:])
44             retDataSet.append(reducedFeatVec)
45     return retDataSet
46 
47 def chooseBestFeatureToSplit(dataSet):
48     # 有多少列的特徵 Feature ,最後一列是類 label
49     numFeature = len(dataSet) - 1
50     # 數據集的原始信息熵
51     baseEntropy = calcShannonEnt(dataSet)
52     # 記錄最優的信息增益和最優的特徵 Feature 編號
53     bestInfoGain, bestFeature = 0.0, -1
54     for i in range(numFeature):
55         # 獲取對應特徵 Feature 下的全部數據
56         featList = [example[i] for example in dataSet]
57         # 對特徵列表進行去重
58         uniqueVals = set(featList)
59         # 建立一個臨時信息熵
60         tempEntropy = 0.0
61         # 遍歷某一列 value 集合計算該列的信息熵
62         for value in uniqueVals:
63             # 取去除第 i 列值爲 value  的子集
64             subDataSet = splitDataSet(dataSet, i, value)
65             # 機率
66             prob = len(subDataSet) / len(dataSet)
67             # 計算信息熵
68             tempEntropy += prob * calcShannonEnt(subDataSet)
69         infoGain = baseEntropy - tempEntropy
70         if infoGain > bestInfoGain:
71             bestInfoGain = infoGain
72             bestFeature = i
73     return bestFeature
決策樹部分代碼
相關文章
相關標籤/搜索