以下是需要的一些子函式
# 計算給定資料集的夏農熵
defcalcshannonent
(dataset):
numentries = len(dataset) #得到行數
labexcounts = {}
for featvec in dataset:
currentlabel = featvec[-1] #獲取每行最後一列的值
#根據最後一列的值進行分類,並計算每一類的個數
if currentlabel not
in labexcounts.keys():
labexcounts[currentlabel] = 0
labexcounts[currentlabel] += 1
shannonent = 0.0
#計算夏農熵
for key in labexcounts:
prob = float (labexcounts [key] )/numentries
shannonent -= prob * log(prob,2)
return shannonent
# 選擇最好的資料集劃分方式
defchoosebestfeaturetosplit
(dataset):
numfeatures = len(dataset[0]) - 1
baseentropy = calcshannonent(dataset) #獲取資料集的夏農熵
bestinfogain = 0
bestfeature = -1
#從1 - (len-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
# 按照給定特徵劃分資料集
defsplitdataset
(dataset, axis, value):
# axis 表示第幾列,value表示特徵值。eg:axis =3 ,value = "kk" 表示,第三列中值為"kk"的,把這些行取出來(去掉第3列)
retdataset =
for featvec in dataset:
if featvec[axis] == value:
reducedfeatvec = featvec[:axis]
reducedfeatvec.extend(featvec[axis + 1:])
return retdataset
# 獲取給定第單列集中最多的分類
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] #最後的特徵列對應的標籤(注意,這個不是結果值,而是每一列的標籤,含義,不包含在dataset中,比dataset少一列,因為結果那一列不需要定義標籤)
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
以下為最終演算法**,同樣的。也是遞迴(樹相關經常會使用遞迴)
# 使用決策樹的分類函式
deftreeclassify
(inputtree,featlabels,testvec):
firststr = inputtree.keys()[0]
seconddict = inputtree[firststr]
featindex = featlabels.index(firststr)
for key in seconddict.keys():
if testvec[featindex] == key:
if type(seconddict[key]).__name__== 'dict':
classlabel = treeclassify(seconddict[key], featlabels, testvec)
else: classlabel = seconddict[key]
return classlabel
構造決策樹是很耗時的任務,即使處理很小的資料集。如果資料集很大,將會耗費很多計算時間。然而用建立好的決策樹解決分類問題,則何以 很快完成。因此,為了節省計算時間,最好能夠在每次執行分類時呼叫巳經構造好的決策樹。為 了解決這個問題,需要使用python模組pickle序列化物件。序列化物件可以在磁 盤上儲存物件,並在需要的時候讀取出來。任何物件都可以執行序列化操作,字典物件也不例外。
#儲存決策樹
defstoretree
(inputtree,filename):
import pickle
fw = open(filename,'w')
pickle.dump(inputtree,fw)
fw.close()
defgrabtree
(filename):
import pickle
fr = open(filename)
return pickle.load(fr)
機器學習讀書筆記 決策樹
決策樹是一類常見的機器學習方法。舉個簡單的例子,我們分辨乙個藝術品是否具有藝術價值,可以從色彩,線條兩方面去評價 不會美術,只是打個比方 例如下面這幅畫,我們可以先判斷色彩不鮮豔,再判斷線條不美觀,從而得出這沒有藝術價值。這判斷的過程就是一棵決策樹。如圖 這是決策樹學習基本演算法 可以看出,關鍵在第...
機器學習實戰 決策樹
決策樹 2 python語言在函式中傳遞的是列表的引用,在函式內部對列表物件的修改,將會影響該列表物件的整個生存週期。為了消除這個不良影響,我們需要在函式的開始宣告乙個新列表物件。在本節中,指的是在劃分資料集函式中,傳遞的引數dataset列表的引用,為了不影響dataset我們重新宣告了乙個ret...
機器學習實戰決策樹
這幾天一直在學習機器學習實戰python 實現,在程式清單的3 6 獲取及誒單數程式,書上的程式是這樣的 def getnumleafs mytree numleafs 0.0 firststr list dict.keys mytree 0 seconddict mytree firststr p...