14.決策樹的最終構(gòu)建

前面是做了一輪決策,按照信息論的方式指蚁,對(duì)各特征做了分析菱父,確定了能夠帶來最大信息增益(注意是熵減)的特征颈娜。但僅這一步是不夠的,我們需要繼續(xù)對(duì)葉子節(jié)點(diǎn)進(jìn)行同樣的操作浙宜,直到完成如下的目標(biāo):

[if !supportLists]1)[endif]程序遍歷完所有劃分?jǐn)?shù)據(jù)集的屬性官辽;

[if !supportLists]2)[endif]每個(gè)分支下的所有實(shí)例都具有相同的分類;

如果程序已經(jīng)遍歷完所有劃分?jǐn)?shù)據(jù)集的屬性粟瞬,葉子節(jié)點(diǎn)下的實(shí)例仍然不具備相同的分類同仆,那就采用多數(shù)表決的方法(有點(diǎn)像KNN)來決定該葉子節(jié)點(diǎn)的分類。

好裙品,上代碼俗批。

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]

如上代碼就不逐行展開了,其實(shí)就是把一個(gè)數(shù)組中的標(biāo)簽項(xiàng)數(shù)一下數(shù)市怎,然后找到哪一個(gè)標(biāo)簽出現(xiàn)的次數(shù)最多岁忘,和KNN中相關(guān)的排序方式類似。

我們?cè)賮砜纯囱媲幔脴涞谋闅v:

def createTree(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 = {bestFeatLabel:{}}

????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

代碼一共16行臭觉。這段代碼比較關(guān)鍵,而且不算太容易看懂辱志,我們來逐行看一下:

def createTree(dataSet, labels):

#定義函數(shù)蝠筑,dataSet實(shí)際上是帶了標(biāo)簽值的數(shù)據(jù)集,labels其實(shí)是標(biāo)簽值的意義定義揩懒,詳見前面的數(shù)據(jù)集定義

????classList = [example[-1] for example in dataSet]

#classList實(shí)際上就是標(biāo)簽值的數(shù)組什乙,標(biāo)簽值位于數(shù)據(jù)集的最后一列

????if classList.count(classList[0]) == len(classList):

#這里做了一個(gè)判斷,count方法的作用就是數(shù)出數(shù)組中某個(gè)元素值的個(gè)數(shù)已球,在這里就是對(duì)classList[0]做了計(jì)數(shù)臣镣,當(dāng)它的數(shù)量等同于數(shù)組的長(zhǎng)度時(shí)辅愿,說明這個(gè)數(shù)組里沒有別的標(biāo)簽了,即已經(jīng)分到了標(biāo)簽唯一的狀態(tài)忆某;按決策樹葉子節(jié)點(diǎn)是否達(dá)到不可分的條件2点待,已經(jīng)完成

????????return classList[0]

#返回classList[0],即當(dāng)前葉子節(jié)點(diǎn)唯一的標(biāo)簽值

????if len(dataSet[0]) == 1:

????????return majorityCnt(classList)

#如果dataSet的長(zhǎng)度為1弃舒,那就等于是葉子節(jié)點(diǎn)中特征值只有1個(gè)癞埠,這個(gè)時(shí)候就滿足了決策樹葉子節(jié)點(diǎn)是否達(dá)到不可分的條件1,程序遍歷完所有劃分?jǐn)?shù)據(jù)集的屬性聋呢,這個(gè)時(shí)候我們要對(duì)葉子節(jié)點(diǎn)中的標(biāo)簽進(jìn)行統(tǒng)計(jì)苗踪,通過多數(shù)表決的方法確定并返回這一分支的標(biāo)簽值。

????bestFeat = chooseBestFeatureToSplit(dataSet)

????bestFeatLabel = labels[bestFeat]

#如果不是上述的兩種情況削锰,即節(jié)點(diǎn)還可分通铲,那么就用chooseBestFeatureToSplit方法找到最佳的特征項(xiàng),并對(duì)節(jié)點(diǎn)進(jìn)行分解器贩。

????myTree = {bestFeatLabel:{}}

#建立一個(gè)字典myTree

????del(labels[bestFeat])

#刪除已選出的特征

????featValues = [example[bestFeat] for example in dataSet]

#根據(jù)最佳特征的下標(biāo)颅夺,從dataSet里取出相關(guān)特征的值的數(shù)組

????uniqueVals = set(featValues)

#去重,得到該數(shù)組中可能的值

????for value in uniqueVals:

#遍歷所有可能的值

????????subLabels = labels[:]

#復(fù)制出一個(gè)label數(shù)組蛹稍,這個(gè)數(shù)組已經(jīng)刪掉了之前的最佳特征項(xiàng)

????????myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)

#根據(jù)最優(yōu)的特征進(jìn)行分叉碗啄,每一個(gè)分叉再去進(jìn)行生成子樹的遞歸操作(這是關(guān)鍵,通過遞歸遍歷生成所有的子節(jié)點(diǎn)稳摄,并根據(jù)那兩條要求確定是否終止并直接return)

????return myTree

#返回樹(注意這里的返回稚字,可能是一棵子樹,因?yàn)槭峭ㄟ^遞歸生成了整棵樹厦酬,只有最開始的調(diào)用才是根節(jié)點(diǎn))


好了胆描,至此,這段代碼結(jié)束仗阅。這段代碼不算太容易看懂昌讲,原理好懂,但是算法理論要想跟代碼聯(lián)系在一起减噪,還是挺復(fù)雜的短绸。最終生成的樹結(jié)構(gòu)如下:


它是個(gè)什么呢?其實(shí)就是一開始的最優(yōu)特征項(xiàng)是“no surfacing”筹裕,然后進(jìn)行分叉醋闭,左邊由于標(biāo)簽一致所以結(jié)束,右邊進(jìn)行再分叉朝卒,然后因?yàn)樘卣饔猛曛ぢ撸Y(jié)束。

一棵有意思的樹抗斤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末囚企,一起剝皮案震驚了整個(gè)濱河市丈咐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌龙宏,老刑警劉巖棵逊,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異银酗,居然都是意外死亡歹河,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門花吟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人厨姚,你說我怎么就攤上這事衅澈。” “怎么了谬墙?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵今布,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我拭抬,道長(zhǎng)部默,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任造虎,我火速辦了婚禮傅蹂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘算凿。我一直安慰自己份蝴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布氓轰。 她就那樣靜靜地躺著婚夫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪署鸡。 梳的紋絲不亂的頭發(fā)上案糙,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音靴庆,去河邊找鬼时捌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛炉抒,可吹牛的內(nèi)容都是我干的匣椰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼端礼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼禽笑!你這毒婦竟也來了入录?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤佳镜,失蹤者是張志新(化名)和其女友劉穎僚稿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蟀伸,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚀同,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啊掏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蠢络。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖迟蜜,靈堂內(nèi)的尸體忽然破棺而出刹孔,到底是詐尸還是另有隱情,我是刑警寧澤娜睛,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布髓霞,位于F島的核電站,受9級(jí)特大地震影響畦戒,放射性物質(zhì)發(fā)生泄漏方库。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一障斋、第九天 我趴在偏房一處隱蔽的房頂上張望纵潦。 院中可真熱鬧,春花似錦垃环、人聲如沸酪穿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽被济。三九已至,卻和暖如春涧团,著一層夾襖步出監(jiān)牢的瞬間只磷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國打工泌绣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钮追,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓阿迈,卻偏偏與公主長(zhǎng)得像元媚,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容