內容學習於 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