機器學習——決策樹、隨機森林(學習筆記)

決策樹

基本流程

決策樹學習的目的是爲了產生一顆泛化能力強,即處理未見示例能力強的決策樹,其基本流程遵循簡單且直觀的“分而治之”(divide-and-conquer)策略,如下所示:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-icykLuCX-1590821731414)(決策樹基本算法.png)]

  • 決策樹的關鍵在於當前狀態下選擇哪個屬性作爲分類條件(即劃分選擇)。
  • 最佳分類屬性這種“最佳性”可以用非純度(impurity)進行衡量。
  • 如果一個數據集合中只有一種分類結果,則該集合最純,即一致性好
  • 有許多分類,則不純,即一致性不好

劃分選擇

1.ID3(信息增益):分類

信息熵(information entropy)是度量樣本集合純度最常用的一種指標。假定當前樣本集合DD中第kk類樣本所佔的比例爲pk(k=1,2,,y)p_k(k=1,2,\cdots,\begin{vmatrix}y\end{vmatrix}),這裏的y\begin{vmatrix}y\end{vmatrix}標示樣本類別總數,即標籤(labels)總數,則DD的信息增益熵定義爲:
Ent(D)=k=1ypklog2pk Ent(D)=-\sum_{k=1}^{\begin{vmatrix}y\end{vmatrix}} p_klog_2p_k
Ent(D)Ent(D)的值越小,則DD的純度越高。

假定離散屬性aaVV個可能的取值{a1,a2,,aV}\{a^1,a^2,\cdots,a^V\}(注意:這裏指的是數據中的某一個特徵,以及該特徵的具體值),若使用aa來對樣本集DD進行劃分,則會產生VV個分支節點,其中第vv個分支節點包含了DD中所有在屬性aa上取值爲ava^v的樣本,記爲DvD^v。在通過上述公式計算出該分支樣本的信息熵,由於各個分支節點數的樣本不平均,需要給分支結點分配相對於的權重Dv/D\begin{vmatrix}D^v\end{vmatrix}/\begin{vmatrix}D\end{vmatrix}。由此可得到信息增益(information gain):
Gain(D,a)=Ent(D)v=1VDvDEnt(Dv) Gain(D,a)=Ent(D)-\sum_{v=1}^{V} \frac{\begin{vmatrix}D^v\end{vmatrix}}{\begin{vmatrix}D\end{vmatrix}}Ent(D^v)

一般而言,信息增益越大,則意味着使用屬性aa來進行劃分所獲得的“純度提升”越大

實例

在這裏插入圖片描述

def entrop(p1, p2):
    if p1 == 0 or p2 == 0:  #當特徵中只存在一個取值時 說明純度最高
        return 0
    else:
        return -p1*np.log2(p1)-p2*np.log2(p2)
# 根據上表可以看出
p_yes = 9/14
p_no = 1 - p_yes
entrop_decision = entrop(p_yes, p_no)
print(entrop_decision)
0.9402859586706311
# 特徵:Outlook
p_outlook_sunny_yes = 2/5
p_outlook_sunny_no = 1 - p_outlook_sunny_yes
p_outlook_rain_yes = 3/5
p_outlook_rain_no = 1 - p_outlook_rain_yes
p_outlook_overcast_yes = 4/4
p_outlook_overcast_no = 1 - p_outlook_overcast_yes
p_outlook_sunny = 5/14
p_outlook_rain = 5/14
p_outlook_overcast = 4/14

gain_decision_outlook  = entrop_decision - (p_outlook_sunny * entrop(p_outlook_sunny_yes,p_outlook_sunny_no)
                                    +p_outlook_rain * entrop(p_outlook_rain_yes,p_outlook_rain_no)
                                    +p_outlook_overcast * entrop(p_outlook_overcast_yes,p_outlook_overcast_no))
print(gain_decision_outlook)
0.24674981977443933
#特徵:Temp
p_temp_hot_yes = 2/4
p_temp_hot_no = 1 - p_temp_hot_yes
p_temp_mild_yes = 4/6
p_temp_mild_no = 1 - p_temp_mild_yes
p_temp_cool_yes = 3/4
p_temp_cool_no = 1 - p_temp_cool_yes
p_temp_hot = 4/14
p_temp_mild = 6/14
p_temp_cool = 4/14


gain_decision_temp = entrop_decision - (p_temp_hot * entrop(p_temp_hot_yes, p_temp_hot_no)
                                        + p_temp_mild * entrop(p_temp_mild_yes, p_temp_mild_no)
                                        + p_temp_cool * entrop(p_temp_cool_yes, p_temp_cool_no))
print(gain_decision_temp)
0.02922256565895487
#特徵:Humidity
p_humidity_high_yes = 5/7
p_humidity_high_no = 1 - p_temp_hot_yes
p_humidity_normal_yes = 6/7
p_humidity_normal_no = 1 - p_temp_mild_yes
p_humidity_high = 7/14
p_humidity_normal = 7/14


gain_decision_humidity = entrop_decision - (p_humidity_high * entrop(p_humidity_high_yes, p_humidity_high_no)
                                        + p_humidity_normal * entrop(p_humidity_normal_yes, p_humidity_normal_no))
print(gain_decision_humidity)
0.15744778017877914
#特徵:Wind
p_wind_weak_yes = 6/8
p_wind_weak_no = 1 - p_wind_weak_yes
p_wind_strong_yes = 3/6
p_wind_strong_no = 1 - p_wind_strong_yes
p_wind_weak = 8/14
p_wind_strong = 6/14


gain_decision_wind = entrop_decision - (p_wind_weak * entrop(p_wind_weak_yes, p_wind_weak_no)
                                        + p_wind_strong * entrop(p_wind_strong_yes, p_wind_strong_no))
print(gain_decision_wind)
0.04812703040826949
print('Gain(decisiong|outlook)={:.3f}\nGain(decision|temp)={:.3f}\nGain(decisiong|humidity)={:.3f}\nGain(decisiong|wind)={:.3f}\n'
      .format(gain_decision_outlook,gain_decision_temp,gain_decision_humidity,gain_decision_wind))
Gain(decisiong|outlook)=0.247
Gain(decision|temp)=0.029
Gain(decisiong|humidity)=0.157
Gain(decisiong|wind)=0.048

通過上述結果可以看出outlook特徵的信息增益最大,說明使用該特徵進行劃分所獲得的“純度提升”效果最好。因此,使用outlook特徵作爲決策樹的第一個節點。後續的決策樹分支,一次進行各特徵下的信息增益。

2.C4.5(信息增益比):分類

ID3的信息增益存在一個缺點:一般會優先選擇有較多屬性值的特徵。

解決方案:增加懲罰項,C4.5使用信息增益比率(gain ratio)
Gainratio(D,a)=Gain(D,a)IV(a), Gain_ratio(D,a)=\frac{Gain(D,a)}{IV(a)},
其中
IV(a)=v=1VDvDlog2DvD IV(a)=-\sum_{v=1}^{V} \frac{\begin{vmatrix}D^v\end{vmatrix}}{\begin{vmatrix}D\end{vmatrix}}log_2\frac{\begin{vmatrix}D^v\end{vmatrix}}{\begin{vmatrix}D\end{vmatrix}}
稱爲屬性aa的“固有值”,該值描述了aa特徵中不同特徵值數目的大小,數目越多,則IV(a)IV(a)越大。

增益率準則是對可取值數目較少的屬性有所偏好,因此,C4.5算法是先從候選劃分屬性中找出信息增益率高與平均水平的屬性,再從中選擇增益率最高的。

3.CART(GINI係數):分類與迴歸

數據集DD的純度可用基尼值來度量:
Gini(D)=k=1ykkpkpk=1k=1ypk2 \begin{aligned} Gini(D)& =\sum_{k=1}^{\begin{vmatrix}y\end{vmatrix}}\sum_{k'\ne k}p_kp_{k'} \\ & = 1-\sum_{k=1}^{\begin{vmatrix}y\end{vmatrix}}p^2_k \\ \end{aligned}
Gini(D)Gini(D)越小,則數據集DD的純度越高。

屬性aa的基尼指數(Gini index)定義爲:
Giniindex(D,a)=v=1VDvD Gini_index(D,a)=\sum_{v=1}^{V} \frac{\begin{vmatrix}D^v\end{vmatrix}}{\begin{vmatrix}D\end{vmatrix}}
選擇使得劃分後基尼指數最小的屬性作爲最優劃分屬性。

剪枝算法

預剪枝

  • 在構造決策樹的同時進行剪枝。
  • 所有決策樹的構建方法,都是在無法進一步降低熵的情況下才會停止創建分支的過程,
    爲了避免過擬合,可以設定一個閾值。
  • 例如:熵減小的數量小於這個閾值,即使還可以繼續降低熵,也停止繼續創建分支。

後剪枝

  • 決策樹構造完成後進行剪枝。
  • 剪枝的過程是對擁有同樣父節點的一組節點進行檢查,判斷如果將其合併,熵的增加
    量是否小於某一閾值。
  • 如果滿足閾值要求,則這一組節點可以合併一個節點,其中包含了所有可能的結果。
  • 示例:𝑹𝒆𝒅𝒖𝒄𝒆𝒅 − 𝑬𝒓𝒓𝒐𝒓 𝑷𝒓𝒖𝒏𝒊𝒏𝒈 (𝑹𝑬𝑷)錯誤率降低剪枝
    • 思路:決策樹過度擬合後,通過測試數據集來糾正。
    • 步驟:
      1. 對於完樹中每一個非葉子節點的子樹,嘗試着把它替換成一個葉子節點
      2. 該葉子節點的類別用子樹覆蓋訓練樣本中存在最多的那個類來代替,產生簡化決策樹
      3. 然後比較這兩個決策樹在測試數據集中的表現
      4. 簡化決策樹在測試數據集中的錯誤比較少,那麼該子樹就可以替換成葉子節點
      5. 以bottom-up的方式遍歷所有的子樹,當沒有任何子樹可以替換提升,算法終止

隨機森林

基本流程

  • 隨機森林以隨機的方式建立一個森林
  • 森林裏有很多決策樹,且每棵樹之間無關聯
  • 當有一個新樣本進入後,讓森林中每棵決策樹分別各自獨立判斷,看這個樣
    本應該屬於哪一類(分類算法)
  • 然後看哪一類被選擇最多,就選擇預測此樣本爲那一類

Out of bag error (OOBE)

  • 關於oob的解釋,stackoverflow上有比較全面的解釋:OOB的解釋
    • RF需要從原始的特徵集中隨機sampling,然後去分裂生成單顆樹.

    • 每個樹的訓練樣本是從原始的訓練集boostraping而來.

    • 由於boostraping的有放回抽樣方式,導致每個樹的訓練集合不同且只是原始訓練集的一個部分.

    • 對於第t個樹來說,原始訓練集中那些不在第t個樹的訓練集的數據,可以使用第t個樹來進行test.

    • 現在生成n(n是原始數據集的大小)個樹,每個樹的訓練樣本大小爲n-1,對第i個樹來說其訓練集不包含(xi,yi)這個樣本.

    • 使用不包含(xi,yi)這個樣本的所有的樹(n-1個),vote的結果作爲最終(xi,yi)這個樣本的test結果.

      參考博客:Out of bag error in Random Forest

優缺點

  • 優點:
    1. 適用數據集廣
    2. 高維數據
    3. Feature重要性排序
    4. 訓練速度快,並行化
  • 缺點:
    1. 級別劃分較多的屬性影響大

boost算法

  • 決策樹:單決策樹時間複雜度較低,模型容易展示,但是容易過擬合(Over-Fitting)
    • 分類樹
    • 迴歸樹
  • 決策樹的𝑩𝒐𝒐𝒔𝒕方法:迭代過程,新的訓練爲了改進上一次的結果
    • 傳統𝑩𝒐𝒐𝒔𝒕: 對正確、錯誤的樣本進行加權,每一步結束後,增加分錯點的權重,減少對分
      對點的權重
    • 𝑮𝒓𝒂𝒅𝒊𝒆𝒏𝒕𝑩𝒐𝒐𝒔𝒕:梯度迭代,每一次建立模型是在之前建立的模型損失函數的梯度下降方向

Adaboost算法

  • Adaboost的核心思想
    • 關注被錯分的樣本,器重性能好的分類器
  • 如何實現
    • 不同的訓練集 -> 調整樣本權重
    • 關注 -> 增加錯分樣本權重
    • 器重 -> 好的分類器權重大
    • 樣本權重間接影響分類器權重
  • 算法實例:
    Adaboost算法實例
    由圖可以看出第一次訓練中,存在三個錯誤值(被圈出),在第二次訓練前加強上述錯誤值的權重,再進行訓練,以此類推。循環T次訓練,T爲人工選取次數。

GBDT(Gradient Boosting Decision Tree)算法

  • 用一個初始值來學習一棵決策樹,葉子處可以得到預測的值,以及預測之
    後的殘差,然後後面的決策樹就要基於前面決策樹的殘差來學習,直到預
    測值和真實值的殘差爲零。
  • 最後對於測試樣本的預測值,就是前面許多棵決策樹預測值的累加。
  • 優點:
    • 適用問題廣,可擴展性好(萬金油算法)
    • 幾乎可以用於所有迴歸問題(線性、非線性)
    • 常用於各大數據挖掘競賽
  • 實例:
    GBDT算法實例
  • Random Forest VS GBDT:
    • 準確度:樹少時,GBDT > RF
    • 擬合:RF容易欠擬合, GBDT容易過擬合
    • 建模能力:GBDT > RF,因爲因爲boosted trees是通過優化目標函數得出的,所以基本上可以用於解決幾乎所有可以寫出梯度的目標。
    • 並行化:GBDT < RF,由於隨機森林可以並行運行,因此可以輕鬆地以分佈式方式進行部署,而Gradient Boosted Machines只能在多個實驗之間進行。

XGBoost

  • Boosting分類器將成百上千個分類準確率較低的樹模型組合起來,成爲一個
    準確率很高的模型。
  • 數據集較大較複雜的時候,我們可能需要幾千次迭代運算,這將造成巨大的
    計算瓶頸。
  • XGBoost正是爲了解決這個瓶頸而提出。單機它採用多線程來加速樹的構建,
    並可以進行分佈式計算。
  • XGBoost提供了 Python和R語言接口。

集成學習

Bagging

讓該學習算法訓練多輪,每輪的訓練集由從初始的訓練集中隨機取出的n個訓練樣本組成,某個初始訓練樣本在某輪訓練集中可以出現多次或根本不出現,訓練之後可得到一個預測函數序h1,,hnh_1,\cdots,h_n,最終的預測函數H對分類問題採用投票方式,對迴歸問題採用簡單平均方法對新示例進行判別。

Boosting

  • 初始化時對每一個訓練例賦相等的權重1n\frac{1}{n}
  • 然後用該學算法對訓練集訓練tt
  • 每次訓練後,對訓練失敗的訓練例賦以較大的權重,也就是讓學習算法在後續的學習中集中對比較難的訓練例進行學習,從而得到一個預測函數序列h1,,hnh_1,\cdots,h_n, 其中hih_i也有一定的權重,預測效果好的預測函數權重較大,反之較小。
  • 最終的預測函數H對分類問題採用有權重的投票方式,對迴歸問題採用加權平均的方法對新示例進行判別。

不難看出Adaboost類似於Bagging和Bossting的綜合

Stacking

  • 將訓練好的所有基模型對訓練基進行預測,第𝒋個基模型對第𝒊個訓練樣本的預測值將作爲新的訓練集中第𝒊個樣本的第𝒋個特徵值,最後基於新的訓練集進行訓練。
  • 同理,預測的過程也要先經過所有基模型的預測形成新的測試集,最後再對測試集進行預測
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章