機器學習算法--決策樹與隨機森林

決策樹的算法比較簡單
主要分爲以下部分:
一、決策樹基本概率以及計算(ID3)
1、決策樹定義
決策樹(Decision Tree),又稱爲判定樹, 是一種以樹結構(包括二叉樹和多叉樹)形式表達的預測分析模型。比如我們會問‘今天出去玩嗎’,那麼室外的溫度,天氣都會影響我們做決策的過程,如果‘溫度適中’,我們就再看‘天氣如何’。
決策樹學習的目地:產生一顆泛化能力強,處理未見示例強的決策樹
2、決策樹優缺點
決策樹學習的優點:速度快,準確率高,對中間缺失值不敏感
決策樹學習的缺點:對於各類別樣本數量不一致的數據, 信息增益偏向於那些更多數值的特徵,容易過擬合,忽略屬性之間的相關性

在這裏插入圖片描述
3、需要掌握熵和信息增益兩個概念和計算公式
熵:對樣本集合純度的一種度量,k指的是樣本類別個數


在這裏插入圖片描述

以表4.1爲例:樣本類別個數爲2,即好瓜和壞瓜,好瓜8個概率爲8/17,壞瓜9個概率爲9/17。
那麼可以計算根節點的熵爲H=Ent(D):


在這裏插入圖片描述

信息增益:
1、假定離散屬性a有V個取值{a1,…aV}, 比如表4.1中,第一個屬性色澤有3個取值,分別是青綠、烏黑、淺白,v=3。
2、若使用a色澤對樣本集D進行劃分,會產生V(3)個分支,其中第v個包含了D中在a屬性上取值爲av的所有樣本,記爲Dv。比如D1(色澤=青綠),D2(色澤=烏黑),D3(色澤=淺白)
3、再根據不同分支結點包含的樣本數不同來給與權重:|Dv|/|D|,比如屬性(色澤)=6/17
信息增益公式:


在這裏插入圖片描述

以色澤爲例,計算3個分支的信息熵:


在這裏插入圖片描述

計算(屬性=色澤)的信息增益:


在這裏插入圖片描述

類似地:我們計算其他屬性的信息增益:

Gain(D,根蒂)=0.143
Gain(D,敲聲)=0.141
Gain(D,根蒂)=0.381
Gain(D,根蒂)=0.289
Gain(D,根蒂)=0.006

其中紋理的信息增益最大,把紋理選爲屬性劃分:


在這裏插入圖片描述

依照上述步驟再分類對紋理的三個屬性進行劃分,得到最後的劃分結果。

這是我自己根據書上步驟寫的程序:

import math
import pandas as pd
import operator
import numpy as np
def data():
    dataSet = [
        ['青綠', '蜷縮', '濁響', '清晰', '凹陷', '硬滑', '好瓜'],
        ['烏黑', '蜷縮', '沉悶', '清晰', '凹陷', '硬滑', '好瓜'],
        ['烏黑', '蜷縮', '濁響', '清晰', '凹陷', '硬滑', '好瓜'],
        ['青綠', '蜷縮', '沉悶', '清晰', '凹陷', '硬滑', '好瓜'],
        ['淺白', '蜷縮', '濁響', '清晰', '凹陷', '硬滑', '好瓜'],
        ['青綠', '稍蜷', '濁響', '清晰', '稍凹', '軟粘', '好瓜'],
        ['烏黑', '稍蜷', '濁響', '稍糊', '稍凹', '軟粘', '好瓜'],
        ['烏黑', '稍蜷', '濁響', '清晰', '稍凹', '硬滑', '好瓜'],
        # ----------------------------------------------------
        ['烏黑', '稍蜷', '沉悶', '稍糊', '稍凹', '硬滑', '壞瓜'],
        ['青綠', '硬挺', '清脆', '清晰', '平坦', '軟粘', '壞瓜'],
        ['淺白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '壞瓜'],
        ['淺白', '蜷縮', '濁響', '模糊', '平坦', '軟粘', '壞瓜'],
        ['青綠', '稍蜷', '濁響', '稍糊', '凹陷', '硬滑', '壞瓜'],
        ['淺白', '稍蜷', '沉悶', '稍糊', '凹陷', '硬滑', '壞瓜'],
        ['烏黑', '稍蜷', '濁響', '清晰', '稍凹', '軟粘', '壞瓜'],
        ['淺白', '蜷縮', '濁響', '模糊', '平坦', '硬滑', '壞瓜'],
        ['青綠', '蜷縮', '沉悶', '稍糊', '稍凹', '硬滑', '壞瓜']
    ]

    # 特徵值列表
    labels = ['色澤', '根蒂', '敲擊', '紋理', '臍部', '觸感']
    return dataSet,labels
###################################################################################
#信息熵
def Ent(df):
    dic={}
    EntD=0
    #df = pd.DataFrame(dataset)
    datalabel = df[df.shape[1] - 1]        #獲取最後一列的數據
    for i in set(datalabel):               #統計好瓜和壞瓜個數
        dic[i]=sum(datalabel==i)
    for i in dic.values():                 #計算信息熵
        EntD -=(i/len(df))*math.log(i/len(df),2)
    return EntD
###################################################################################
#去除標籤那一列的數據
def remove(df,i):
    dicall = []
    #df=pd.DataFrame(dataset)
    lei=set(df[i])                      #屬性類別
    for yangben in lei:                 #獲取去除標籤那列的數據
        aa=df[(df[i]==yangben)]
        aa=np.array(aa.drop([i], axis=1)).tolist()       #刪除標籤列,轉化爲list保存
        aa=pd.DataFrame(aa)                              #重新轉化爲dataframe格式
        dicall.append(aa)
    return dicall,lei
###################################################################################
 #計算信息增益
def Gain(dataset,labels):
    dic={}
    for i in range(len(labels)):                   #遍歷每個標籤
        ENtall = Ent(dataset)                       #得到信息熵
        dataset1,shuxing=remove(dataset,i)
        for j in range(len(shuxing)):               #計算每個屬性每個類別的信息熵
            size=Ent(dataset1[j])
            ENtall-= (len(dataset1[j])/len(dataset))*size    #得到信息增益
        dic[i] = ENtall                             #將屬性和信息增益存在字典中
    largelabels = sorted(dic.items(),key=operator.itemgetter(1), reverse=True)  #將信息增益排序
    return largelabels[0][0]                    # 返回最大的信息增益

###########################################################################
#返回最後類別中比較多的那一類[好瓜,好瓜,壞瓜],返回好瓜
def largedata(dataset):
    dic = {}
    setnum=set(dataset[dataset.shape[1]-1])
    for i in setnum:
        dic[i]=sum(dataset[dataset.shape[1]-1]==i)
    aa=sorted(dic.items(),key=operator.itemgetter(1),reverse=True)
    return aa[0][0]
######################################################################
#生成決策樹
def TreeGenerate1(dataset, labels):
    df=pd.DataFrame(dataset) 
    if len(df)==1 :                                   #第一個返回條件
        return np.array(df[len(df.ix[0])-1]).tolist()[0]
    labelset=set(df[len(labels)])
    if len(labels) == 0 or len(labelset) == 1:        #第二個返回條件
        return largedata(dataset)
    dic={}
    dicall=[]
    bestlabel=Gain(df,labels)                       #獲取最好標籤
    dataset1,shu=remove(df,bestlabel)               #去除最好標籤的數據集和屬性類別
    #pdb.set_trace()
    linedata1 = labels[:bestlabel]     
    linedata1.extend(labels[bestlabel + 1:])        #在列表中刪除最好標籤
    #pdb.set_trace()
    for i,aa in enumerate(shu):                     #遍歷屬性類別

        dic1 = {}
        dic1[aa]=TreeGenerate1(dataset1[i], linedata1)       #生成字典dic1={清晰:?,模糊:?,稍糊:?}
        dicall.append(dic1)
    dic[labels[bestlabel]]=dicall                    #再將上邊的字典放入大字典中{紋理:dic1}
    return dic
########################################################################
dataset, labels = data()
regr_1=TreeGenerate1(dataset, labels )
print(regr_1)

程序結果:

{'紋理': [{'清晰': {'根蒂': [{'稍蜷': {'色澤': [{'青綠': '好瓜'}, {'烏黑': {'觸感': [{'軟粘': '壞瓜'}, {'硬滑': '好瓜'}]}}]}}, {'硬挺': '壞瓜'}, {'蜷縮': '好瓜'}]}}, {'稍糊': {'觸感': [{'軟粘': '好瓜'}, {'硬滑': '壞瓜'}]}}, {'模糊': '壞瓜'}]}

程序講解:
以下是整個程序的流程圖:
在這裏插入圖片描述

二、信息增益率
著名的C4.5算法就提出不使用信息增益,而使用信息增益率來劃分最優屬性。信息增益率的出現是因爲信息增益不夠好,信息增益對可取值數目較多的屬性有所偏好,這樣會造成決策樹分支多,深度淺。舉例:比如表4.1中,將編號也劃爲屬性。那麼編號中有17個取值。Ent(Di)=0,Gain(編號)=0.998。這時候就會變成:


在這裏插入圖片描述

可見由編號作爲劃分條件雖然可以直接判斷西瓜的好壞,但是這樣的分支屬性太多,並不一定是最好的。
信息增益率公式:


在這裏插入圖片描述

Gain(D,a)我們通過第一節已經求出來了,信息增益率就是用信息增益除以IV(a)。v就是屬性的類別數目,比如色澤(青綠,烏黑,淺白)v=3。


在這裏插入圖片描述

得到IV(色澤)=1.580(v=3)
增益率準則對屬性類別較少的屬性(觸感V=2)有所偏好,所以C4.5不直接使用增益率最大的候選劃分屬性,而是先選出信息增益高於平均值的屬性,再從中選擇增益率最高的一個。
三、CART基尼指數
數據集D的純度可以用基尼值來度量


在這裏插入圖片描述
在這裏插入圖片描述

表4.1中,以屬性色澤爲例
在這裏插入圖片描述
基尼係數越小,屬性越優。
Gini 指數的計算不需要對數運算,更加高效;
Gini 指數更偏向於連續屬性,熵更偏向於離散屬性。

四、決策樹的過擬合
決策樹的對訓練數據集有很好的分類能力,但是對未知的測試書籍未必有很好的分類能力,泛化能力弱,容易發生過擬合。剪枝是處理過擬合問題的重要手段。剪枝分爲預剪枝和後剪枝。
隨機森林是一種比較好的處理決策樹過擬合的方法。

1、隨機森林來源
Bagging策略
(從樣本中重採樣(有重複)選出n個樣本。
在所有屬性上對n個樣本建立分類器(ID3、C4.5、CART、SVM、logistic迴歸))
重複以上m次,得到m個分類器
根據這m個分類器的結果,決定數據屬於哪一類

2、隨機森林在Bagging基礎上做了修改
隨機森林策略
(從數據集中用Bootstrap採樣選出n個樣本;
從所有屬性中隨機選出k個屬性,選擇最佳分割屬性作爲節點建立CART決策樹)
重複以上步驟m次,就得到m棵CART決策樹
這m個決策樹就是隨機森林,通過投票表決結果

3、隨機森林/Bagging/決策樹的關係

  • 隨機森林和Bagging可以使用決策樹爲基本分類器
  • 也可以使用SVM、Logistic迴歸等其他分類器,習慣上,這些分類器組成總的“分類器”,仍然叫隨機森林

想要了解關於集成學習-boosting算法,隨機森林,bagging算法的,可以點這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章