3-4節(jié) 決策樹|遞歸構(gòu)建決策樹|機器學(xué)習(xí)實戰(zhàn)-學(xué)習(xí)筆記

文章原創(chuàng),最近更新:2018-08-16

學(xué)習(xí)參考鏈接:
1.機器學(xué)習(xí)(9)之ID3算法詳解及python實現(xiàn)
2.機器學(xué)習(xí)實戰(zhàn)-第3章《決策樹》

本章節(jié)的主要內(nèi)容是:
重點介紹項目案例1:判定魚類和非魚類遞歸構(gòu)建決策樹的函數(shù)代碼

1.決策樹項目案例介紹:

項目案例1:

判定魚類和非魚類

項目概述:
  • 根據(jù)以下 2 個特征,將動物分成兩類:魚類和非魚類篡九。
  • 特征: 1. 不浮出水面是否可以生存 2. 是否有腳蹼
開發(fā)流程:
  • 收集數(shù)據(jù):可以使用任何方法
  • 準備數(shù)據(jù):樹構(gòu)造算法只適用于標稱型數(shù)據(jù)忧换,因此數(shù)值型數(shù)據(jù)必須離散化
  • 分析數(shù)據(jù):可以使用任何方法杨拐,構(gòu)造樹完成之后欣簇,我們應(yīng)該檢查圖形是否符合預(yù)期
  • 訓(xùn)練算法:構(gòu)造樹的數(shù)據(jù)結(jié)構(gòu)
  • 測試算法:使用決策樹執(zhí)行分類
  • 使用算法:此步驟可以適用于任何監(jiān)督學(xué)習(xí)算法,而使用決策樹可以更好地理解數(shù)據(jù)的內(nèi)在含義
數(shù)據(jù)集介紹

2.遞歸構(gòu)建決策樹的函數(shù)代碼

2.1篩選出現(xiàn)次數(shù)最多的分類標簽名稱

如果數(shù)據(jù)集已經(jīng)處理了所有的屬性,但是類標簽依然不是唯一的,此時我們需要決定如何定義該葉子節(jié)點,在這種情況下,我們通常會采用多數(shù)表決的方法決定該葉子節(jié)點的分類.

在trees.py文件頂部增加一行代碼:import operator,然后添加下面的代碼到trees.py文件中.

#篩選出現(xiàn)次數(shù)最多的分類標簽名稱
def majorityCnt(classList):
    """
    majorityCnt(篩選出現(xiàn)次數(shù)最多的分類標簽名稱)

    Args:
        classList 類別標簽的列表
    Returns:
        sortedClassCount[0][0] 出現(xiàn)次數(shù)最多的分類標簽名稱
        
    假設(shè)classList=['yes', 'yes', 'no', 'no', 'no']    
    """
    classCount={}
    for vote in classList:
        if vote not in classCount.keys():classCount[vote]= 0
        classCount[vote] += 1
        """
        print(classCount[vote])的結(jié)果為:
        {'yes': 1}
        {'yes': 2}
        {'yes': 2, 'no': 1}
        {'yes': 2, 'no': 2}
        {'yes': 2, 'no': 3}
        """
    sortedClassCount =sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    """
    print(sortedClassCount)的結(jié)果為:
    [('no', 3), ('yes', 2)]
    """
    return sortedClassCount[0][0]

測試代碼及其結(jié)果如下:

import trees
classList=['yes', 'yes', 'no', 'no', 'no']

majorityCnt(classList)
Out[45]: 'no'

2.3遞歸構(gòu)建決策樹

所以決策樹是一個遞歸算法预麸,偽代碼如下:

def createBranch():
    檢測數(shù)據(jù)集中的所有數(shù)據(jù)的分類標簽是否相同:
        If so return 類標簽
        Else:
            尋找劃分數(shù)據(jù)集的最好特征(劃分之后信息熵最小侣姆,也就是信息增益最大的特征)
            劃分數(shù)據(jù)集
            創(chuàng)建分支節(jié)點
                for 每個劃分的子集
                    調(diào)用函數(shù) createBranch (創(chuàng)建分支的函數(shù))并增加返回結(jié)果到分支節(jié)點中
            return 分支節(jié)點

構(gòu)建決策樹的算法流程如下:

  1. 得到原始數(shù)據(jù)集生真,
  2. 基于最好的屬性值劃分數(shù)據(jù)集,由于特征值可能多于兩個捺宗,因此可能存在大于兩個分支的數(shù)據(jù)集劃分柱蟀。
  3. 第一次劃分之后,數(shù)據(jù)將被向下傳遞到樹分支的下一個節(jié)點蚜厉,在這個節(jié)點上长已,我們可以再次劃分數(shù)據(jù)。我們可以采用遞歸的原則處理數(shù)據(jù)集昼牛。
  4. 遞歸結(jié)束的條件是术瓮,程序遍歷完所有劃分數(shù)據(jù)集的屬性,或者每個分支下的所有實例都具有相同的分類匾嘱。

參見如下圖所示:


決策樹一般使用遞歸的方法生成斤斧。

  • 編寫遞歸函數(shù)有一個好習(xí)慣,就是先考慮結(jié)束條件霎烙。生成決策樹結(jié)束的條件有兩個:其一是劃分的數(shù)據(jù)都屬于一個類,其二是所有的特征都已經(jīng)使用了蕊连。在第二種結(jié)束情況中悬垃,劃分的數(shù)據(jù)有可能不全屬于一個類,這個時候需要根據(jù)多數(shù)表決準則確定這個子數(shù)據(jù)集的分類甘苍。

  • 在非結(jié)束的條件下尝蠕,首先選擇出信息增益最大的特征,然后根據(jù)其分類载庭。分類開始時看彼,記錄分類的特征到?jīng)Q策樹中廊佩,然后在特征標簽集中刪除該特征,表示已經(jīng)使用過該特征靖榕。根據(jù)選中的特征將數(shù)據(jù)集分為若干個子數(shù)據(jù)集标锄,然后將子數(shù)據(jù)集作為參數(shù)遞歸創(chuàng)建決策樹,最終生成一棵完整的決策樹

# 創(chuàng)建樹的函數(shù)代碼       
def createTree(dataSet, labels):
    """
    createTree(創(chuàng)建樹)

    Args:
        dataSet 數(shù)據(jù)集
        labels  標簽列表:標簽列表包含了數(shù)據(jù)集中所有特征的標簽茁计。最后代碼遍歷當前選擇
    Returns:
        myTree 標簽樹:特征包含的所有屬性值料皇,在每個數(shù)據(jù)集劃分上遞歸待用函數(shù)createTree(),
        得到的返回值將被插入到字典變量myTree中星压,因此函數(shù)終止執(zhí)行時践剂,字典中將會嵌套很多代
        表葉子節(jié)點信息的字典數(shù)據(jù)。
    """
    #取得dataSet的最后一列數(shù)據(jù)保存在列表classList中
    classList = [example[-1] for example in dataSet]
    #如果classList中的第一個值在classList中的總數(shù)等于長度,也就是說classList中所有的值都一樣
    #也就等價于當所有的類別只有一個時停止
    if classList.count(classList[0])==len(classList):
        return classList[0]
    #當數(shù)據(jù)集中沒有特征可分時也停止
    if len(dataSet[0])==1:
        #通過majorityCnt()函數(shù)返回列表中最多的分類
        return majorityCnt(classList)
    #通過chooseBestFeatTopSplit()函數(shù)選出劃分數(shù)據(jù)集最佳的特癥
    bestFeat = chooseBestFeatTopSplit(dataSet) 
    #最佳特征名 = 特征名列表中下標為bestFeat的元素
    bestFeatLabel=labels[bestFeat]
    # 構(gòu)造樹的根節(jié)點娜膘,多級字典的形式展現(xiàn)樹逊脯,類似多層json結(jié)構(gòu)
    myTree={bestFeatLabel:{}}
    # 刪除del列表labels中的最佳特征(就在labels變量上操作)
    del(labels[bestFeat])
    #取出所有訓(xùn)練樣本最佳特征的值形成一個list
    featValues = [example[bestFeat] for example in dataSet]
    # 通過set函數(shù)將featValues列表變成集合,去掉重復(fù)的值
    uniqueVals = set(featValues)
    for value in uniqueVals:
        #復(fù)制類標簽并將其存儲在新列表subLabels中
        subLabels = labels[:] 
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
    return myTree

測試代碼及其結(jié)果如下:

import trees
myDat,labels=createDataSet()
myTree =createTree(myDat,labels)

myTree
Out[55]: {'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

3.決策樹相關(guān)知識點補充

3.1決策樹算法的過程

算法的過程為:

  1. 初始化信息增益的閾值?
  2. 判斷樣本是否為同一類輸出Di,如果是則返回單節(jié)點樹T竣贪。標記類別為Di
  3. 判斷特征是否為空军洼,如果是則返回單節(jié)點樹T,標記類別為樣本中輸出類別D實例數(shù)最多的類別贾富。
  4. 計算A中的各個特征(一共n個)對輸出D的信息增益歉眷,選擇信息增益最大的特征Ag
  5. 如果Ag的信息增益小于閾值?,則返回單節(jié)點樹T颤枪,標記類別為樣本中輸出類別D實例數(shù)最多的類別汗捡。
  6. 否則,按特征Ag的不同取值A(chǔ)gi將對應(yīng)的樣本輸出D分成不同的類別Di畏纲。每個類別產(chǎn)生一個子節(jié)點扇住。對應(yīng)特征值為Agi。返回增加了節(jié)點的數(shù)T盗胀。
  7. 對于所有的子節(jié)點艘蹋,令D=Di,A=A?{Ag}遞歸調(diào)用2-6步,得到子樹Ti并返回票灰。

3.2 ID3算法的不足

ID3算法雖然提出了新思路女阀,但是還是有很多值得改進的地方。

  1. ID3沒有考慮連續(xù)特征屑迂,比如長度浸策,密度都是連續(xù)值,無法在ID3運用惹盼。這大大限制了ID3的用途庸汗。
  2. ID3采用信息增益大的特征優(yōu)先建立決策樹的節(jié)點。很快就被人發(fā)現(xiàn)手报,在相同條件下蚯舱,取值比較多的特征比取值少的特征信息增益大改化。比如一個變量有2個值,各為1/2枉昏,另一個變量為3個值陈肛,各為1/3,其實他們都是完全不確定的變量凶掰,但是取3個值的比取2個值的信息增益大燥爷。如果校正這個問題呢?
  3. ID3算法對于缺失值的情況沒有做考慮
  4. 沒有考慮過擬合的問題

ID3 算法的作者昆蘭基于上述不足懦窘,對ID3算法做了改進前翎,這就是C4.5算法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末畅涂,一起剝皮案震驚了整個濱河市港华,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌午衰,老刑警劉巖立宜,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異臊岸,居然都是意外死亡橙数,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進店門帅戒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灯帮,“玉大人,你說我怎么就攤上這事逻住≈痈纾” “怎么了?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵瞎访,是天一觀的道長腻贰。 經(jīng)常有香客問我,道長扒秸,這世上最難降的妖魔是什么播演? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮伴奥,結(jié)果婚禮上宾巍,老公的妹妹穿的比我還像新娘。我一直安慰自己渔伯,他們只是感情好,可當我...
    茶點故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布肄程。 她就那樣靜靜地躺著锣吼,像睡著了一般选浑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玄叠,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天古徒,我揣著相機與錄音,去河邊找鬼读恃。 笑死隧膘,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的寺惫。 我是一名探鬼主播疹吃,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼西雀!你這毒婦竟也來了萨驶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤艇肴,失蹤者是張志新(化名)和其女友劉穎腔呜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再悼,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡核畴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了冲九。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谤草。...
    茶點故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖娘侍,靈堂內(nèi)的尸體忽然破棺而出咖刃,到底是詐尸還是另有隱情,我是刑警寧澤憾筏,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布嚎杨,位于F島的核電站,受9級特大地震影響氧腰,放射性物質(zhì)發(fā)生泄漏枫浙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一古拴、第九天 我趴在偏房一處隱蔽的房頂上張望箩帚。 院中可真熱鬧,春花似錦黄痪、人聲如沸紧帕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽是嗜。三九已至愈案,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鹅搪,已是汗流浹背站绪。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丽柿,地道東北人恢准。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像甫题,于是被迫代替她去往敵國和親馁筐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,576評論 2 349

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