機器學(xué)習(xí)算法之決策樹詳解

決策樹:決策樹是一個預(yù)測模型,他代表的是對象屬性與對象值之間的一種映射關(guān)系。Entropy(熵) = 系統(tǒng)的凌亂程度,使用算法ID3, C4.5和C5.0生成樹算法得出熵掏父,這一度量是基于信息學(xué)理論中熵的概念。決策樹是一種樹形結(jié)構(gòu)秆剪,其中每個內(nèi)部節(jié)點表示一個屬性上的測試赊淑,每個分支代表一個測試輸出爵政,每個葉節(jié)點代表一種類別。決策樹是一種十分常用的分類方法陶缺,是一種監(jiān)督學(xué)習(xí)钾挟。

判斷是否適合外出的決策樹

決策樹的構(gòu)造

在構(gòu)造決策樹時,我們需要解決的第一個問題就是饱岸,當前數(shù)據(jù)集上那個特征在劃分數(shù)據(jù)分類時起決定性的作用掺出。為了找到?jīng)Q定性的特征,劃分出最好的結(jié)果伶贰,我們必須評估每個特征蛛砰。完成測試之后,原始數(shù)據(jù)集就會被劃分為幾個數(shù)據(jù)子集黍衙。這些數(shù)據(jù)子集會分布在第一個決策點的所有分支上。如果某個分支下的數(shù)據(jù)屬于同一類型荠诬,則已正確劃分數(shù)據(jù)類型琅翻,如過不同,則需重復(fù)劃分數(shù)據(jù)子集柑贞。劃分數(shù)據(jù)子集的算法和原始數(shù)據(jù)相同方椎,直到所有的節(jié)點都是同一類型為止。


信息增益

上面說到我們需要找到?jīng)Q定性的特征來劃分出最好的結(jié)果钧嘶,這也是決策樹核心問題所在棠众,那怎么確定這個最優(yōu)特征呢?我們常用的方法就是用信息論中的信息增益來確定這個特征有决。

在劃分數(shù)據(jù)集之前之后信息發(fā)生的變化叫做信息增益闸拿,知道如何計算信息增益,獲得計算增益最高的特征就是最好的選擇书幕。

在1948年新荤,香農(nóng)引入了信息熵,將其定義為離散隨機事件出現(xiàn)的概率台汇,一個系統(tǒng)越有序苛骨,信息熵就越低,反之一個系統(tǒng)越混亂苟呐,它的信息熵就越高痒芝。所以信息熵可以被認為是系統(tǒng)有序化程度的一個度量。

熵定義為信息的期望值牵素,既然是要算期望严衬,就得先知道信息的定義。如果待分類的事件可能劃分在多個分類之中两波,則事件(Xi)的信息定義為:

info(xi) = -log2p(xi)

其中p(xi)是選擇該類別的概率瞳步。
為了計算熵闷哆,需要計算出信息的期望,即:(這里要吐槽一下簡書单起,不支持MathJax抱怔,所以只能找圖片替代公式)

信息期望

接下來以氣象數(shù)據(jù)為例子,來說明決策樹的構(gòu)建過程:

outlook temperature humidity windy play
sunny hot high FALSE no
sunny hot high TRUE no
overcast hot high FALSE yes
rainy mild high FALSE yes
rainy cool normal FALSE yes
rainy cool normal TRUE no
overcast cool normal TRUE yes
sunny mild high FALSE no
sunny cool normal FALSE yes
rainy mild normal FALSE yes
sunny mild normal TRUE yes
overcast mild high TRUE yes
overcast hot normal FALSE yes
rainy mild high TRUE no

在沒有使用特征劃分類別的情況下嘀倒,有9個yes和5個no屈留,當前的熵為:


計算熵

假設(shè)我們以 outlook 特征劃分數(shù)據(jù)集,對該特征每項指標分別統(tǒng)計:在不同的取值下 play 和 no play 的次數(shù):

outlook yes no
sunny 2 3
overcast 4 0
rainy 3 2

此時各分支的熵計算如下:

各分支的熵

因此如果用特征outlook來劃分數(shù)據(jù)集的話测蘑,總的熵為:
outlook劃分后的總熵

那么最終得到特征屬性outlook帶來的信息增益為:IG(outlook)=0.940?0.694=0.246灌危,然后用同樣的方法,可以分別求出temperature碳胳,humidity勇蝙,windy的信息增益。IG(temperature)=0.029挨约,IG(humidity)=0.152味混,IG(windy)=0.048〗氩眩可以得出使用outlook特征所帶來的信息增益最大翁锡,所以應(yīng)該首先選擇outlook來劃分數(shù)據(jù)集。然后繼續(xù)劃分各個分支的數(shù)據(jù)集夕土,知道每個分支下的所有實例都具有相同的分類馆衔。最終構(gòu)造出決策樹:
最終的決策樹(圖片源自網(wǎng)絡(luò))


決策樹代碼實現(xiàn)

1. 計算香農(nóng)熵

# 計算香農(nóng)熵
def calShannonEntropy(dataSet):
    numEntries = len(dataSet)   # 數(shù)據(jù)總數(shù)
    labelCounts = {}
    for featureVect in dataSet:
        currentLabel = featureVect[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        probability = float(labelCounts[key]) / numEntries
        shannonEnt -= probability * log(probability, 2)
    return shannonEnt

2. 按照給定的特征劃分數(shù)據(jù)集

# 劃分數(shù)據(jù)集
def splitDataSet(dataSet, featureIndex, featureValue):
    newDataSet = []
    for featVec in dataSet:
        if featVec[featureIndex] == featureValue:
            reducedFeatVec = featVec[:featureIndex]
            reducedFeatVec.extend(featVec[featureIndex+1:])
            newDataSet.append(reducedFeatVec)
    return newDataSet

3. 選擇最佳特征值劃分數(shù)據(jù)集

def chooseBestFeatureToSplit(dataSet):
    numFeature = len(dataSet[0]) - 1
    baseEntropy = calShannonEntropy(dataSet)
    bestFeature = -1; bestInfoGain = 0
    for i in range(numFeature):
        featList = [entry[i] for entry in dataSet]  # 取出每一種屬性
        uniqueValue = set(featList)  # 得到該屬性有哪些值(用集合的方法去掉重復(fù)值)
        newEntropy = 0.0
        for value in uniqueValue:
            subDataSet = splitDataSet(dataSet, i, value)
            probility = len(subDataSet) / float(len(dataSet))
            newEntropy += probility * calShannonEntropy(subDataSet)
        infoGain = baseEntropy - newEntropy
        if infoGain > bestInfoGain:
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

4. 投票決定不確定結(jié)果
如果數(shù)據(jù)集已經(jīng)處理了所有屬性,但是類標簽依然不是唯一的怨绣,通常我們才有多數(shù)表決的方法決定該葉子節(jié)點的分類角溃。

# 找出票數(shù)最多的標簽
def majorityVote(classList):
    classCount = {}
    for vote in classList:
        if vote not in classList.keys():
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reversed=True)
    return sortedClassCount[0][0]

5. 創(chuàng)建決策樹

def createTree(dataset, labels):
    # 取出位于最后一列的類別標簽
    classList = [label[-1] for label in dataset]
    if classList.count(classList[0]) == len(classList):  # 類別完全相同時,停止劃分
        return classList[0]  # 返回唯一特征值
    if len(dataset[0]) == 1:  # 已經(jīng)遍歷完所有特征梨熙,只剩最后一列類別標簽
        return majorityVote(classList)  # 返回票數(shù)最多的類標簽

    # 開始劃分
    # 先選取最好的劃分特征值
    bestFeature = chooseBestFeatureToSplit(dataset)
    bestFeatureLabel = labels[bestFeature]

    # 初始化樹
    myTree = {bestFeatureLabel: {}}
    subLabels = labels[:]
    del subLabels[bestFeature]
    
    # 遞歸構(gòu)建決策樹
    featList = [entry[bestFeature] for entry in dataset]
    uniqueValues = set(featList)
    for value in uniqueValues:
        myTree[bestFeatureLabel][value] = createTree(splitDataSet(dataset, bestFeature, value), subLabels)
    return myTree

6. 使用決策樹執(zhí)行分類

# 使用決策樹執(zhí)行分類
def classify(inputTree, featLabels, testVec):
    # 取出根節(jié)點,python2直接寫成inputTree.keys()[0]
    firstStr = list(inputTree.keys())[0]
    # 找到根節(jié)點下面的分支(該分類特征的分支)
    childDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr)

    # 遍歷分類特征的所有取值
    for key in childDict.keys():
        # 如果測試向量的該類值等于分類特征的第key個節(jié)點
        if testVec[featIndex] == key:
            # 判斷該節(jié)點是否為字典類型
            if type(childDict[key]).__name__ == 'dict':
                # 是字典類型开镣,繼續(xù)遍歷
                classLabel = classify(childDict[key], featLabels, testVec)
            else:
                # 不是字典,返回最終結(jié)果
                classLabel = childDict[key]
    return classLabel

7. 存儲決策樹
構(gòu)建決策樹是非常耗時的任務(wù)咽扇,即使很小的數(shù)據(jù)集邪财,也要花費幾秒的時間來構(gòu)建決策樹,這樣顯然耗費計算時間质欲。所以树埠,我們可以將構(gòu)建好的決策樹保存在磁盤中,這樣當我們需要的時候嘶伟,再從磁盤中讀取出來使用即可怎憋。為了解決這個問題,可以使用pickle序列化對象,任何對象都可以執(zhí)行序列化操作绊袋,字典對象也不例外毕匀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市癌别,隨后出現(xiàn)的幾起案子皂岔,更是在濱河造成了極大的恐慌,老刑警劉巖展姐,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躁垛,死亡現(xiàn)場離奇詭異,居然都是意外死亡圾笨,警方通過查閱死者的電腦和手機教馆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擂达,“玉大人土铺,你說我怎么就攤上這事“鬻蓿” “怎么了舒憾?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長穗熬。 經(jīng)常有香客問我,道長丁溅,這世上最難降的妖魔是什么唤蔗? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮窟赏,結(jié)果婚禮上妓柜,老公的妹妹穿的比我還像新娘。我一直安慰自己涯穷,他們只是感情好棍掐,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拷况,像睡著了一般作煌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赚瘦,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天粟誓,我揣著相機與錄音,去河邊找鬼起意。 笑死鹰服,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悲酷,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼套菜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了设易?” 一聲冷哼從身側(cè)響起逗柴,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亡嫌,沒想到半個月后嚎于,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡挟冠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年于购,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片知染。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡肋僧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出控淡,到底是詐尸還是另有隱情嫌吠,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布掺炭,位于F島的核電站辫诅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涧狮。R本人自食惡果不足惜炕矮,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望者冤。 院中可真熱鬧肤视,春花似錦、人聲如沸涉枫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愿汰。三九已至困后,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尼桶,已是汗流浹背操灿。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泵督,地道東北人趾盐。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親救鲤。 傳聞我的和親對象是個殘疾皇子久窟,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

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

  • 轉(zhuǎn)自算法雜貨鋪--決策樹決策樹和隨機森林學(xué)習(xí)筆記-歡迎補充 http://www.cnblogs.com/fion...
    明翼閱讀 10,709評論 1 6
  • 前言 決策樹是一種簡單高效并且具有強解釋性的模型,廣泛應(yīng)用于數(shù)據(jù)分析領(lǐng)域本缠。其本質(zhì)是一顆由多個判斷節(jié)點組成的樹斥扛,如:...
    兩棵橘樹閱讀 30,373評論 5 46
  • 決策樹理論在決策樹理論中,有這樣一句話丹锹,“用較少的東西稀颁,照樣可以做很好的事情。越是小的決策樹楣黍,越優(yōu)于大的決策樹”匾灶。...
    制杖灶灶閱讀 5,832評論 0 25
  • 曾經(jīng)認為非常重要的人和事也許真的會隨著時間的推移而變得不重要,曾經(jīng)要好的人也許也真的會隨著時間的推移而變淡租漂。有沒有...
    94a677a11bf9閱讀 148評論 0 0
  • 因為移動老客戶不能使用99元無限量套餐阶女,所以我爽快的換了聯(lián)通號。 大家都知道哩治,聯(lián)通的這個99元套餐很牛...
    魚小路閱讀 428評論 0 1