機器學習實戰之決策樹演算法

2021-08-17 16:40:18 字數 4205 閱讀 2914

決策樹演算法目前最流行的有id3, c4.5, cart三種,其中c4.5是由id3改進而來,用資訊增益比代替id3中的資訊增益,id3演算法不能直接處理連續型資料,事先要把資料轉換成離散型才可以操作,c4.5演算法可以處理非離散型資料,而且可以處理不完整資料。cart演算法使用基尼指數用於特徵選擇,並在樹構造過程中進行剪枝。在構造決策樹的時候,那些掛著幾個元素的節點,不考慮最好,不然容易導致overfitting。

決策樹(id3)基本原理可以概括為:通過計算資訊增益劃分屬性集,選擇增益最大的屬性作為決策樹當前節點,依次往下,構建整個決策樹。

假如隨機變數x = ,每乙個變數取到的概率是p=,熵的計算通過下面公式:

熵計算完成後,通過將各個屬性劃分出來,計算各屬性特徵的資訊增益來確定決策樹的節點。資訊增益計算公式如下:

其中s為全部樣本集合,a為屬性,value(a)是屬性a的值域,v是屬性a的乙個取值,sv是s中屬性a值為v的樣本集合,|sv|是樣本數量。

以下為id3演算法的python實現,構造決策樹並測試。

#!/bin/python

#coding=utf-8

from math import log

import operator

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 clacshannonent(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.0

for key in labelcounts:

prob = float(labelcounts[key]) / numentries

shannonent -= prob * log(prob, 2)

return shannonent

def splitdataset(dataset, axis, value):

"""按照給定特徵劃分資料集

dataset是資料集,axis是資料集特徵中的某乙個(待劃分出去),value是待劃分的那個特徵的值,

retdataset是劃分之後去掉axis=value特徵之後的資料集

"""retdataset =

for featvec in dataset:

if featvec[axis] == value:

reducedfeatvec = featvec[: axis]

reducedfeatvec.extend(featvec[axis + 1 : ])

return retdataset

def choosebestfeaturetosplit(dataset):

"""選擇最好的資料集劃分方式

"""numfeatures = len(dataset[0]) - 1

#原資料集的熵

baseentropy = clacshannonent(dataset)

#print baseentropy

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 * clacshannonent(subdataset)

infogain = baseentropy - newentropy

#print infogain

#print i

if (infogain > bestinfogain):

bestinfogain = infogain

bestfeature = i

#print 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.iteritems(), key=operator.itemgetter(1), reverse=true)

return sortedclasscount

def creattree(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]

mytree = }

#得到列表包含的所有屬性值

del(labels[bestfeat])

featvalues = [example[bestfeat] for example in dataset]

uniquevals = set(featvalues)

for value in uniquevals:

sublables = labels[:]

mytree[bestfeatlabel][value] = creattree(splitdataset(dataset, bestfeat, value), sublables)

return mytree

def classify(inputtree, featlabels, testvec):

"""分類測試函式,inputtree為構造的決策樹,featlabels為測試資料的label,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 = classify(seconddict[key], featlabels, testvec)

else:

classlabel = seconddict[key]

return classlabel

機器學習實戰之決策樹

1.熵 entropy h s 用來測量乙個資料集s的不確定程度。h s x x p x log2 p x s 待計算熵的資料集,在id3演算法的每次迭代中會改變 x s中類別的集合 p x 屬於類別x的元素站集合s中總元素的比例 h s 0 集合s 被完全分到乙個類中。在id3中,對每乙個屬性熵,...

機器學習實戰之決策樹

在 機器學習實戰 決策樹這一章的時候,有些地方的 有點看不太懂,看了幾篇部落格,還是未解。最後仔細看書,發現自己不懂資料集的組織方式。希望大家看的時候也注意一下。在決策樹函式呼叫的資料要滿足如下要求 1 資料必須是由列表元素組成的列表,所有的列表元素都要具有相同的資料長度 2 資料 也就是資料集中的...

機器學習實戰之決策樹

1 演算法概述 1.1 結構分析 決策樹是一種依託決策而建立起來的樹,其中,每乙個內部節點表示乙個屬性上的測試,每乙個分支代表乙個測試的結果輸出,每乙個葉子代表一種類別。如上圖所示就是乙個決策樹,首先分析所給資料集是否為同一類別,如果是,那就不用劃分了,如果不是,就尋找劃分資料集最好的特徵進行劃分 ...