1. 程式人生 > 實用技巧 >GBDT梯度下降數原理理解

GBDT梯度下降數原理理解

gbdt全稱梯度下降樹,在傳統機器學習演算法裡面是對真實分佈擬合的最好的幾種演算法之一,在前幾年深度學習還沒有大行其道之前,gbdt在各種競賽是大放異彩。原因大概有幾個,一是效果確實挺不錯。二是即可以用於分類也可以用於迴歸。三是可以篩選特徵。這三點實在是太吸引人了,導致在面試的時候大家也非常喜歡問這個演算法。gbdt的面試考核點,大致有下面幾個:

  • gbdt 的演算法的流程?
  • gbdt 如何選擇特徵 ?
  • gbdt 如何構建特徵 ?
  • gbdt 如何用於分類?
  • gbdt 通過什麼方式減少誤差 ?
  • gbdt的效果相比於傳統的LR,SVM效果為什麼好一些 ?
  • gbdt 如何加速訓練?
  • gbdt的引數有哪些,如何調參 ?
  • gbdt 實戰當中遇到的一些問題 ?
  • gbdt的優缺點 ?

首先gbdt 是通過採用加法模型(即基函式的線性組合),以及不斷減小訓練過程產生的殘差來達到將資料分類或者回歸的演算法

gbdt是基於Boosting,而Boosting(Freund & Shapire, 1996) 通過迭代方式訓練若干基礎分類器,每個分類器依據上一輪分類器產生的殘差做權重調整,每輪的分類器需要夠“簡單”,具有高偏差、低方差的特點,框架再輔以(加權)投票方式降低偏差,使得整體趨於低偏差、低方差。

gbdt通過多輪迭代,每輪迭代產生一個弱分類器,每個分類器在上一輪分類器的殘差基礎上進行訓練

。對弱分類器的要求一般是足夠簡單,並且是低方差和高偏差的。因為訓練的過程是通過降低偏差來不斷提高最終分類器的精度,(此處是可以證明的)。
弱分類器一般會選擇為CART TREE(也就是分類迴歸樹)。由於上述高偏差和簡單的要求 每個分類迴歸樹的深度不會很深。最終的總分類器 是將每輪訓練得到的弱分類器加權求和得到的(也就是加法模型)。
模型最終可以描述為:

其中 hi(x) 為基模型與其權值的乘積,根據上式,整體模型的訓練目標是使預測值F(x)逼近真實值y,也就是說要讓每一個基模型的預測值逼近各自要預測的部分真實值。由於要同時考慮所有基模型,導致了整體模型的訓練變成了一個非常複雜的問題。所以,研究者們想到了一個貪心的解決手段:每次只訓練一個基模型

。那麼,現在改寫整體模型為迭代式:

使F[i](x)逼近真實值,其實就是使h[i](x)逼近真實值和上一輪迭代的預測值F[i-1](x)之差,即殘差(y-F[i-1](x))。最直接的做法是構建基模型來擬合殘差,在博文《GBDT(MART) 迭代決策樹入門教程 | 簡介》中,作者舉了一個生動的例子來說明通過基模型擬合殘差,最終達到整體模型F(x)逼近真實值。

研究者發現,殘差其實是最小均方損失函式的關於預測值的反向梯度

引入任意損失函式後,我們可以定義整體模型的迭代式如下:

這裡的 L() 是損失函式,迴歸演算法選擇的損失函式一般是均方差(最小二乘)或者絕對值誤差;而在分類演算法中一般的損失函式選擇對數函式來表示

gbdt如何選擇特徵?

gbdt選擇特徵的細節其實是想問你CART Tree生成的過程。這裡有一個前提,gbdt的弱分類器預設選擇的是CART TREE。其實也可以選擇其他弱分類器的,選擇的前提是低方差和高偏差。框架服從boosting 框架即可。
下面我們具體來說CART TREE(是一種二叉樹) 如何生成。CART TREE 生成的過程其實就是一個選擇特徵的過程。假設我們目前總共有 M 個特徵。第一步我們需要從中選擇出一個特徵 j,做為二叉樹的第一個節點。然後對特徵 j 的值選擇一個切分點 m. 一個 樣本的特徵j的值 如果小於m,則分為一類,如果大於m,則分為另外一類。如此便構建了CART 樹的一個節點。其他節點的生成過程和這個是一樣的。現在的問題是在每輪迭代的時候,如何選擇這個特徵 j,以及如何選擇特徵 j 的切分點 m:
原始的gbdt的做法非常的暴力,首先遍歷每個特徵,然後對每個特徵遍歷它所有可能的切分點,找到最優特徵 m 的最優切分點 j。
如何衡量我們找到的特徵 m和切分點 j 是最優的呢? 我們用定義一個函式 FindLossAndSplit 來展示一下求解過程:

gbdt引數詳解

class sklearn.ensemble.GradientBoostingClassifier(*, loss='deviance', learning_rate=0.1, n_estimators=100, subsample=1.0, 
criterion='friedman_mse', min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3,
min_impurity_decrease=0.0, min_impurity_split=None, init=None, random_state=None, max_features=None,
verbose=0, max_leaf_nodes=None, warm_start=False, presort='deprecated', validation_fraction=0.1,
n_iter_no_change=None, tol=0.0001, ccp_alpha=0.0)

引數:

(1)n_estimators: 也就是弱學習器的最大迭代次數,或者說最大的弱學習器的個數。一般來說n_estimators太小,容易欠擬合,n_estimators太大,又容易過擬合,一般選擇一個適中的數值。預設是100。在實際調參的過程中,我們常常將n_estimators和下面介紹的引數learning_rate一起考慮

(2)learning_rate, float,預設= 0.1,學習率縮小了每棵樹的貢獻learning_rate。在learning_rate和n_estimators之間需要權衡

(3)subsample: 即我們在原理篇的正則化章節講到的子取樣,取值為(0,1]。注意這裡的子取樣和隨機森林不一樣,隨機森林使用的是放回抽樣,而這裡是不放回抽樣。如果取值為1,則全部樣本都使用,等於沒有使用子取樣。如果取值小於1,則只有一部分樣本會去做GBDT的決策樹擬合。選擇小於1的比例可以減少方差,即防止過擬合,但是會增加樣本擬合的偏差,因此取值不能太低。推薦在[0.5, 0.8]之間,預設是1.0,即不使用子取樣

(4)loss: 即我們GBDT演算法中的損失函式。分類模型和迴歸模型的損失函式是不一樣的。
對於分類模型,有對數似然損失函式"deviance"和指數損失函式"exponential"兩者輸入選擇。預設是對數似然損失函式"deviance"。在原理篇中對這些分類損失函式有詳細的介紹。一般來說,推薦使用預設的"deviance"。它對二元分離和多元分類各自都有比較好的優化。而指數損失函式等於把我們帶到了Adaboost演算法。
對於迴歸模型,有均方差"ls", 絕對損失"lad", Huber損失"huber"和分位數損失“quantile”。預設是均方差"ls"。一般來說,如果資料的噪音點不多,用預設的均方差"ls"比較好。如果是噪音點較多,則推薦用抗噪音的損失函式"huber"。而如果我們需要對訓練集進行分段預測的時候,則採用“quantile”

(5)alpha:這個引數只有GradientBoostingRegressor有,當我們使用Huber損失"huber"和分位數損失“quantile”時,需要指定分位數的值。預設是0.9,如果噪音點較多,可以適當降低這個分位數的值

(6)min_samples_split, int或float,預設為2,拆分內部節點所需的最少樣本數:如果為int,則認為min_samples_split是最小值。如果為float,min_samples_split則為分數, 是每個拆分的最小樣本數。ceil(min_samples_split * n_samples)

(7)min_samples_leaf, int或float,預設值= 1,在葉節點處所需的最小樣本數。僅在任何深度的分裂點在min_samples_leaf左分支和右分支中的每個分支上至少留下訓練樣本時,才考慮。這可能具有平滑模型的效果,尤其是在迴歸中。如果為int,則認為min_samples_leaf是最小值。如果為float,min_samples_leaf則為分數, 是每個節點的最小樣本數。ceil(min_samples_leaf * n_samples)

(8)min_weight_fraction_leaf, float,預設值= 0.0,在所有葉節點處(所有輸入樣本)的權重總和中的最小加權分數。如果未提供sample_weight,則樣本的權重相等。

(9)max_depth, int,預設= 3,各個迴歸估計量的最大深度。最大深度限制了樹中節點的數量。調整此引數以獲得最佳效能;最佳值取決於輸入變數的相互作用。也就是那個樹有多少層(一般越多越容易過擬合)

(10)min_impurity_decrease, 浮動,預設值= 0.0,如果節點分裂會導致雜質的減少大於或等於該值,則該節點將被分裂

(11)min_impurity_split ,float,預設=無提前停止樹木生長的閾值。如果節點的雜質高於閾值,則該節點將分裂,否則為葉

(12)init:計量或“零”,預設=無,一個估計器物件,用於計算初始預測。 init必須提供fit和predict_proba。如果為“零”,則初始原始預測設定為零。預設情況下,使用 DummyEstimator預測類優先順序

(13)max_features:節點分裂時參與判斷的最大特徵數

  • int:個數
  • float:佔所有特徵的百分比
  • auto:所有特徵數的開方
  • sqrt:所有特徵數的開方
  • log2:所有特徵數的log2值
  • None:等於所有特徵數

其他沒啥好說的,有興趣可以自己檢視官網https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.GradientBoostingClassifier.html

屬性:

n_estimators_
feature_importances_
oob_improvement_
train_score_
loss_
init_
estimators_
classes_
n_features_
n_classes_
max_features_