決策樹——選擇最好的劃分方法之信息熵

決策樹(Decision Tree)是一種簡單但是廣泛使用的分類器。通過訓練數據構建決策樹,可以高效的對未知的數據進行分類。決策數有兩大優點:1)決策樹模型可以讀性好,具有描述性,有助於人工分析;2)效率高,決策樹只需要一次構建,反覆使用,每一次預測的最大計算次數不超過決策樹的深度。
訓練數據如下表:
這裏寫圖片描述
根據訓練數據集的數據,構造決策樹
這裏寫圖片描述
比如新發現一種動物,通過決策樹就可以判斷它是否是魚類
但是在本例中決策樹的劃分也不止上圖的一種,還有另一種
這裏寫圖片描述
我們通過表能看出第二種分類也能正確分類
但是計算機最終只生成一種決策樹,那麼如何選擇呢?在這裏就要使用信息熵來決定使用哪種方案
下面代碼給出了選擇哪個特徵(不浮出水面是否可以生存、是否有腳蹼)能最好的劃分數據集

# coding:utf-8 
from math import log
import operator
##創建訓練數據集
def createDataSet():
    dataSet = [[1, 1, 'yes'],
               [1, 1, 'yes'],
               [1, 0, 'no'],
               [0, 1, 'no'],
               [0, 1, 'no']] #數據集的最後一個元素作爲該數據的標籤,是否是魚
    labels = ['no surfacing','flippers'] #不浮出水面是否可以生存、是否有腳蹼
    return dataSet, labels

##計算信息熵
def calcShannonEnt(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) #log base 2
    return shannonEnt
##分割數據集 axis即爲在每一行中第axis個元素作爲特徵值劃分並選出值與value相等的那一行,但要除去第axis個元素
def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]     #輸出的數據中要剔除該行第axis個元素
            reducedFeatVec.extend(featVec[axis+1:])#輸出的數據中要剔除該行第axis個元素
            retDataSet.append(reducedFeatVec)
    return retDataSet
##選擇最好的數據集劃分方式
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1      #每一行的最後一個元素作爲該行的標籤
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0; bestFeature = -1
    for i in range(numFeatures):        #遍歷每一個特徵
        featList = [example[i] for example in dataSet]#取出特徵值數組,即取出數據集每行的第i列組成一個數組
        uniqueVals = set(featList)       #使用set數據類型來去除重複項
        newEntropy = 0.0
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value) #分割數據集
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)     
        infoGain = baseEntropy - newEntropy     #計算數據集的基礎信息熵與所選特徵信息熵的差值,越大表示選擇的特徵所具有的信息熵越小,就選擇該特徵
        if (infoGain > bestInfoGain):       
            bestInfoGain = infoGain         
            bestFeature = i
    return bestFeature                      #返回能最好劃分數據集的特徵, 如dataSet = [[1, 1, 'yes'], [1, 1, 'yes'],[1, 0, 'no'], [0, 1, 'no'],[0, 1, 'no']] 一行中的第一個元素或第二個元素

dataSet, labels=createDataSet()
print chooseBestFeatureToSplit(dataSet)

計算出的結果爲 0,說明選擇不浮出水面是否可以生存該特徵
這裏寫圖片描述

發佈了27 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章