決策樹 機器學習實戰

2021-09-12 07:25:08 字數 4216 閱讀 1517

'''

需要檔案聯絡我

決策樹優點: 計算複雜度不高,輸出結果易於理解,對中間值缺失不敏感,可以處理不相關特徵資料

缺點:可能會產生過度匹配問題

適用資料型別:數值型,標稱型

一般流程:

收集資料

準備資料:數構造演算法只適合用於標稱型資料,因此數值型資料必須離散化

分析資料

訓練演算法

測試演算法

使用演算法

劃分資料集:

檢測資料集中的每個子項是否屬於同一分類

if so return 類標籤

else

尋找劃分資料集的最好特徵

劃分資料集

建立分支節點

for 每個劃分的子集

呼叫函式createbranch並增加返回結果到分支點中

return 分支節點

資訊增益——————

原則:將無序資料變為有序資料

集合資訊的度量方式成為香濃熵或者簡稱熵(shannonent)

熵定義為資訊的期望

l(xi) = -log2p(xi) p(xi)表示選擇該分類的概率

計算所有類別所有可能值包含的資訊期望

h = -σp(xi)log2p(xi) 1->n

熵越高混合的資料越高

得到熵之後可以按照獲取最大資訊增益的方法劃分資料集

另乙個方法基尼不純度

'''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 su***cing', 'fippers']

return dataset, labels

def calcshannonent(dataset):

#計算給定資料的夏農熵

numentries = len(dataset) #多少組資料

labelcounts = {} #儲存標籤

for featvec in dataset:

currentlabel = featvec[-1] #獲得標籤

if currentlabel not in labelcounts.keys(): #如果當前標籤沒有出現過

labelcounts[currentlabel] = 0 #建立乙個新的標籤鍵值 並且設定為0

labelcounts[currentlabel] += 1 #當前標籤+1

shannonent = 0.0 #計算夏農熵

for key in labelcounts: # 對於每個標籤

prob = float(labelcounts[key])/numentries #計算當前標籤的概率

shannonent -= prob*log(prob, 2) #計算log

return shannonent #返回夏農熵

'''mydat, labels = createdataset()

shannon = calcshannonent(mydat)

print(shannon)

mydat[0][-1] = 'maybe'

shannon = calcshannonent(mydat)

print(shannon)

'''def splitdataset(dataset, axis, value):

# 劃分資料集

# 帶劃分的資料集,劃分資料集的特徵, 需要返回的特徵值

retdataset = #存值

for featvec in dataset: # 對於每乙個資料

if featvec[axis] == value: #如果是需要返回的資料

reducedfeatvec = featvec[:axis] # 複製

reducedfeatvec.extend(featvec[axis+1:]) #複製 extend 在list 後 一次性追加多個值

return retdataset

def choosebestfeaturetosplit(dataset):#選擇最好的資料集劃分方式

numfeatures = len(dataset[0]) - 1 #計算資料形狀 最後一列』yes『 』no『 不計算

baseentropy = calcshannonent(dataset) #計算夏農熵

bestinfogain = 0.0 # 最好的資訊增益

bestfeature = -1 # 最好的特徵值

for i in range(numfeatures): #對於每乙個特徵值

featlist = [example[i] for example in dataset] #每一列的值

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 classlist:

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 createtree(dataset, labels):

classlist = [example[-1] for example in dataset]

# print('go')

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[:]

mytree[bestfeatlabel][value] = createtree(splitdataset(dataset, bestfeat, value), sublabels)

return mytree

''''

mydat, labels = createdataset()

mytree = createtree(mydat, labels)

print(mytree)

'''

機器學習實戰 決策樹

決策樹 2 python語言在函式中傳遞的是列表的引用,在函式內部對列表物件的修改,將會影響該列表物件的整個生存週期。為了消除這個不良影響,我們需要在函式的開始宣告乙個新列表物件。在本節中,指的是在劃分資料集函式中,傳遞的引數dataset列表的引用,為了不影響dataset我們重新宣告了乙個ret...

機器學習實戰決策樹

這幾天一直在學習機器學習實戰python 實現,在程式清單的3 6 獲取及誒單數程式,書上的程式是這樣的 def getnumleafs mytree numleafs 0.0 firststr list dict.keys mytree 0 seconddict mytree firststr p...

機器學習實戰 決策樹

class sklearn.tree.decisiontreeclassifier criterion gini splitter best max depth none,min samples split 2,min samples leaf 1,min weight fraction leaf ...