'''
需要檔案聯絡我
決策樹優點: 計算複雜度不高,輸出結果易於理解,對中間值缺失不敏感,可以處理不相關特徵資料
缺點:可能會產生過度匹配問題
適用資料型別:數值型,標稱型
一般流程:
收集資料
準備資料:數構造演算法只適合用於標稱型資料,因此數值型資料必須離散化
分析資料
訓練演算法
測試演算法
使用演算法
劃分資料集:
檢測資料集中的每個子項是否屬於同一分類
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 ...