# coding:utf-8
from math import log
import operator
##建立訓練資料集
defcreatedataset
(): dataset = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']] #資料集的最後乙個元素作為該資料的標籤,是否是魚
labels = ['no su***cing','flippers'] #不浮出水面是否可以生存、是否有腳蹼
return dataset, labels
##計算資訊熵
defcalcshannonent
(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) #log base 2
return shannonent
##分割資料集 axis即為在每一行中第axis個元素作為特徵值劃分並選出值與value相等的那一行,但要除去第axis個元素
defsplitdataset
(dataset, axis, value):
retdataset =
for featvec in dataset:
if featvec[axis] == value:
reducedfeatvec = featvec[:axis] #輸出的資料中要剔除該行第axis個元素
reducedfeatvec.extend(featvec[axis+1:])#輸出的資料中要剔除該行第axis個元素
return retdataset
###################################選擇最好的資料集劃分方式#########################
defchoosebestfeaturetosplit
(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) #使用set資料型別來去除重複項
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 #返回能最好劃分資料集的特徵, 如dataset = [[1, 1, 'yes'], [1, 1, 'yes'],[1, 0, 'no'], [0, 1, 'no'],[0, 1, 'no']] 一行中的第乙個元素或第二個元素
##以下為本文新增的**
defmajoritycnt
(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)
return sortedclasscount[0][0]
defcreatetree
(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 = }
del(labels[bestfeat])
featvalues = [example[bestfeat] for example in dataset]
uniquevals = set(featvalues)
for value in uniquevals:
sublabels = labels[:] #為了保證每次呼叫createtree時不改變原有labels的值,建立新變數代替元素列表
mytree[bestfeatlabel][value] = createtree(splitdataset(dataset, bestfeat, value),sublabels)
return mytree
dataset, labels=createdataset()
mytree=createtree(dataset,labels)
print mytree
執行的結果為
下面使用流程圖說明決策樹的構造過程
最後構造出的決策樹就如下圖所示
決策樹之 ID3
id3 是一種用來構建決策樹的演算法,它根據資訊增益來進行屬性選擇。關於決策樹,請參見 此處主要介紹 id3 演算法如何利用資訊增益選擇屬性。資訊熵,簡稱 熵 假定訓練集中目標屬性為 c c的取值為 c1 c2,cm 每個取值佔的比例為p1 p2,pm 則資訊熵的定義為 en trop y s en...
決策樹 ID3演算法
id3演算法通過計算每個屬性的資訊增益,認為資訊增益越大屬性越優,每次劃分選取資訊增益最大的屬性為劃分標準,重複這個過程,直到構成一棵決策樹。資訊熵是描述事件給我們的驚訝程度,如果所有事件的概率均等,那熵值大,驚訝程度低。如果有一事件的概率極高而其他極低,熵值便低,驚訝程度大。其計算公式如下 資訊增...
決策樹 ID3演算法
一 決策樹基本概念 在機器學習中,決策樹是乙個 模型,它代表的是物件屬性與物件值之間的一種對映關係。本質上決策樹是通 過一系列規則對資料進行分類的過程。下圖為經典決策樹例項。如圖所示,例項是由 屬性 值 對表示的 例項是用一系列固定的屬性和他們的值構成。目標函式具有離散的輸出值 上圖給每個例項賦予乙...