《機器學習實戰》決策樹(ID3演算法)的分析與實現
============================================================================================
《機器學習實戰》系列部落格是博主閱讀《機器學習實戰》這本書的筆記,包含對其中演算法的理解和演算法的Python程式碼實現
另外博主這裡有機器學習實戰這本書的所有演算法原始碼和演算法所用到的原始檔,有需要的留言
============================================================================================
KNN演算法請參考:http://blog.csdn.net/gamer_gyt/article/details/47418223
一、簡介
決策樹是一個預測模型;他代表的是物件屬性與物件值之間的一種對映關係。樹中每個節點表示某個物件,而每個分叉路徑則代表的某個可能的屬性值,而每個葉結點則對應從根節點到該葉節點所經歷的路徑所表示的物件的值。決策樹僅有單一輸出,若欲有複數輸出,可以建立獨立的決策樹以處理不同輸出。 資料探勘中決策樹是一種經常要用到的技術,可以用於分析資料,同樣也可以用來作預測
二、基本思想
1)樹以代表訓練樣本的單個結點開始。
2)如果樣本都在同一個類.則該結點成為樹葉,並用該類標記。
3)否則,演算法選擇最有分類能力的屬性作為決策樹的當前結點.
4)根據當前決策結點屬性取值的不同,將訓練樣本資料集tlI分為若干子集,每個取值形成一個分枝,有幾個取值形成幾個分枝。勻針對上一步得到的一個子集,重複進行先前 步驟,遞4'I形成每個劃分樣本上的決策樹。一旦一個屬性出現在一個結點上,就不必在該結點的任何後代考慮它。
5)遞迴劃分步驟僅當下列條件之一成立時停止:
①給定結點的所有樣本屬於同一類。
②沒有剩餘屬性可以用來進一步劃分樣本.在這種情況下.使用多數表決,將給定的結點轉換成樹葉,並以樣本中元組個數最多的類別作為類別標記,同時也可以存放該結點樣本的類別分佈,
③如果某一分枝tc,沒有滿足該分支中已有分類的樣本,則以樣本的多數類建立一個樹葉。
三、構造方法 決策樹構造的輸入是一組帶有類別標記的例子,構造的結果是一棵二叉樹或多叉樹。二叉樹的內部節點(非葉子節點)一般表示為一個邏輯判斷,如形式為a=aj的邏輯判斷,其中a是屬性,aj是該屬性的所有取值:樹的邊是邏輯判斷的分支結果。多叉樹(ID3)的內部結點是屬性,邊是該屬性的所有取值,有幾個屬性值就有幾條邊。樹的葉子節點都是類別標記。
由於資料表示不當、有噪聲或者由於決策樹生成時產生重複的子樹等原因,都會造成產生的決策樹過大。因此,簡化決策樹是一個不可缺少的環節。尋找一棵最優決策樹,主要應解決以下3個最優化問題:①生成最少數目的葉子節點;②生成的每個葉子節點的深度最小;③生成的決策樹葉子節點最少且每個葉子節點的深度最小。
四、Python程式碼實現呼叫:命令列進入該程式碼所在目錄執行:import trees dataSet,labels = trees.createDataSet() trees.myTree()
#coding=utf-8
from math import log
import operator
def createDataSet():
dataSet =[[1,1,'yes'],
[1,1,'yes'],
[1,0,'no'],
[0,1,'no'],
[0,1,'no']] #建立資料集
labels = ['no surfacing','flippers'] #分類屬性
return dataSet,labels
'''
測試結果
[[1, 'no'], [1, 'no']]
>>> dataSet
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
>>> labels
['no surfacing', 'flippers']
'''
def calcShannonEnt(dataSet): #計算給定資料集的夏農熵
numEntries = len(dataSet) #求長度
labelCounts = {}
for featVec in dataSet:
currentLabel = featVec[-1] #獲得標籤
if currentLabel not in labelCounts.keys(): #如果標籤不在新定義的字典裡建立該標籤值
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1 #該類標籤下含有資料的個數
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key])/numEntries #同類標籤出現的概率
shannonEnt -=prob*log(prob,2) #以2為底求對數
return shannonEnt
'''
測試結果
>>> trees.calcShannonEnt(dataSet)
0.9709505944546686
'''
def splitDataSet(dataSet,axis,value): #劃分資料集,三個引數為帶劃分的資料集,劃分資料集的特徵,特徵的返回值
retDataSet = []
for featVec in dataSet:
if featVec[axis] ==value:
#將相同資料集特徵的抽取出來
reducedFeatVec = featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet #返回一個列表
'''
測試結果
>>> trees.splitDataSet(dataSet,0,1)
[[1, 'yes'], [1, 'yes'], [0, 'no']]
>>> trees.splitDataSet(dataSet,0,0)
[[1, 'no'], [1, 'no']]
'''
def chooseBestFeatureToSplit(dataSet): #選擇最好的資料集劃分方式
numFeature = len(dataSet[0])-1
baseEntropy = calcShannonEnt(dataSet)
bestInfoGain = 0.0
beatFeature = -1
for i in range(numFeature):
featureList = [example[i] for example in dataSet] #獲取第i個特徵所有的可能取值
uniqueVals = set(featureList) #從列表中建立集合,得到不重複的所有可能取值
newEntropy = 0.0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet,i,value) #以i為資料集特徵,value為返回值,劃分資料集
prob = len(subDataSet)/float(len(dataSet)) #資料集特徵為i的所佔的比例
newEntropy +=prob * calcShannonEnt(subDataSet) #計算每種資料集的資訊熵
infoGain = baseEntropy- newEntropy
#計算最好的資訊增益,增益越大說明所佔決策權越大
if (infoGain > bestInfoGain):
bestInfoGain = infoGain
bestFeature = i
return bestFeature
'''
測試結果
>>> trees.chooseBestFeatureToSplit(dataSet)
0
說明:第0個特徵是最好的用於劃分資料集的特徵
'''
def majorityCnt(classList): #遞迴構建決策樹
classCount = {}
for vote in classList:
if vote not in classCount.keys():
classCount[vote]=0
classCount[vote]+=1
sortedClassCount = sorted(classCount.iteritems(),key =operator.itemgetter(1),reverse=True)#排序,True升序
return sortedClassCount[0][0] #返回出現次數最多的
'''
測試結果
'''
def createTree(dataSet,labels): #建立樹的函式程式碼
classList = [example[-1] for example in dataSet]
if classList.count(classList[0])==len(classList): #類別完全相同則停止劃分
return classList[0]
if len(dataSet[0]) ==1: #遍歷完所有特徵值時返回出現次數最多的
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet) #選擇最好的資料集劃分方式
bestFeatLabel = labels[bestFeat] #得到對應的標籤值
myTree = {bestFeatLabel:{}}
del(labels[bestFeat]) #清空labels[bestFeat],在下一次使用時清零
featValues = [example[bestFeat] for example in dataSet]
uniqueVals = set(featValues)
for value in uniqueVals:
subLabels =labels[:]
#遞迴呼叫建立決策樹函式
myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels)
return myTree
'''
測試結果
>>> reload(trees)
>>> dataSet,labels = trees.createDataSet()
>>> myTree = trees.createTree(dataSet,labels)
>>> myTree
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
'''
相關文章
- 決策樹ID3演算法python實現 -- 《機器學習實戰》演算法Python機器學習
- 機器學習之決策樹ID3(python實現)機器學習Python
- 機器學習實戰(三)決策樹ID3:樹的構建和簡單分類機器學習
- 《機器學習Python實現_09_01_決策樹_ID3與C4.5》機器學習Python
- 【Python機器學習實戰】決策樹和整合學習(二)——決策樹的實現Python機器學習
- 決策樹ID3分類演算法的C++實現演算法C++
- 04 ML 決策樹入門 ID3 演算法實現演算法
- 機器學習|決策樹-sklearn實現機器學習
- 機器學習 - 決策樹:技術全解與案例實戰機器學習
- 決策樹演算法的推理與實現演算法
- 決策樹演算法-實戰篇演算法
- 機器學習——決策樹模型:Python實現機器學習模型Python
- 決策樹中資訊增益、ID3以及C4.5的實現與總結
- 機器學習之決策樹在sklearn中的實現機器學習
- 機器學習筆記之資訊熵、資訊增益和決策樹(ID3演算法)機器學習筆記熵演算法
- 機器學習之 決策樹(Decision Tree)python實現機器學習Python
- [機器學習&資料探勘]機器學習實戰決策樹plotTree函式完全解析機器學習函式
- 決策樹在機器學習的理論學習與實踐機器學習
- 【Python機器學習實戰】決策樹和整合學習(一)Python機器學習
- Reinventing the wheel:決策樹演算法的實現演算法
- 《機器學習Python實現_09_02_決策樹_CART》機器學習Python
- 從決策樹到隨機森林:樹型演算法的原理與實現隨機森林演算法
- 機器學習之決策樹演算法機器學習演算法
- 【Python機器學習實戰】決策樹與整合學習(三)——整合學習(1)Python機器學習
- 【機器學習】實現層面 決策樹 並用graphviz視覺化樹機器學習視覺化
- 第四篇:決策樹分類演算法原理分析與程式碼實現演算法
- 機器學習:決策樹機器學習
- 機器學習-決策樹機器學習
- 機器學習之決策樹原理和sklearn實踐機器學習
- 鵝廠優文 | 決策樹及ID3演算法學習演算法
- 決策樹在sklearn中的實現
- 【Python機器學習實戰】決策樹與整合學習(四)——整合學習(2)GBDTPython機器學習
- 機器學習經典演算法之決策樹機器學習演算法
- 機器學習——決策樹模型機器學習模型
- 機器學習之決策樹機器學習
- 《機器學習:演算法原理和程式設計實踐》3:決策樹的發展機器學習演算法程式設計
- 機器學習筆記--決策樹機器學習筆記
- 決策樹C4.5演算法的技術深度剖析、實戰解讀演算法