隨機森林 RF RandomForest
隨機森林的集成學習方法是bagging ,但是和bagging 不同的是bagging只使用bootstrap有放回的采樣樣本,但隨機森林即隨機采樣樣本,也隨機選擇特征,因此防止過擬合能力更強,降低方差。
使用的融合方法:bagging
- 一種集成學習算法,基於bootstrap sampling 自助采樣法,重復性有放回的隨機采用部分樣本進行訓練最后再將結果 voting 或者 averaging 。
- 它是並行式算法,因為不同基學習器是獨立
- 訓練一個bagging集成學習器時間復雜度與基學習器同階(n倍,n為基學習器個數)。
- bagging可以用於二分類/多分類/回歸
- 每個基學習器的未用作訓練樣本可用來做包外估計,評價泛化性能。
- bagging主要關注降低 方差。
- 兩個步驟 1. 抽樣訓練(采樣樣本,采樣特征) 2 融合
隨機森林進一步在決策樹訓練時加入隨機屬性選擇:
如果有M個輸入變量,每個節點都將隨機選擇m(m<M)個特定的變量,然后運用這m個變量來確定最佳的分裂點。在決策樹的生成過程中,m的值是保持不變的。m一般取M均方根
因此隨機森林即有樣本隨機性(來自bagging的boostrap sampling)又有特征隨機性。
隨機森林的優缺點
優點:
a)隨機森林算法能解決分類與回歸兩種類型的問題,表現良好,由於是集成學習,方差和偏差都比較低,泛化性能優越;
b)隨機森林對於高維數據集的處理能力很好,它可以處理成千上萬的輸入變量,並確定最重要的變量,因此被認為是一個不錯的降維方法。此外,該模型能夠輸出特征的重要性程度,這是一個非常實用的功能。
c) 可以應對缺失數據;
d)當存在分類不平衡的情況時,隨機森林能夠提供平衡數據集誤差的有效方法;
e ) 高度並行化,易於分布式實現
f) 由於是樹模型 ,不需要歸一化即可之間使用
缺點:
a)隨機森林在解決回歸問題時並沒有像它在分類中表現的那么好,這是因為它並不能給出一個連續型的輸出。當進行回歸時,隨機森林不能夠作出超越訓練集數據范圍的預測,這可能導致在對某些還有特定噪聲的數據進行建模時出現過度擬合。
b)對於許多統計建模者來說,隨機森林給人的感覺像是一個黑盒子——你幾乎無法控制模型內部的運行,只能在不同的參數和隨機種子之間進行嘗試。
c) 忽略屬性之間的相關性
RF的調參
通用的調參方法:
- grid search 網格搜索。 sklearn 提供了相應的方GridSearchCV。即使用cross validation,對模型迭代的選用候選參數進行交叉驗證,取結果最好的參數,優點:效果好,相當於窮舉的思想,調參得到了候選參數里全局最優化結果。 缺點:計算復雜。 一般做競賽的小項目選這個啦。
- 基於貪心的坐標下降搜索。即固定其他參數,把某個參數取得最好。這樣迭代一遍得到最終結果。優點:計算量少,缺點:可能不是全局最優值、陷入局部最優解。
- 隨機網格搜索:防止 網格搜索間隔過大而跳過最優值,而隨機可以相對單個參數取到更多的值。
- n_estimators越多結果更穩定(方差越小),所以只要允許內,數目越大越好, 但計算量會大增。只有這個參數對結果的影響是越大越好,其他參數都是中間取得最優值。
- “分裂條件”(criterion)對模型的准確度的影響也不一樣,該參數需要在實際運用時靈活調整,可取gini或者信息增益比?。
- 每棵樹最大特征數(max_features) 一般用sqrt(總特征數)。
- 調整“最大葉節點數”(max_leaf_nodes)以及“最大樹深度”(max_depth)之一,可以粗粒度地調整樹的結構:葉節點越多或者樹越深,意味着子模型的偏差越低,方差越高;同時,調整“分裂所需最小樣本數”(min_samples_split)、“葉節點最小樣本數”(min_samples_leaf)及“葉節點最小權重總值”(min_weight_fraction_leaf),可以更細粒度地調整樹的結構:分裂所需樣本數越少或者葉節點所需樣本越少,也意味着子模型越復雜。
隨機森林的推廣(Extra Trees)
extra trees是RF的一個變種, 原理幾乎和RF一模一樣,僅有區別有:
1) 對於每個決策樹的訓練集,RF采用的是隨機采樣bootstrap來選擇采樣集作為每個決策樹的訓練集,而extra trees一般不采用隨機采樣,即每個決策樹采用原始訓練集。
2) 在選定了划分特征后,RF的決策樹會基於信息增益,基尼系數,均方差之類的原則,選擇一個最優的特征值划分點,這和傳統的決策樹相同。但是extra trees比較的激進,他會隨機的選擇一個特征值來划分決策樹。
從第二點可以看出,由於隨機選擇了特征值的划分點位,而不是最優點位,這樣會導致生成的決策樹的規模一般會大於RF所生成的決策樹。也就是說,模型的方差相對於RF進一步減少,但是bias相對於RF進一步增大。在某些時候,extra trees的泛化能力比RF更好
GBDT (Gradient Boosting Decision Tree)
gbdt的基本原理是boost 里面的 boosting tree(提升樹),並使用 gradient boost。
GBDT中的樹都是回歸樹,不是分類樹 ,因為gradient boost 需要按照損失函數的梯度近似的擬合殘差,這樣擬合的是連續數值,因此只有回歸樹。
梯度提升 gradient boosting:
Gradient Boosting是一種Boosting的方法,其與傳統的Boosting的區別是,每一次的計算是為了減少上一次的殘差(residual),而為了消除殘差,可以在殘差減少的梯度(Gradient)方向上建立一個新的模型。所以說,在Gradient Boosting中,每個新的模型的建立是為了使得之前模型的殘差往梯度方向減少,與傳統Boosting對正確、錯誤樣本進行加權有着很大的區別。這個梯度代表上一輪學習器損失函數對預測值求導。
與Boosting Tree的區別:Boosting Tree的適合於損失函數為平方損失或者指數損失。而Gradient Boosting適合各類損失函數(損失函數為:平方損失則相當於Boosting Tree擬合殘差、損失函數為:使用指數損失則可以近似於Adaboost,但樹是回歸樹)
對於梯度提升樹其學習流程與提升樹類似只是不再使用殘差作為新的訓練數據而是使用損失函數的梯度作為新的新的訓練數據的y值,具體的來說就是使用損失函數對f(x)求梯度然后帶入fm-1(x)計算:
GDBT與提升樹之間的關系:
提升樹模型每一次的提升都是靠上次的預測結果與訓練數據的label值差值作為新的訓練數據進行重新訓練,GDBT則是將殘差計算替換成了損失函數的梯度方向,將上一次的預測結果帶入梯度中求出本輪的訓練數據,這兩種模型就是在生成新的訓練數據時采用了不同的方法,那么在這個背后有啥區別?使用殘差有啥不好?
李航老師《統計學習方法》中提到了在使用平方誤差損失函數和指數損失函數時,提升樹的殘差求解比較簡單,但是在使用一般的損失誤差函數時,殘差求解起來不是那么容易,所以就是用損失函數的負梯度在當前模型的值作為回歸問題中殘差(均方誤差)或者殘差的近似值。
(來自MLAPP)
XGBoost
XGBoost比GBDT好的地方:
二階泰勒展開
節點分數懲罰正則
增益計算不同,gbdt是gini,xgb是優化推導公式Xgboost是GB算法的高效實現,xgboost中的基學習器除了可以是CART(gbtree)也可以是線性分類器(gblinear)。下面所有的內容來自原始paper,包括公式。
(1). xgboost在目標函數中顯示的加上了正則化項,基學習為CART時,正則化項與樹的葉子節點的數量T和葉子節點的值有關。
(2). GB中使用Loss Function對f(x)的一階導數計算出偽殘差用於學習生成fm(x),xgboost不僅使用到了一階導數,還使用二階導數。
第t次的loss:
對上式做二階泰勒展開:g為一階導數,h為二階導數
(3). 上面提到CART回歸樹中尋找最佳分割點的衡量標准是最小化均方差,xgboost尋找分割點的標准是最大化,lamda,gama與正則化項相關
xgboost算法的步驟和GB基本相同,都是首先初始化為一個常數,gb是根據一階導數ri,xgboost是根據一階導數gi和二階導數hi,迭代生成基學習器,相加更新學習器。
xgboost與gdbt除了上述三點的不同,xgboost在實現時還做了許多優化:
- 在尋找最佳分割點時,考慮傳統的枚舉每個特征的所有可能分割點的貪心法效率太低,xgboost實現了一種近似的算法。大致的思想是根據百分位法列舉幾個可能成為分割點的候選者,然后從候選者中根據上面求分割點的公式計算找出最佳的分割點。
- xgboost考慮了訓練數據為稀疏值的情況,可以為缺失值或者指定的值指定分支的默認方向,這能大大提升算法的效率,paper提到50倍。
- 特征列排序后以塊的形式存儲在內存中,在迭代中可以重復使用;雖然boosting算法迭代必須串行,但是在處理每個特征列時可以做到並行。
- 按照特征列方式存儲能優化尋找最佳的分割點,但是當以行計算梯度數據時會導致內存的不連續訪問,嚴重時會導致cache miss,降低算法效率。paper中提到,可先將數據收集到線程內部的buffer,然后再計算,提高算法的效率。
- xgboost 還考慮了當數據量比較大,內存不夠時怎么有效的使用磁盤,主要是結合多線程、數據壓縮、分片的方法,盡可能的提高算法的效率。
以下內容來自wepon作者:wepon
鏈接:https://www.zhihu.com/question/41354392/answer/98658997
- 傳統GBDT以CART作為基分類器,xgboost還支持線性分類器,這個時候xgboost相當於帶L1和L2正則化項的邏輯斯蒂回歸(分類問題)或者線性回歸(回歸問題)。
- 傳統GBDT在優化時只用到一階導數信息,xgboost則對代價函數進行了二階泰勒展開,同時用到了一階和二階導數。順便提一下,xgboost工具支持自定義代價函數,只要函數可一階和二階求導。
- xgboost在代價函數里加入了正則項,用於控制模型的復雜度。正則項里包含了樹的葉子節點個數、每個葉子節點上輸出的score的L2模的平方和。從Bias-variance tradeoff角度來講,正則項降低了模型的variance,使學習出來的模型更加簡單,防止過擬合,這也是xgboost優於傳統GBDT的一個特性。
- Shrinkage(縮減),相當於學習速率(xgboost中的eta)。xgboost在進行完一次迭代后,會將葉子節點的權重乘上該系數,主要是為了削弱每棵樹的影響,讓后面有更大的學習空間。實際應用中,一般把eta設置得小一點,然后迭代次數設置得大一點。(補充:傳統GBDT的實現也有學習速率)
- 列抽樣(column subsampling)即特征抽樣。xgboost借鑒了隨機森林的做法,支持列抽樣,不僅能降低過擬合,還能減少計算,這也是xgboost異於傳統gbdt的一個特性。
- 對缺失值的處理。對於特征的值有缺失的樣本,xgboost可以自動學習出它的分裂方向。
- xgboost工具支持並行。boosting不是一種串行的結構嗎?怎么並行的?注意xgboost的並行不是tree粒度的並行,xgboost也是一次迭代完才能進行下一次迭代的(第t次迭代的代價函數里包含了前面t-1次迭代的預測值)。xgboost的並行是在特征粒度上的。我們知道,決策樹的學習最耗時的一個步驟就是對特征的值進行排序(因為要確定最佳分割點),xgboost在訓練之前,預先對數據進行了排序,然后保存為block結構,后面的迭代中重復地使用這個結構,大大減小計算量。這個block結構也使得並行成為了可能,在進行節點的分裂時,需要計算每個特征的增益,最終選增益最大的那個特征去做分裂,那么各個特征的增益計算就可以開多線程進行。
- 可並行的近似直方圖算法。樹節點在進行分裂時,我們需要計算每個特征的每個分割點對應的增益,即用貪心法枚舉所有可能的分割點。當數據無法一次載入內存或者在分布式情況下,貪心算法效率就會變得很低,所以xgboost還提出了一種可並行的近似直方圖算法,用於高效地生成候選的分割點。
- 多種語言封裝支持。
XGBoost 調參
參考資料:
chentq的slides http://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf
chentq的paper http://arxiv.org/abs/1603.02754
chentq在52cs上的中文博文 http://www.52cs.org/?p=429
微博上分享的 xgboost導讀和實戰.pdf