DecisonTree

# -*- coding: utf-8 -*-

"""

Created on Fri Jul 13 16:00:57 2018

"""

#coding:utf-8

from math import log


class DecisonTree:

? ? trainData = []

? ? trainLabel = []

? ? featureValus = {} #每個(gè)特征所有可能的取值

? ? def __init__(self, trainData, trainLabel, threshold):

? ? ? ? self.loadData(trainData, trainLabel)

? ? ? ? self.threshold = threshold

? ? ? ? self.tree = self.createTree(range(0,len(trainLabel)), range(0,len(trainData[0])))

? ? #加載數(shù)據(jù)

? ? def loadData(self, trainData, trainLabel):

? ? ? ? if len(trainData) != len(trainLabel):

? ? ? ? ? ? raise ValueError('input error')

? ? ? ? self.trainData = trainData

? ? ? ? self.trainLabel = trainLabel

? ? ? ? #計(jì)算 featureValus

? ? ? ? for data in trainData:

? ? ? ? ? ? for index, value in enumerate(data):

? ? ? ? ? ? ? ? if not index in self.featureValus.keys():

? ? ? ? ? ? ? ? ? ? self.featureValus[index] = [value]

? ? ? ? ? ? ? ? if not value in self.featureValus[index]:

? ? ? ? ? ? ? ? ? ? self.featureValus[index].append(value)

? ? #計(jì)算信息熵

? ? def caculateEntropy(self, dataset):

? ? ? ? labelCount = self.labelCount(dataset)

? ? ? ? size = len(dataset)

? ? ? ? result = 0

? ? ? ? for i in labelCount.values():

? ? ? ? ? ? pi = i / float(size)

? ? ? ? ? ? result -= pi * (log(pi) /log(2))

? ? ? ? return result

? ? #計(jì)算信息增益

? ? def caculateGain(self, dataset, feature):

? ? ? ? values = self.featureValus[feature] #特征feature 所有可能的取值

? ? ? ? result = 0

? ? ? ? for v in values:

? ? ? ? ? ? subDataset = self.splitDataset(dataset=dataset, feature=feature, value=v)

? ? ? ? ? ? result += len(subDataset) / float(len(dataset)) * self.caculateEntropy(subDataset)

? ? ? ? return self.caculateEntropy(dataset=dataset) - result

? ? #計(jì)算數(shù)據(jù)集中缠犀,每個(gè)標(biāo)簽出現(xiàn)的次數(shù)

? ? def labelCount(self, dataset):

? ? ? ? labelCount = {}

? ? ? ? for i in dataset:

? ? ? ? ? ? if trainLabel[i] in labelCount.keys():

? ? ? ? ? ? ? ? labelCount[trainLabel[i]] += 1

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? labelCount[trainLabel[i]] = 1

? ? ? ? return labelCount

? ? '''

? ? dataset:數(shù)據(jù)集

? ? features:特征集

? ? '''

? ? def createTree(self, dataset, features):

? ? ? ? labelCount = self.labelCount(dataset)

? ? ? ? #如果特征集為空敷待,則該樹為單節(jié)點(diǎn)樹

? ? ? ? #計(jì)算數(shù)據(jù)集中出現(xiàn)次數(shù)最多的標(biāo)簽

? ? ? ? if not features:

? ? ? ? ? ? return max(list(labelCount.items()),key = lambda x:x[1])[0]

? ? ? ? #如果數(shù)據(jù)集中,只包同一種標(biāo)簽壶硅,則該樹為單節(jié)點(diǎn)樹

? ? ? ? if len(labelCount) == 1:

? ? ? ? ? ? return labelCount.keys()[0]

? ? ? ? #計(jì)算特征集中每個(gè)特征的信息增益

? ? ? ? l = map(lambda x : [x, self.caculateGain(dataset=dataset, feature=x)], features)

? ? ? ? #選取信息增益最大的特征

? ? ? ? feature, gain = max(l, key = lambda x: x[1])

? ? ? ? #如果最大信息增益小于閾值威兜,則該樹為單節(jié)點(diǎn)樹

? ? ? ? #

? ? ? ? if self.threshold > gain:

? ? ? ? ? ? return max(list(labelCount.items()),key = lambda x:x[1])[0]

? ? ? ? tree = {}

? ? ? ? #選取特征子集

? ? ? ? subFeatures = filter(lambda x : x != feature, features)

? ? ? ? tree['feature'] = feature

? ? ? ? #構(gòu)建子樹

? ? ? ? for value in self.featureValus[feature]:

? ? ? ? ? ? subDataset = self.splitDataset(dataset=dataset, feature=feature, value=value)

? ? ? ? ? ? #保證子數(shù)據(jù)集非空

? ? ? ? ? ? if not subDataset:

? ? ? ? ? ? ? ? continue

? ? ? ? ? ? tree[value] = self.createTree(dataset=subDataset, features=subFeatures)

? ? ? ? return tree

? ? def splitDataset(self, dataset, feature, value):

? ? ? ? reslut = []

? ? ? ? for index in dataset:

? ? ? ? ? ? if self.trainData[index][feature] == value:

? ? ? ? ? ? ? ? reslut.append(index)

? ? ? ? return reslut

? ? def classify(self, data):

? ? ? ? def f(tree, data):

? ? ? ? ? ? if type(tree) != dict:

? ? ? ? ? ? ? ? return tree

? ? ? ? ? ? else:

? ? ? ? ? ? ? ? return f(tree[data[tree['feature']]], data)

? ? ? ? return f(self.tree, data)


? ? if __name__ == '__main__':

? ? trainData = [

? ? ? ? [0, 0, 0, 0],

? ? ? ? [0, 0, 0, 1],

? ? ? ? [0, 1, 0, 1],

? ? ? ? [0, 1, 1, 0],

? ? ? ? [0, 0, 0, 0],

? ? ? ? [1, 0, 0, 0],

? ? ? ? [1, 0, 0, 1],

? ? ? ? [1, 1, 1, 1],

? ? ? ? [1, 0, 1, 2],

? ? ? ? [1, 0, 1, 2],

? ? ? ? [2, 0, 1, 2],

? ? ? ? [2, 0, 1, 1],

? ? ? ? [2, 1, 0, 1],

? ? ? ? [2, 1, 0, 2],

? ? ? ? [2, 0, 0, 0],

? ? ]

? ? trainLabel = [0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0]

? ? tree = DecisonTree(trainData=trainData, trainLabel=trainLabel, threshold=0)

? ? print tree.tree

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末军俊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子提前,更是在濱河造成了極大的恐慌拓哺,老刑警劉巖肥照,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茅坛,死亡現(xiàn)場(chǎng)離奇詭異音半,居然都是意外死亡则拷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門曹鸠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)煌茬,“玉大人,你說(shuō)我怎么就攤上這事彻桃√成疲” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵邻眷,是天一觀的道長(zhǎng)眠屎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)肆饶,這世上最難降的妖魔是什么改衩? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮驯镊,結(jié)果婚禮上葫督,老公的妹妹穿的比我還像新娘。我一直安慰自己板惑,他們只是感情好橄镜,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著洒放,像睡著了一般蛉鹿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上往湿,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天妖异,我揣著相機(jī)與錄音,去河邊找鬼领追。 笑死他膳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绒窑。 我是一名探鬼主播棕孙,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼些膨!你這毒婦竟也來(lái)了蟀俊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤订雾,失蹤者是張志新(化名)和其女友劉穎肢预,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洼哎,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烫映,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年沼本,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锭沟。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抽兆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出族淮,到底是詐尸還是另有隱情辫红,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布瞧筛,位于F島的核電站厉熟,受9級(jí)特大地震影響导盅,放射性物質(zhì)發(fā)生泄漏较幌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一白翻、第九天 我趴在偏房一處隱蔽的房頂上張望乍炉。 院中可真熱鬧,春花似錦滤馍、人聲如沸岛琼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)槐瑞。三九已至,卻和暖如春阁苞,著一層夾襖步出監(jiān)牢的瞬間困檩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工那槽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悼沿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓骚灸,卻偏偏與公主長(zhǎng)得像糟趾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子甚牲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361