'''
決策樹例項,決策樹優點:
缺點:可能會產生過度匹配問題
適用資料型別:數值型和標稱型
''''''
決策樹一般流程:
1、收集資料
2、準備資料
3、分析資料
4、訓練資料
5、測試資料
6、使用演算法
'''from numpy import *
import operator
from os import listdir
from math import log
#建立資料集,標籤集
def creatdataset():
dataset = [[1,1,'yes'],
[1,1,'yes'],
[1,0,'no'],
[0,1,'no'],
[0,1,'no']]
labels = ['no su***cing','flippers']
return dataset,labels
#計算給定資料集的熵
#熵:資訊的期望值(均值),熵越高資料越混亂
def calcshannonent(dataset):
numentries = len(dataset) #計算樣本集中樣本的個數,確定迴圈次數
labelcounts = {}
for eachline in dataset: #遍歷dataset的每一行
currentlabel = eachline[-1] #提取樣本集中每個樣本的標籤,每一行資料的最後乙個為標籤
if currentlabel not in labelcounts.keys(): #labelcounts.keys()返回labelcounts所有鍵值
labelcounts[currentlabel] = 0 #如果當前樣本的標籤不在labelcounts中,將其值賦為0,
labelcounts[currentlabel] += 1 #如果在就加1,統計標籤出現的次數
shannonent = 0.0
for key in labelcounts:
prob = float(labelcounts[key])/numentries #計算p(x_i)
shannonent -= prob * log(prob,2) #計算熵值
return shannonent
#按照給定屬性劃分資料集
# dataset: 需要劃分的資料集
# axis: 劃分資料集的屬性 0: 不浮出水面是否可以生存 1: 是否有腳蹼
# value: 需要返回的特徵的值 0: 否 1:是
def splitdataset(dataset,axis,value):
retdataset = #建立新的列表物件,防止列表被修改
for featvec in dataset: #dataset中每個元素也為乙個列表,遍歷dataset中每個元素
if featvec[axis] == value: #提取符合特徵的資料
reducedfeatvec = featvec[:axis]
reducedfeatvec.extend(featvec[axis+1:])
return retdataset
#選擇最好的資料劃分方式
def choosebestfeaturetosplit(dataset):
numfeatures = len(dataset[0]) - 1 #dataset第一行長度減去標籤,即為屬性個數
baseentropy = calcshannonent(dataset) #計算整個資料集的熵
bestinfogain = 0.0; bestfeature = -1
for i in range(numfeatures): #遍歷資料集中所有的特徵
featlist = [example[i] for example in dataset] #取出dataset中每個元素(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
def majoritycnt(classlist): #返回出現次數最多的分類名稱
classcount = {}
for vote in classcount:
if vote not in classcount.keys():
classcount[vote] = 0
classcount[vote] += 1
sortedclasscount = sorted(classcount.items(),key=operator.itemgetter(1),reverse=true)
return sortedclasscount[0][0]
def creattree(dataset,labels):
classlist = [example[-1] for example in dataset] #取出dataset中每個元素(dataset中元素為列表)中的最後一列元素組成乙個列表,即為類別
if classlist.count(classlist[0]) == len(classlist): #count()方法統計classlist中classlist[0]出現的次數,如果與長度相等,則表明全為一類
return classlist[0]
if len(classlist) == 1 :
return majoritycnt(classlist)
bestfeat = choosebestfeaturetosplit(dataset)
bestfeatlabel = labels[bestfeat]
mytree = }
del(labels[bestfeat])
featvalues = [example[bestfeat] for example in dataset]
uniquevalues = set(featvalues)
for value in uniquevalues:
sublabels = labels[:] #複製類標籤
mytree[bestfeatlabel][value] = creattree(splitdataset(dataset,bestfeat,value),sublabels) #遞迴建立決策樹
return mytree
機器學習實戰 筆記二 決策樹
要理解決策樹演算法需要首先明確資訊增益及資訊熵的概念 對於乙個分類集中的分類xi,其熵為 l xi log 2p x i 對於所有類別的資訊熵總和 h ni 1p xi l og2p xi 計算夏農熵的函式 from math import log defcalcshannonent dataset...
機器學習實戰 決策樹
決策樹 2 python語言在函式中傳遞的是列表的引用,在函式內部對列表物件的修改,將會影響該列表物件的整個生存週期。為了消除這個不良影響,我們需要在函式的開始宣告乙個新列表物件。在本節中,指的是在劃分資料集函式中,傳遞的引數dataset列表的引用,為了不影響dataset我們重新宣告了乙個ret...
機器學習實戰決策樹
這幾天一直在學習機器學習實戰python 實現,在程式清單的3 6 獲取及誒單數程式,書上的程式是這樣的 def getnumleafs mytree numleafs 0.0 firststr list dict.keys mytree 0 seconddict mytree firststr p...