1. 程式人生 > >機器學習——決策樹和隨機森林演算法

機器學習——決策樹和隨機森林演算法

認識決策樹

決策樹思想的來源非常樸素,程式設計中的條件分支結構就是if-then結構,最早的決策樹就是利用這類結構分割資料的一種分類學習方法。

下面以一個問題引出決策樹的思想

這個問題用圖來表示就是這樣:

為什麼先把年齡放在第一個呢,下面就是一個概念:資訊熵

資訊熵

單位為位元

公式為:

資訊和消除不確定性是相聯絡的

資訊熵越大不確定性越大

決策樹的劃分依據:資訊增益

特徵A對訓練資料集D的資訊增益g(D,A),定義為集合D的資訊熵H(D)與特徵A給定條件下D的資訊條件熵H(D|A)之差,即公式為:

g(D,A)=H(D)-H(D|A)     H(D)初始資訊熵大小

資訊增益:當得知一個特徵條件之後,減少的資訊熵的大小。

注意:資訊增益表示得知特徵X的資訊而使得類Y的資訊的不確定性減少的程度

下面用一個例子來說明

ID 年齡 有工作 有自己的房子 信貸情況 類別
1 青年 一般
2 青年
3 青年
4 青年 一般
5 青年 一般
6 中年 一般
7 中年
8 中年
9 中年 非常好
10 中年 非常好
11 老年 非常好
12 老年
13 老年
14 老年 非常好
15 老年 一般

H(D)=-(9/15log9/15+6/15(6/15)) 總的資訊熵大小

g(D,年齡)=H(D)-H(D'|年齡)=0.971-[1/3H(青年)+1/3H(中年)+1/3H(老年)]

                                         H(青年)=-(2/5log2/5+3/5log3/5)

                                         H(中年) =-(2/5log2/5+3/5log3/5)

                                         H(老年)=-(1/5log1/5+4/5log4/5)

決策樹的分類依據之一:資訊增益

常見決策樹使用的演算法

  • ID3

資訊增益 最大原則

  • C4.5

資訊增益比 最大的準則 即資訊增益比上原來的H(D)的比值大小

  • CART

迴歸樹:平方誤差

分類樹:基尼係數 最小的準則 在sklearn中可以選擇劃分的預設原則

sklearn決策樹API

class sklearn.tree.DescisionTreeClassifier(criterion='gini',max_depth=None.random_state=None)

  • 決策樹分類器
  • criterion:預設是'gini'係數,也可以選擇資訊增益的熵'entropy'
  • max_depth:樹的深度大小
  • random_state:隨機數種子
  • method:
  • decision_path"返回決策樹的路徑

下面用一個例項說明:

預測泰坦尼克號人員的存活情況

部分資料截圖如下:

程式碼如下:

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
import pandas as pd
def decision():
    """
    決策樹對泰坦尼克號進行預測生死
    :return:
    """
    #獲取資料
    titan=pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
    #處理資料,找出特徵值和目標值
    x=titan[['pclass','age','sex']] #特徵值
    y=titan['survived']    #目標值
    #缺失值處理
    x['age'].fillna(x['age'].mean(),inplace=True)
    #分割資料集到訓練集合測試集
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
    #進行處理(特徵工程) 特徵=》 類別=》 one_hot編碼
    dict=DictVectorizer(sparse=False)
    x_train=dict.fit_transform(x_train.to_dict(orient="records"))
    print(dict.get_feature_names())
    x_test=dict.transform(x_test.to_dict(orient="records"))
    #用決策樹進行預測
    dec=DecisionTreeClassifier(max_depth=5)
    dec.fit(x_train,y_train)
    #預測準確率
    print(dec.score(x_test,y_test))
    return None
    
if __name__=="__main":
    decision()

執行結果如下:

決策樹的優缺點

優點:

  • 簡單的理解和解釋,樹木視覺化。
  • 需要很少的資料準備,其他技術通常需要資料歸一化。

缺點:

  • 決策樹學習者可以建立不能很好地推廣資料的過於複雜的樹,這被稱為過擬合。

改進:

  • 剪枝cart演算法(決策樹API當中已經實現,隨機森林引數調優有相關介紹)
  • 隨機森林

隨機森林

整合學習方法

整合學習通過建立幾個模型組合的來解決單一預測問題。它的工作原理是生成多個分類器/模型,各自獨立地學習和作出預測。這些預測最後結合成單預測,因此優於任何一個單分類的做出預測。

隨機森林建立多個決策樹的過程:                 N個樣本,M個特徵

單個樹建立過程:

  1. 隨機在N個樣本當中選擇一個樣本,重複N次
  2. 隨機在M個特徵當中選出m個特徵  m取值

建立多棵決策樹,樣本,特徵大多不一樣          隨機有放回,建立決策樹

採取bootstrap抽樣

為什麼要隨機抽樣訓練集?

如果不進行隨機抽樣,每棵樹的訓練集都一樣,那麼最終訓練出的樹分類結果也是完全一樣的

為什麼要有放回地抽樣?

如果不是有放回的抽樣,那麼每棵樹的訓練樣本都是不同的,都是沒有交集的,這樣每棵樹都是"有偏的",都是絕對"片面的,也就是說每棵樹訓練出來都是有很大的差異的;而隨機森林最後分類取決於多棵樹(弱分類器)的投票表決。

隨機森林API

class sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=True,random_state=None)

  • 隨機森林分類器
  • n_estimators:integer,optional(default=10)森林裡的數木數量120,200,300,500,800,1200
  • criteria:string,可選(defalut="gini")分割特徵的測量方法
  • max_depth:integer或None,可選(預設=無)樹的最大深度 5,8,15,25,30
  • max_features="auto",每個決策樹的的最大特徵數量
  • bootstrap:boolean,optional(default=True)是否在構建樹使用放回抽樣

程式碼如下所示:

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
import pandas as pd
def decision():
    """
    決策樹對泰坦尼克號進行預測生死
    :return:
    """
    #獲取資料
    titan=pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
    #處理資料,找出特徵值和目標值
    x=titan[['pclass','age','sex']] #特徵值
    y=titan['survived']    #目標值
    #分割資料集到訓練集合測試集
    x['age'].fillna(x['age'].mean(),inplace=True)
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.25)
    #進行處理(特徵工程) 特徵=》 類別=》 one_hot編碼
    dict=DictVectorizer(sparse=False)
    x_train=dict.fit_transform(x_train.to_dict(orient="records"))
    print(dict.get_feature_names())
    rf=RandomForestClassifier()
    param={"n_estimators":[120,200,300,500,800,1200],"max_depth":[5,8,15,25,30]}
    #網格搜尋與交叉驗證調優
    gc=GridSearchCV(rf,param_grid=param,cv=2)
    gc.fit(x_train,y_train)
    print("預測準確率為:",gc.score(x_test,y_test))
    print("檢視選擇的引數模型:",gc.best_params_)
if __name__=="__main":
    decision()

執行結果如下:

隨機森林的優點

  • 在當前所有演算法中,具有極好的準確率
  • 能夠有效地執行在大資料集上
  • 能夠處理具有高維特徵的輸入樣本,而且不需要降維
  • 能夠評估各個特徵在分類問題上的重要性