筆記目錄
決策樹
基本流程
決策樹學習的目的是爲了產生一顆泛化能力強,即處理未見示例能力強的決策樹,其基本流程遵循簡單且直觀的“分而治之”(divide-and-conquer)策略,如下所示:
- 決策樹的關鍵在於當前狀態下選擇哪個屬性作爲分類條件(即劃分選擇)。
- 最佳分類屬性這種“最佳性”可以用非純度(impurity)進行衡量。
- 如果一個數據集合中只有一種分類結果,則該集合最純,即一致性好
- 有許多分類,則不純,即一致性不好
劃分選擇
1.ID3(信息增益):分類
信息熵(information entropy)是度量樣本集合純度最常用的一種指標。假定當前樣本集合中第類樣本所佔的比例爲,這裏的標示樣本類別總數,即標籤(labels)總數,則的信息增益熵定義爲:
的值越小,則的純度越高。
假定離散屬性有個可能的取值(注意:這裏指的是數據中的某一個特徵,以及該特徵的具體值),若使用來對樣本集進行劃分,則會產生個分支節點,其中第個分支節點包含了中所有在屬性上取值爲的樣本,記爲。在通過上述公式計算出該分支樣本的信息熵,由於各個分支節點數的樣本不平均,需要給分支結點分配相對於的權重。由此可得到信息增益(information gain):
一般而言,信息增益越大,則意味着使用屬性來進行劃分所獲得的“純度提升”越大
實例
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)
其中
稱爲屬性的“固有值”,該值描述了特徵中不同特徵值數目的大小,數目越多,則越大。
增益率準則是對可取值數目較少的屬性有所偏好,因此,C4.5算法是先從候選劃分屬性中找出信息增益率高與平均水平的屬性,再從中選擇增益率最高的。
3.CART(GINI係數):分類與迴歸
數據集的純度可用基尼值來度量:
越小,則數據集的純度越高。
屬性的基尼指數(Gini index)定義爲:
選擇使得劃分後基尼指數最小的屬性作爲最優劃分屬性。
剪枝算法
預剪枝
- 在構造決策樹的同時進行剪枝。
- 所有決策樹的構建方法,都是在無法進一步降低熵的情況下才會停止創建分支的過程,
爲了避免過擬合,可以設定一個閾值。 - 例如:熵減小的數量小於這個閾值,即使還可以繼續降低熵,也停止繼續創建分支。
後剪枝
- 決策樹構造完成後進行剪枝。
- 剪枝的過程是對擁有同樣父節點的一組節點進行檢查,判斷如果將其合併,熵的增加
量是否小於某一閾值。 - 如果滿足閾值要求,則這一組節點可以合併一個節點,其中包含了所有可能的結果。
- 示例:𝑹𝒆𝒅𝒖𝒄𝒆𝒅 − 𝑬𝒓𝒓𝒐𝒓 𝑷𝒓𝒖𝒏𝒊𝒏𝒈 (𝑹𝑬𝑷)錯誤率降低剪枝
- 思路:決策樹過度擬合後,通過測試數據集來糾正。
- 步驟:
- 對於完樹中每一個非葉子節點的子樹,嘗試着把它替換成一個葉子節點
- 該葉子節點的類別用子樹覆蓋訓練樣本中存在最多的那個類來代替,產生簡化決策樹
- 然後比較這兩個決策樹在測試數據集中的表現
- 簡化決策樹在測試數據集中的錯誤比較少,那麼該子樹就可以替換成葉子節點
- 以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結果.
-
優缺點
- 優點:
- 適用數據集廣
- 高維數據
- Feature重要性排序
- 訓練速度快,並行化
- 缺點:
- 級別劃分較多的屬性影響大
boost算法
- 決策樹:單決策樹時間複雜度較低,模型容易展示,但是容易過擬合(Over-Fitting)
- 分類樹
- 迴歸樹
- 決策樹的𝑩𝒐𝒐𝒔𝒕方法:迭代過程,新的訓練爲了改進上一次的結果
- 傳統𝑩𝒐𝒐𝒔𝒕: 對正確、錯誤的樣本進行加權,每一步結束後,增加分錯點的權重,減少對分
對點的權重 - 𝑮𝒓𝒂𝒅𝒊𝒆𝒏𝒕𝑩𝒐𝒐𝒔𝒕:梯度迭代,每一次建立模型是在之前建立的模型損失函數的梯度下降方向
- 傳統𝑩𝒐𝒐𝒔𝒕: 對正確、錯誤的樣本進行加權,每一步結束後,增加分錯點的權重,減少對分
Adaboost算法
- Adaboost的核心思想
- 關注被錯分的樣本,器重性能好的分類器
- 如何實現
- 不同的訓練集 -> 調整樣本權重
- 關注 -> 增加錯分樣本權重
- 器重 -> 好的分類器權重大
- 樣本權重間接影響分類器權重
- 算法實例:
由圖可以看出第一次訓練中,存在三個錯誤值(被圈出),在第二次訓練前加強上述錯誤值的權重,再進行訓練,以此類推。循環T次訓練,T爲人工選取次數。
GBDT(Gradient Boosting Decision Tree)算法
- 用一個初始值來學習一棵決策樹,葉子處可以得到預測的值,以及預測之
後的殘差,然後後面的決策樹就要基於前面決策樹的殘差來學習,直到預
測值和真實值的殘差爲零。 - 最後對於測試樣本的預測值,就是前面許多棵決策樹預測值的累加。
- 優點:
- 適用問題廣,可擴展性好(萬金油算法)
- 幾乎可以用於所有迴歸問題(線性、非線性)
- 常用於各大數據挖掘競賽
- 實例:
- 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個訓練樣本組成,某個初始訓練樣本在某輪訓練集中可以出現多次或根本不出現,訓練之後可得到一個預測函數序,最終的預測函數H對分類問題採用投票方式,對迴歸問題採用簡單平均方法對新示例進行判別。
Boosting
- 初始化時對每一個訓練例賦相等的權重
- 然後用該學算法對訓練集訓練輪
- 每次訓練後,對訓練失敗的訓練例賦以較大的權重,也就是讓學習算法在後續的學習中集中對比較難的訓練例進行學習,從而得到一個預測函數序列, 其中也有一定的權重,預測效果好的預測函數權重較大,反之較小。
- 最終的預測函數H對分類問題採用有權重的投票方式,對迴歸問題採用加權平均的方法對新示例進行判別。
不難看出Adaboost類似於Bagging和Bossting的綜合
Stacking
- 將訓練好的所有基模型對訓練基進行預測,第𝒋個基模型對第𝒊個訓練樣本的預測值將作爲新的訓練集中第𝒊個樣本的第𝒋個特徵值,最後基於新的訓練集進行訓練。
- 同理,預測的過程也要先經過所有基模型的預測形成新的測試集,最後再對測試集進行預測