1.資訊增益
決策樹應該是比較簡單的概念了,其結構類似於二叉樹,從根節點向下依次判斷,直至葉子節點獲得結果。對於基本結構不多說了,這裡主要說一下和決策樹相關的兩個數學上的概念,即資訊增益和夏農熵。資訊增益是指的以某乙個特徵對資料集劃分前後資料集發生的變化,而夏農熵則是度量這一變化的量。
夏農熵的計算公式如下:
計算夏農熵的**:
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)
return shannonent
以上**比較簡單,在資料集中資料是以[1,1,』yes』]這樣的形式存放的,最後乙個元素即為標籤,以此為基礎,建立乙個空字典統計各個標籤出現的次數,以每個標籤出現的次數做分子來計算標籤出現的概率,計算夏農熵。
2.劃分資料集
這一步我們需要兩個函式,乙個是按照給定的特徵劃分資料集,另乙個是選擇如何選擇劃分效果最好的特徵。
按照給定的特徵劃分資料集**:
def
splitdataset
(dataset,axis,value):
retdataset =
for featvec in dataset:
if featvec[axis]==value:
reducedfeatvec = featvec[:axis]
reducedfeatvec.extend(featvec[axis+1:])
return retdataset
選擇最好的劃分方式的**如下:
def
choosebestfeaturetosplit
(dataset):
numfeatures = len(dataset[0])-1
#資料集的長度
baseentropy = calcshannonent(dataset) #初始資料集的熵
bestinfogain = 0.0
#初始化最優資訊增益
bestfeature = -1
#最優特徵的位置
for i in range (numfeatures): #遍歷特徵集
featlist = [example[i]for example in dataset] #各元素中特徵i的特徵值的集合
uniquevals= set(featlist) #建立乙個無序不重複的特徵值的集合
newentropy= 0.0
for value in uniquevals: #遍歷特徵值集
subdataset = splitdataset(dataset,i,value) #劃分後的子集
prob = len(subdataset)/float(len(dataset)) #劃分後子集的概率
newentropy+=prob*calcshannonent(subdataset) #夏農熵
infogain = baseentropy - newentropy #計算資訊增益
if(infogain>bestinfogain): #判斷是否為最優資訊增益
bestinfogain = infogain
bestfeature = i
return bestfeature #返回最優特徵
這一部分**主要是乙個兩層迴圈,外層是資料集中特徵的遍歷,內層是每乙個特徵對應特徵值集合的遍歷,用以上兩個值對資料集進行劃分,並得到乙個劃分後的子集,計算子集的夏農熵,進而計算資訊增益,並與最優資訊增益比較,最後返回最優資訊增益。
3.決策樹的構建
對於以上劃分資料集的方法,有可能存在類標籤不唯一的情況,在這時我就需要通過多數表決的方式來確定葉子結點的分類,這一部分**如下:
def
majoritycht
(classlist):
classcount={} #建立乙個空字典
for vote in classlist:
if vote not
in classcount.keys():classcount[vote]=0
classcount[vote]+=1
sortedclasscount = sorted(classcount.items(),key=operator.itemgetter(1),reverse=true) #對字典的key進行排序
return sortedclasscount[0][0]
下面是建立決策樹的**:
def
createtree
(dataset,labels):
classlist = [example[-1] for example in dataset] #特徵的集合
if classlist.count(classlist[0])==len(classlist): #count()統計某個字元出現的次數
return classlist[0] #如果特徵都相同,則返回該特徵
if len(dataset[0])==1: #如果特徵不唯一,則返回多數的特徵
return majoritycht(classlist)
bestfeat = choosebestfeaturetosplit(dataset) #選擇最優特徵
bestfeatlabel =labels[bestfeat]
mytree = } #生成樹的根節點
del(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
4.使用決策樹進行分類
**如下:
def
classify
(inputtree,featlabels,testvec):
firststr = inputtree.keys()[0] #取第乙個特徵
seconddict = inputtree[firststr] #第乙個特徵的值的集合
featindex = featlabels.index(firststr)#字串的索引
for key in seconddict.keys():#遍歷集合
if testvec[featindex] ==key:
if type(seconddict[key]).__name__=='dict':#判斷是否為字典型別
classlabel = classify(seconddict[key],featlabels,testvec)#以此特徵為根節點繼續查詢
else: classlabel = seconddict[key]#若不是字典型別則將其視為類標籤
return classlabel
決策樹的儲存:
def
storetree
(inputtree,filename):
import pickle
fw = open(filename,'wb')#python 3中需要以二進位制形式開啟
pickle.dump(inputtree,fw)
fw.close()
defgrabtree
(filename):
import pickle
fr = open(filename,'rb')#python 3 同上
return pickle.load(fr)
《機器學習實戰》學習筆記三 決策樹
第三章 決策樹 決策樹就是乙個樹狀結構的判別模式 這棵樹的每個非葉節點都包含乙個判斷條件,每個葉節點都是一種特定的分出來的類別。缺點 可能產生匹配過度 關於優缺點,個人理解 對中間值的缺失不敏感就是說可以處理有缺失值的特徵資料,匹配過度應該是對於分出來的類別中存在父子類這種情況來說的 一 決策樹總體...
機器學習實戰 決策樹(三)
構造決策樹之後,將用於實際資料的分類。執行資料分類時需要使用決策樹以及用於構造決策樹的標籤向量。如下 該函式的inputtree是已經生成的決策樹,是字典集,featlabels是要測試的資料特徵的列表,testvec是與featlabels的特徵列表中對應的特徵值,注意位置需要對應。輸入形式如 c...
機器學習實戰筆記之三(決策樹)
決策樹,資料形式易於理解。k 近鄰演算法,完成很多分類任務。缺點 可能會產生過度匹配問題。適用資料型別 數值型和標稱型。收集資料 可以使用任何方法。準備資料 樹構造演算法只適用於標稱型資料,因此數值型資料必須離散化。分析資料 可以使用任何方法,構造樹完成之後,我們應該檢查圖形是否符合預期。訓練演算法...