1.CART樹回顧
在正式講Xgboost之前,我們先回顧一下CART樹。
CART樹的生成過程,就是遞歸構建二叉樹的過程,本質上是在某個特徵維度對樣本空間進行劃分。這種空間劃分是一種NP Hard問題,因此一般都是用啓發式的方式去求解,即求某個特徵j的且分點s,使得
j,smin⎣⎡c1minxi∈R1(j,s)∑(yi−c1)2+c2minxi∈R2(j,s)∑(yi−c2)2⎦⎤
2.XGBoost葉子節點取值推導
XGBoost的大體思路跟GBDT一樣,也是通過不斷進行特徵分裂添加樹,來學習一個新的弱學習器,來擬合上次預測結果的殘差。
首先來看一下XGBoost的損失函數
L(ϕ)=i∑l(yi,y^i)+k∑Ω(fk),其中Ω(fk)=γT+21λ∣∣w∣∣2
很容易可以看出來
i∑l(yi,y^i)是代表預測值與真實值的偏差,而k∑Ω(fk)爲正則項。
其中,yi爲樣本的真實值,y^i爲預測值。fk表示第k棵樹,γ爲葉子樹的正則項,起到剪枝的作用,T爲樹的葉子節點個數,w爲葉子節點的分數,λ爲葉子節點分數的正則項,起到防止過擬合的作用。
前面樹系列的文章提到過很多次,boost系列算法的核心思想是用新生成的樹擬合上次預測的殘差(對於GBDT來說是上次預測的負梯度方向)。生成第t棵樹後,預測值可以寫爲
y^i=y^it−1+ft(x)
此時,損失函數可以表示爲
Lt=i=1∑l(yit,y^it−1)+ft(xi)+Ω(ft)
於是我們要找一個ft讓損失函數最小。對上面的式子進行泰勒展開
L(t)≃i=1∑n[l(yi,y^(t−1))+gift(xi)+21hift2(xi)]+Ω(ft)
其中,
gi=∂y^it−1∂l(yi,y^it−1)
hi=∂(y^it−1)2∂2l(yi,y^it−1)
其中gi,hi的含義可以按如下方式理解
假設目前已經有t-1棵數,這t-1棵樹組成的模型對第i個訓練樣本有一個預測值y^i,y^i與真實值yi肯定有差距,這個差距可以用l(yi,y^i)這個損失函數來衡量,所以此處的gi與hi就是對於該損失函數的一階導和二階導。(參考文獻1)
搞定了前面的損失函數部分,接下來再觀察一下正則項
Ω(ft)=γT+21λj=1∑Twj2
對於上面的正則項,我們最簡單的理解方式爲:要使模型儘可能簡單,那就是葉子節點的個數T要小,同時葉子節點上的值也儘可能小。
因爲前t-1棵樹的預測分數與y的殘差對目標函數優化不影響, 可以直接去掉,所以損失函數可以寫成
L(t)≃i=1∑n[gift(xi)+21hift2(xi)]+Ω(ft)
上面式子的含義是將每個樣本的損失函數相加,而每個樣本最終都會落到一個葉子節點上,所以我們可以將所有同一個葉子結點的樣本重組起來
L^(t)=i=1∑n[gift(xi)+21htft2(xi)]+Ω(ft)=i=1∑n[gift(xi)+21htft2(xi)]+γT+21λj=1∑Twj2=j=1∑T[(i∈Ij∑gi)wj+21(i∈Ij∑hi+λ)wj2]+γT=21j=1∑T(Hj+λ)(wj+Hj+λGj)2+γT−21j=1∑THj+λGj2
其中,Gj=∑i∈Ijgi是落入葉子節點i所有樣本一階梯度的總和,而Hj=∑i∈Ijhi是落入葉子節點i所有樣本二階梯度的總和。
基於中學數學的原理,我們可以得知:
當
wj∗=−Hj+λGj
時,損失函數最小。此時最終的損失函數大小爲
L^∗=−21j=1∑THj+λGj2+γT
3.與牛頓法的關係
上面我們推導過程中,用到了二階導數。而常見的基於二階導數的優化方法就是牛頓法,下面我們看看與牛頓法的關係。
假設有一個函數f(x)二階可微,我們對其進行泰勒展開到二階,有
f(x)=f(xk)+f′(xk)(x−xk)+f′′(xk)(x−xk)2
上面的式子對x求導,並令導數等於0
f′(xk)+f′′(xk)(x−xk)=0
可以得到x的迭代公式爲
x=xk−f′′(xk)f′(xk)
這就是牛頓法的迭代公式。
對比一下葉子節點的取值方式
wj∗=−Hj+λGj
與牛頓法唯一的區別在於,分母上二階導多了一個正則項λ,形式上完全一致,就是一階導除以二階導,與牛頓法的形式完全一致。
4.XGBoost的樹分裂方式
上面推導了這麼一大串,都是在分析葉子節點怎麼取值。提升樹系列的算法,還有很重要的一點是樹的分裂方式。
首先我們回顧一下其他算法比如GBDT是怎麼進行分裂的。標準的做法是選擇MSE作爲損失函數,採用啓發式的方式來選擇某個特徵j的切分點s進行分裂。這個分裂的過程,並不一定總與損失函數相關。比如在分類樹中,我們一般都會用對數損失函數(交叉熵)來評估模型的最終效果,這個時候樹分裂的結果與損失函數就沒有直接的關係。
XGBoost的樹分裂是直接與損失函數相關的。在分裂的時候,會計算損失函數的增益Gain
Gain=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−γ
上面這個式子其實很容易理解
HL+HR+λ(GL+GR)2是分裂前最終的損失函數值,而
HL+λGL2,HR+λGR2
分別爲分裂後的左右子樹的損失函數值
那樹進行分裂的時候,自然希望損失函數減少得越多越好。
前面我們推導出了損失函數最終的表達式
L^∗=−21j=1∑THj+λGj2+γT
那我們想要的結果就是分列前的損失函數減去分裂後的損失函數,差值最大,注意前面的負號,最後的分裂準則爲
max(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)
5.XGBoost的各種Tricks總結
防止過擬合方法:
1.加入了正則項,對葉子節點數量,葉子節點分數加入了正則懲罰項。
2.加入了學習率,減少了單棵樹影響,給後面樹的優化留了更多空間。
3.列採樣(特徵採樣),與隨機森林類似,不僅來帶來更好的效果,還可以提高運行速度。
缺失值的處理
在別的算法中,一般會使用中位數,均值或者兩者進行融合計算的方式去處理缺失值。但是xgboost能處理缺失值,模型允許缺失值存在。
在尋找分裂點的時候,不對該特徵缺失的樣本進行遍歷,只遍歷該特徵有的樣。具體實現時,將該特徵值缺失的樣本分別分配到左葉子節點與右葉子節點,分別計算增益,然後選擇增益較大的方向進行分裂即可。如果訓練樣本中沒有缺失值,而預測時有缺失,默認將缺失值劃分到右子節點。
分裂點的選擇
並不把所有特徵值間的間隔點作爲候選分裂點,而是用分位數的方法將其作爲分裂的候選集。
並行處理
XGBoost中雖然樹之間是串行關係,但是同層級的節點可以並行。對於某個節點,節點內選擇最佳分裂點與計算分裂點的增益是可以並行的。
基學習器(弱學習器)
傳統的GBDT與CART樹作爲基分類器,XGBoost不僅支持CART樹,還支持線性分類器,這個時候xgboost就相當於帶L1與L2正則項的邏輯斯蒂迴歸(分類問題)或者線性迴歸(迴歸問題)。
6.XGBoost 與GBDT的對比
主要的區別其實就是上面的Tricks。
參考文獻
1.https://www.jianshu.com/p/ac1c12f3fba1