注:先提交**和各行**的解釋,後續完善。參照機器學習實戰教材
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.0for key in labelcounts:
#求資訊熵,資訊熵公式
prob =
float
(labelcounts[key]
)/numentries
shannonent -= prob * log(prob,2)
#log base 2
return shannonent #自定義函式返回資訊熵
defsplitdateset
(dataset,axis,value)
:#實現資料集劃分,引數:待劃分資料集、劃分資料集的特徵、特徵值的返回值
retdataset=
#空列表
for featvec in dataset:
#if featvec[axis]
==value:
#判斷特徵值等於特徵的返回值
reducedfeatvec=featvec[
:axis]
#截圖某特徵之前的特徵資料
reducedfeatvec.extend(featvec[axis+1:
])#拼接某特徵值之後的特徵資料,構成新資料
#資料集中滿足特徵值等於特徵的返回值的樣本
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]
#求某特徵的所有取值
uniquevals=
set(featlist)
#對某特徵值進行去重,獲得某特徵的唯一元素取值
newentropy=
0.0for value in uniquevals:
#依次遍歷某特徵的某個值
subdateset=splitdateset(dataset,i,value)
# 對當前特徵的每個特徵劃分一次資料集
prob=
len(subdateset)
/float
(len
(dataset)
)# 計算每種劃分的資訊熵公式
newentropy +=prob*calcshannonent(subdateset)
# 計算每種劃分的資訊熵公式
infogain=baseentropy-newentropy # 計算每種劃分方式的資訊增益
if(infogain>bestinfogain)
:#計算最好的資訊增益
bestinfogain=infogain
bestfeature=i
return bestfeature #返回最好特徵劃分的索引值
#test=choosebestfeaturetosplit(dataset)#求得資料集最好的特徵劃分的索引值
defmajoritycnt
(classlist)
:#該函式使用分類名稱的列表,然後建立鍵值為classlist中唯一值的資料字典,
#字典物件儲存了classlist中每個類表現出現的次數,並利用operator操作鍵值排序字典,並返回次數最多的分類名稱。
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
creattree
(dataset,labels)
:#建立決策樹,引數為資料集和標籤列表
classlist=
[example[-1
]for example in dataset]
# 獲取待分類資料集的所有分類結果
if classlist.count(classlist[0]
)==len(classlist)
:#資料集下的所有分類都具有相同的分類
return classlist[0]
#返回此分類
iflen
(dataset[0]
)==1:
#遍歷完所有劃分資料集的屬性,遍歷到最後乙個屬性的時候
return majoritycnt(classlist)
#返回次數最多的分類名稱,來替代劃分成僅包含唯一類別的分組
bestfeat=choosebestfeaturetosplit(dataset)
#選擇資料集最好的特徵劃分的索引值
bestfeatlabel=labels[bestfeat]
#選擇資料集最好的特徵劃分的特徵
mytree=
}#得到的返回值插入到字典變數mytree中
del(labels[bestfeat]
)#對屬性標籤依次刪除已經插入到字典的特徵
featvalues=
[example[bestfeat]
for example in dataset]
#得到當前用來劃分的特徵的所有屬性值
uniquevals=
set(featvalues)
#對當前特徵的所有屬性值去重,得到唯一值
for value in uniquevals:
#遍歷當前特徵的所有屬性的唯一值
sublabels=labels[:]
#複製了類標籤,並將其儲存在新列表變數中,確保不修改原始列表內容
mytree[bestfeatlabel]
[value]
=creattree(splitdateset(dataset,bestfeat,value)
,sublabels)
return mytree
dataset, labels=createdataset(
)#得到待劃分的資料集和特徵
test=creattree(dataset,labels)
#完成決策樹的巢狀字典
決策樹 構造註解樹
註解樹 將樹中的資訊新增到決策樹圖中。note 繪製圖形的x軸有效範圍是0.0到1.0,y軸有效範圍也是0.0到1.0。def getnumleafs mytree 獲取葉節點樹 numleafs 0 firststr mytree.keys 0 mytree的第乙個特徵值 python2寫法 fi...
決策樹和CART決策樹
首先簡單介紹下決策樹 說到決策樹肯定離不開資訊熵 什麼是資訊熵 不要被這名字唬住,其實很簡單 乙個不太可能的時間居然發生了,要比乙個非常可能的時間發生提供更多的資訊。訊息說 今天早上太陽公升起 資訊量是很少的,以至於沒有必要傳送。但另一條訊息說 今天早上日食 資訊量就很豐富。概率越大資訊量就越少,與...
決策樹(二)決策樹回歸
回歸 決策樹也可以用於執行回歸任務。我們首先用sk learn的decisiontreeregressor類構造一顆回歸決策樹,並在乙個帶雜訊的二次方資料集上進行訓練,指定max depth 2 import numpy as np quadratic training set noise np.r...