決策樹分類


決策樹分類 

  決策樹分類歸類於監督學習,能夠根據特征值一層一層的將數據集進行分類。它的有點在於計算復雜度不高,分類出的結果能夠很直觀的呈現,但是也會出現過度匹配的問題。使用ID3算法的決策樹分類第一步需要挑選出一個特征值,能夠將數據集最好的分類,之后遞歸構成分類樹。使用信息增益,來得到最佳的分類特制。

  信息增益

  根據某一特征划分數據集之后,信息發生的變化就叫做信息增益,計算出根據哪一個特征值划分之后數據集的信息增益值最大,那個該特制就是當前划分數據集的最好特征。可以用下面的公式計算得到信息增益值:

  

  為同一類別的概率值。例如一個數據集有10條記錄 3條記錄類別屬於A類, 7條記錄類別屬於B類 根據公式就有 信息增益值為 -(0.3*log2(0.3) + 0.7*log2(0.7))。

  

定義一個函數的計算該值

def calcuShannon(dataset):
    dataset_row = len(dataset) #得到數據集的行數
    labels = {} #聲明一個標簽字典
    for featVec in dataset:
        lable = featVec[-1] #得到每一行最后的標簽歸類
        if label not in labels.keys():
            labels[lable] = 0
        labels[lable] += 1 #得到每一個分類標簽的數量
    shannon = 0.0

    for key in labels:
        pro = float(labels[key])/dataset_row

        Shannon -= pro *log(pro, 2)
    return  shannon #返回 信息增益值

 舉一個實際運用的例子,有如下數據集 有四個特征 X1, X2, X3, X4

接下來計算一下以X2特征作為划分的之后信息增益值。

X2的取值有1,0,按1 切割矩陣后得到

計算 S1 = -((2/3) * log2 (2/3) + (1/3)*log2(1/3))

按0切割矩陣后得到

計算  S2 = -(1 * log21 )

總得信息增益值 S = (3/6)*S1 + (3/6)*S2

上面是以X2划分得到的信息增益值 ,循環計算得到 所有特征的該值,最后取出最大的一個,那么該特征就是最佳的分類特征,得到之后的子數據集矩陣,重復這一過程,當所有的特征都划分完畢,或者子集中的數據都屬於同一類,停止划分 比如

#  某一列 指定的值 划分出 數據矩陣
def splitdataset(dataset, axis, value):
    redataset = []
    for featVec in dataset:
        if featVec[axis] == value:
            reduecfeatVec = featVec[:, axis]
            reduecfeatVec.extend(featVec[axis, :])
            redataset.append(reduecfeatVec)
    return  redataset

 

#傳入數據 輸入最佳的划分特征
def getbestfeature(dataset):
    numfeature = len(dataset[0]) - 1 #得到特征數量
    baseEntropy = caluShannonent(dataset) #計算數據集的基礎信息增益值

    bestinfoGain = 0.0
    bestfeature = -1

    for i in range(numfeature):
        featlist  = []
        for data_row in dataset:
            featlist.extend(data_row[i]) #得到第i列的特征量
        uniqueVals = set(featlist) #構造一個list,去除掉重復值
        newEntropy = 0.0
        for value in uniqueVals: #根據第i列以及取值划分數據集
            subdataset = splitdataset(dataset, i, value) #得到子數據集
            prob =len(subdataset)/float(len(dataset))
            newEntropy += prob *calcuShannon(subdataset) #得到第i的信息增益值

        infoGain = baseEntropy - newEntropy

        if infoGain > bestinfoGain :
            bestinfoGain = infoGain
            bestfeature = i
    return bestfeature #返回最佳划分特征 列號

 

遞歸生成分分類樹:

 

#所有特征都划分完成,最后的標簽中若並不是所有都是屬於同一類,調用該函數返回最多哪一類
def majorityCnt(classlist):
    classcount = {}
    for vote in classlist:
        if vote in classlist:
            classcount[vote] = 0
            classcount[vote] += 1

    sortedclasscount = sorted(classcount.iteritems(),
                              key = operator.itemgetter(1),
                              reverse= True)
    return sortedclasscount[0][0]

def createTree(dataset, lables):
    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 = getbestfeature(dataset)#返回最佳分類特征索引

    bestfeatlabel = lables[bestfeat] #返回特征值

    del(lables[bestfeat])#刪除該最佳分類特征

    classifyTree = {bestfeatlabel: {}}

    bestfeatColValue = [example[bestfeat] for example in dataset]

    uniqueValue = set(bestfeatColValue)

    for value in uniqueValue:
        sublabels = lables[:]
        classifyTree = createTree(splitdataset(dataset,
                                               bestfeat, value), sublabels)#遞歸調用生成分類樹

    return classifyTree 

 

 

 

   

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM