監督學習集成模型——XGBoost

一、XGBoost原理

XGBoost的全稱爲eXtreme Gradient Boosting,即極度梯度提升樹,由陳天奇在其論文“XGBoost: A Scalable Tree Boosting System:https://arxiv.org/pdf/1603.02754.pdf
中提出,一度因其強大性能流行於各大數據競賽,在各種頂級解決方案中屢見不鮮。
image

XGBoost本質上仍屬於GBDT算法,但在算法精度、速度和泛化能力上均要優於傳統的GBDT算法。

  • 從算法精度上來看,XGBoost通過將損失函數展開到二階導數,使得其更能逼近真實損失;
  • 從算法速度上來看,XGBoost使用了加權分位數sketch和稀疏感知算法這兩個技巧,緩存優化和模型並行來提高算法速度;
  • 從算法泛化能力上來看,通過對損失函數加入正則化項、加性模型中設置縮減率和列抽樣等方法,來防止模型過擬合。

二、XGBoost基本原理

既然XGBoost整體上仍屬於GBDT算法系統,那麼XGBoost也一定是由多個基模型組成的一個加性模型,所以XGBoost可表示爲:

\(y ̂_i=∑_{k=1}^K f_k(x_i)\)

根據前向分步算法,假設第t次迭代的基模型爲\(f_t(x)\),有:

$y ̂_i(t)=∑_{k=1}^t y ̂_i(t−1)+f_t(x_i) $

XGBoost損失函數由經驗損失項和正則化項構成:

$L=∑_{i=1}^nl(y_i,y ̂_i)+∑_{i=1}^t Ω(f_i) $

其中\(∑_{i=1}^n l(y_i,y ̂_i)\)爲經驗損失項,表示訓練數據預測值與真實值之間的損失;\(∑_{i=1}^tΩ(f_i)\)爲正則化項,表示全部t棵樹的複雜度之和,這也是XGBoost控制模型過擬合的方法。

根據前向分步算法,以第t步模型爲例,假設模型對第i個樣本\(x_i\)的預測值爲:

\(y ̂_i (t)=y ̂_i (t−1)+f_t(x_i)\)

其中,\(y ̂_i(t−1)\)是由第t−1步的模型給出的預測值,其作爲一個已知常量存在,\(f_t(x_i)\)爲第t步樹模型的預測值。

所以,損失函數可以改寫爲:

\(L(t)=∑_{i=1}^n l(y_i,y ̂_i(t))+∑_{i=1}^t Ω(f_i)\)

\(=∑_{i=1}^n l(y_i,y ̂_i(t−1)+f_t(x_i))+∑_{i=1}^tΩ(f_i)\)

$=∑_{i=1}nl(y_i,y ̂_i(t−1)+f_t(x_i))+Ω(f_t)+Constant $

上式對正則化項進行了拆分,因爲前t−1棵樹的結構已經確定,所以前t−1棵樹的複雜度之和也可以表示爲常數:

$∑_{i=1}^t Ω(f_i)=Ω(f_t)+∑_{i=1}^t−1Ω(f_i) =Ω(f_t)+Constant $

然後針對損失函數式前半部分\(l(y_i,y ̂_i(t−1)+f_t(x_i))\),使用二階泰勒展開式,這裏需要用到函數的二階導數,相應的損失函數經驗損失項可以改寫爲:

\(l(y_i,y ̂_i(t−1)+f_t(x_i))=l(y_i,y ̂_i(t−1))+g_if_t(x_i)+\frac{1}{2}ℎ_if_t^2(x_i)\)

其中,\(g_i\)爲損失函數一階導數,\(ℎ_i\)爲損失函數二階導數,需要注意的是,這裏是對\(y ̂_i (t−1)\)求導。

XGBoost相較於GBDT的一個最大的特點就是用到了損失函數的二階導數信息,所以當自定義或者選擇XGBoost損失函數時,需要其二階可導。將的損失函數二階泰勒展開式代入,可得損失函數的近似表達式:

$L(t)≈∑_{i=1}^n[l(y_i,y ̂_i (t−1))+g_if_t(x_i)+\frac{1}{2}ℎ_if_t^2(x_i)]+Ω(f_t)+Constant $

去掉常數項後,上式可簡化爲:\(L^(t)≈∑_{i=1}^n[g_if_t(x_i)+\frac{1}{2}ℎ_if_t^2(x_i)]+Ω(f_t)\)

關於XGBoost的推導並沒有到此結束,爲了計算XGBoost決策樹結點分裂條件,我們還需要進一步的推導。

我們對決策樹做一下定義。假設一棵決策樹是由葉子結點的權重向量w和樣本實例到葉子結點的映射關係q構成,這種映射關係可以理解爲決策樹的分支結構。所以一棵樹的數學表達可以定義爲:

\(f_t(x)=w_q(x)\)

然後定義決策樹複雜度的正則化項。模型複雜度Ω可由單棵決策樹的葉子結點數T和葉子權重w決定,即損失函數的複雜度由所有決策樹的葉子結點數和葉子權重所決定。

\(Ω(f_t)=γT+\frac{1}{2}λ∑_{j=1}^T w_j^2\)

image

下面對決策樹所有葉子結點重新進行歸組。將屬於第j個葉子結點的所有樣本\(x_i\)劃入一個葉子結點的樣本集合中,即\(I_j=\{i|q(x_i)=j\}\),因而簡化後的XGBoost損失函數式又可以改寫爲:

\(L(t)≈∑_{i=1}^n[g_if_t(x_i)+\frac{1}{2}ℎ_if_t^2(x_i)]+Ω(f_t)\)

\(=∑_{i=1}^n[g_iw_q(x_i)+\frac{1}{2}ℎ_iw_q(x_i)^2]+γT+\frac{1}{2}λ∑_j1^Tw_j^2\)

$=∑_{j=1}^T[(∑_{i∈I_j }g_i)w_j+\frac{1}{2}(∑_{i∈I_j}ℎ_i+λ)w_j^2]+γT $

定義\(G_j=∑_{i∈I_j}g_i,H_j=∑_{i∈I_j}ℎ_i\)

其中:

  • \(G_j\)可以理解爲葉子結點j所包含樣本的一階偏導數累加之和
  • \(H_j\)可以理解爲葉子結點j所包含樣本的二階偏導數累加之和

\(G_j\)\(H_j\)均爲常量,將\(G_j\)\(H_j\)代入上式,損失函數又可以變換爲:

\(L(t)=∑_{j=1}^T[G_jw_j+\frac{1}{2}(H_j+λ)w_j^2]+γT\)

對於每個葉子結點j,將其從目標函數中單獨取出:

\(G_jw_j+\frac{1}{2}(H_j+λ)w_j^2\)

在樹結構固定的情況下,對上式求導並令其爲0,可得最優點和最優值爲:

$w_j^∗=−\frac{G_j}{H_j}+λ $

$L=−\frac{1}{2}∑_{j=1}^T \frac{G_j^2}{H_j+λ}+γT $

假設決策樹模型在某個結點進行了特徵分裂,分裂前的損失函數寫爲:

$L_{before}=−[\frac{(G_L+G_R)^2}{H_L+H_R+λ}]+γ $

分裂後的損失函數爲:

\(L_{after}=−\frac{1}{2}[ \frac{G_L^2}{H_L+λ} + \frac{G_R^2}{H_R+λ}]+2γ\)

分裂後的信息增益爲:

\(Gain=\frac{1}{2}[ \frac{G_L^2}{H_L+λ} + \frac{G_R^2}{H_R+λ}−\frac{(G_L+G_R)^2}{H_L+H_R+λ}]-γ\)

如果增益Gain>0,即分裂爲兩個葉子結點後,目標函數下降,則考慮此次分裂的結果。實際處理時需要遍歷所有特徵尋找最優分裂特徵。

以上就是XGBoost相對完整的數學推導過程,核心是通過損失函數展開到二階導數來進一步逼近真實損失。XGBoost的推導思路和流程簡化後如下圖所示。

image

三、XGBoost常見問題

https://zhuanlan.zhihu.com/p/81368182

1.介紹一下XGBoost的原理

  • XGBoost是基於GBDT的一種算法或者說工程實現。
  • GBDT是一種基於boosting集成思想的加法模型,訓練時採用前向分佈算法進行貪婪的學習,每次迭代都學習一棵CART樹來擬合之前 t-1 棵樹的預測結果與訓練樣本真實值的殘差。
  • XGBoost的基本思想和GBDT相同,但是做了一些優化,如默認的缺失值處理,加入了二階導數信息、正則項、列抽樣,並且可以並行計算等。

2.XGBoost和GBDT的不同點

  • GBDT是機器學習算法,XGBoost是該算法的工程實現
  • 在使用CART作爲基分類器時,XGBoost顯式地加入了正則項來控制模型的複雜度,有利於防止過擬合,從而提高模型的泛化能力。
  • GBDT在模型訓練時只是用了代價函數的一階導數信息,XGBoost對代價函數進行二階泰勒展開,可以同時使用一階和二階導數。(好處:相對於GBDT的一階泰勒展開,XGBoost採用二階泰勒展開,可以更爲精準的逼近真實的損失函數。需要注意的是,損失函數需要二階可導。)
  • 傳統的GBDT採用CART作爲基分類器,XGBoost支持多種類型的基分類器,比如線性分類器。
  • 傳統的GBDT在每輪迭代時使用全部的數據,XGBoost則採用了與隨機森林相似的策略,支持對數據進行列採樣
  • 傳統的GBDT沒有涉及對缺失值進行處理,XGBoost能夠自動學習出缺失值的處理策略
  • 特徵維度上的並行化。XGBoost預先將每個特徵按特徵值排好序,存儲爲塊結構,分裂結點時可以採用多線程並行查找每個特徵的最佳分割點,極大提升訓練速度。

3.XGBoost的並行是怎麼做的?

由於XGBoost是一種boosting算法,樹的訓練是串行的,不能並行。這裏的並行指的是特徵維度的並行。在訓練之前,每個特徵按特徵值對樣本進行預排序,並存儲爲Block結構,在後面查找特徵分割點時可以重複使用,而且特徵已經被存儲爲一個個block結構,那麼在尋找每個特徵的最佳分割點時,可以利用多線程對每個block並行計算。

4.XGBoost算法防止過擬合的方法有哪些?

  • 在目標函數中添加了正則化。葉子節點個數+葉子節點權重的L2正則化。
  • 列抽樣。訓練時只使用一部分的特徵。
  • 子採樣。每輪計算可以不使用全部樣本,類似bagging。
  • early stopping。如果經過固定的迭代次數後,並沒有在驗證集上改善性能,停止訓練過程。
  • shrinkage。調小學習率增加樹的數量,爲了給後面的訓練留出更多的空間。

5.使用XGBoost訓練模型時,如果過擬合了怎麼調參?

  • 控制模型的複雜度。包括max_depth,min_child_weight,gamma 等參數。
  • 增加隨機性,從而使得模型在訓練時對於噪音不敏感。包括subsample,colsample_bytree。
  • 減小learning rate,但需要同時增加estimator 參數。

6.XGBoost的正則項是什麼?

葉子節點個數葉子節點權重的L2正則

7.XGBoost爲什麼對缺失值不敏感?

一些涉及到對樣本距離的度量的模型,如SVM和KNN,如果缺失值處理不當,最終會導致模型預測效果很差。

樹模型對缺失值的敏感度低,大部分時候可以在數據缺失時時使用。原因就是,一棵樹中每個結點在分裂時,尋找的是某個特徵的最佳分裂點(特徵值),完全可以不考慮存在特徵值缺失的樣本,也就是說,如果某些樣本缺失的特徵值缺失,對尋找最佳分割點的影響不是很大。

另外,XGBoost還有一些處理缺失值的方法。

8.XGBoost怎麼處理缺失值?

這是XGBoost的一個優點。具體處理方法爲:

  • 在某列特徵上尋找分裂節點時,不會對缺失的樣本進行遍歷,只會對非缺失樣本上的特徵值進行遍歷,這樣減少了爲稀疏離散特徵尋找分裂節點的時間開銷。
  • 另外,爲了保證完備性,對於含有缺失值的樣本,會分別把它分配到左葉子節點和右葉子節點,然後再選擇分裂後增益最大的那個方向,作爲預測時特徵值缺失樣本的默認分支方向。
  • 如果訓練集中沒有缺失值,但是測試集中有,那麼默認將缺失值劃分到右葉子節點方向。

9.XGBoost中的一棵樹的停止生長條件

  • 當樹達到最大深度時,停止建樹,因爲樹的深度太深容易出現過擬合,這裏需要設置一個超參數max_depth。
  • 當新引入的一次分裂所帶來的增益Gain<0時,放棄當前的分裂。這是訓練損失和模型結構複雜度的博弈過程。
  • 當引入一次分裂後,重新計算新生成的左、右兩個葉子結點的樣本權重和。如果任一個葉子結點的樣本權重低於某一個閾值,也會放棄此次分裂。這涉及到一個超參數:最小樣本權重和,是指如果一個葉子節點包含的樣本數量太少也會放棄分裂,防止樹分的太細。

10.XGBoost可以做特徵選擇,它是如何評價特徵重要性的?

XGBoost中有三個參數可以用於評估特徵重要性:

  • weight :該特徵在所有樹中被用作分割樣本的總次數。
  • gain :該特徵在其出現過的所有樹中產生的平均增益。
  • cover :該特徵在其出現過的所有樹中的平均覆蓋範圍。覆蓋範圍這裏指的是一個特徵用作分割點後,其影響的樣本數量,即有多少樣本經過該特徵分割到兩個子節點。

11.隨機森林和GBDT的異同點

相同點:

  • 都是由多棵樹組成,最終的結果都是由多棵樹一起決定。

不同點:

  • 集成學習:RF屬於bagging思想,而GBDT是boosting思想。
  • 偏差-方差權衡:RF不斷的降低模型的方差,而GBDT不斷的降低模型的偏差。
  • 訓練樣本:RF每次迭代的樣本是從全部訓練集中有放回抽樣形成的,而GBDT每次使用全部樣本。
  • 並行性:RF的樹可以並行生成,而GBDT只能順序生成(需要等上一棵樹完全生成)。
  • 最終結果:RF最終是多棵樹進行多數表決(迴歸問題是取平均),而GBDT是加權融合。
  • 數據敏感性:RF對異常值不敏感,而GBDT對異常值比較敏感。
  • 泛化能力:RF不易過擬合,而GBDT容易過擬合。

12.XGBoost中如何對樹進行剪枝

  • 在目標函數中增加了正則項:使用葉子結點的數目和葉子結點權重的L2模的平方,控制樹的複雜度。
  • 在結點分裂時,定義了一個閾值,如果分裂後目標函數的增益小於該閾值,則不分裂。
  • 當引入一次分裂後,重新計算新生成的左、右兩個葉子結點的樣本權重和。如果任一個葉子結點的樣本權重低於某一個閾值(最小樣本權重和),也會放棄此次分裂。
  • XGBoost 先從頂到底建立樹直到最大深度,再從底到頂反向檢查是否有不滿足分裂條件的結點,進行剪枝。

13.XGBoost如何選擇最佳分裂點?

XGBoost在訓練前預先將特徵按照特徵值進行了排序,並存儲爲block結構,以後在結點分裂時可以重複使用該結構。

因此,可以採用特徵並行的方法利用多個線程分別計算每個特徵的最佳分割點,根據每次分裂後產生的增益,最終選擇增益最大的那個特徵的特徵值作爲最佳分裂點。如果在計算每個特徵的最佳分割點時,對每個樣本都進行遍歷,計算複雜度會很大,這種全局掃描的方法並不適用大數據的場景。XGBoost還提供了一種直方圖近似算法,對特徵排序後僅選擇常數個候選分裂位置作爲候選分裂點,極大提升了結點分裂時的計算效率。

14.XGBoost的延展性很好,怎麼理解?

可以有三個方面的延展性:

  • 基分類器:弱分類器可以支持CART決策樹,也可以支持LR和Linear。
  • 目標函數:支持自定義loss function,只需要其二階可導。因爲需要用二階泰勒展開,得到通用的目標函數形式。
  • 學習方法:Block結構支持並行化,支持 Out-of-core計算。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章