文章轉自公眾號【機器學習煉丹術】,關注回覆“煉丹”即可獲得海量免費學習資料哦!
[TOC]
1 作者前言
在2020年還在整理XGB的演算法,其實已經有點過時了。不過,主要是為了擴大知識面和應付面試嘛。現在的大資料競賽,XGB基本上已經全面被LGB模型取代了,這裡主要是學習一下Boost演算法。之前已經在其他博文中介紹了Adaboost演算法和Gradient-boost演算法,這篇文章講解一下XGBoost。
2 樹模型概述
XGB就是Extreme Gradient Boosting極限梯度提升模型。XGB簡單的說是**一組分類和迴歸樹(CART)**的組合。跟GBDT和Adaboost都有異曲同工之處。 【CART=classification adn regression trees】
這裡對於一個決策樹,如何分裂,如何選擇最優的分割點,其實就是一個搜尋的過程。搜尋怎麼分裂,才能讓目標函式最小。目標函式如下: \(Obj = Loss + \Omega\) $Obj$就是我們要最小化的優化函式,$Loss$就是這個CART模型的預測結果和真實值得損失。$\Omega$就是這個CART模型的複雜度,類似神經網路中的正則項。 【上面的公式就是一個抽象的概念。我們要知道的是:CART樹模型即要求預測儘可能準確,又要求樹模型不能過於複雜。】
對於迴歸問題,我們可以用均方差來作為Loss: \(Loss=\sum_i{(y_i-\hat{y_i})^2}\)
對於分類問題,用交叉熵是非常常見的,這裡用二值交叉熵作為例子: \(Loss = \sum_i{(y_ilog(\hat{y_i})+(1-y_i)log(\hat{y_i}))}\)
總之,這個Loss就是衡量模型預測準確度的損失。
下面看一下如何計算這個模型複雜度$\Omega$吧。 \(\Omega = \gamma T+\frac{1}{2} \lambda \sum^T_j{w_j}^2\)
$T$表示葉子節點的數量,$w_j$表示每個葉子節點上的權重(與葉子節點的樣本數量成正比)。
【這裡有點麻煩的在於,$w_j$是與每個葉子節點的樣本數量成正比,但是並非是樣本數量。這個$w_j$的求取,要依靠與對整個目標函式求導數,然後找到每個葉子節點的權重值$w_j$。】
3 XGB vs GBDT
其實說了這麼多,感覺XGB和GDBT好像區別不大啊?那是因為說了這麼多還沒開始說XGB呢!之前都是講樹模型的通用概念的。下面講解XGB~整理一下網上有的說法,再加上自己的理解。有錯誤請指出評論,謝謝!
3.1 區別1:自帶正則項
GDBT中,只是讓新的弱分類器來擬合負梯度,那擬合多少棵樹才算好呢?不知道。XGB的優化函式中,有一個$\Omega$複雜度。這個複雜度不是某一課CART的複雜度,而是XGB中所有CART的總複雜度。可想而知,每多一顆CART,這個複雜度就會增加他的懲罰力度,當損失下降小於複雜度上升的時候,XGB就停止了。
3.2 區別2:有二階導數資訊
GBDT中新的CART擬合的是負梯度,也就是一階導數。而在XGB會考慮二階導數的資訊。
這裡簡單推導一下XGB如何用上二階導數的資訊的:
之前我們得到了XGB的優化函式: \(Obj = Loss + \Omega\)
然後我們把Loss和Omega寫的更具體一點: \(Obj = \sum_i^n{Loss(y_i,\hat{y}_i^t)}+\sum_j^t{\Omega(cart_j)}\)
- $\hat{y_i^t}$表示總共有t個CART弱分類器,然後t個弱分類器給出樣本i的估計值就。
- $y_i$第i個樣本的真實值;
- $\Omega(cart_j)$第j個CART模型的複雜度。
我們現在要求取第t個CART模型的優化函式,所以目前我們只是知道前面t-1的模型。所以我們得到: \(\hat{y}_i^t = \hat{y}_i^{t-1}+f_t(x_i)\) t個CART模型的預測,等於前面t-1個CART模型的預測加上第t個模型的預測。
所以可以得到: \(\sum_i^n{Loss(y_i,\hat{y}_i^t)}=\sum_i^n{Loss(y_i,\hat{y}_i^{t-1}+f_t(x_i))}\) 這裡考慮一下特勒展開: \(f(x+\Delta x)\approx f(x)+f'(x)\Delta x + \frac{1}{2} f''(x)\Delta x^2\)
如何把泰勒公式帶入呢? ${Loss(y_i,\hat_it)}$中的$y_i$其實就是常數,不是變數 所以其實這個是可以看成$Loss(\hat_it)$,也就是: \(Loss(\hat{y}_i^{t-1}+f_t(x_i))\)
帶入泰勒公式,把$f_t(x_i)\(看成\)\Delta x$: \(Loss(\hat{y}_i^{t-1}+f_t(x_i))=Loss(\hat{y}_i^{t-1})+Loss'(\hat{y}_i^{t-1})f_t(x_i)+\frac{1}{2}Loss''(\hat{y}_i^{t-1})(f_t(x_i))^2\)
- 在很多的文章中,會用$g_i=Loss'(\hat_i^)$,以及$h_i=Loss''(\hat_i^)$來表示函式的一階導數和二階導數。
把泰勒展開的東西帶回到最開始的優化函式中,刪除掉常數項$Loss(\hat_i^)$(這個與第t個CART模型無關呀)以及前面t-1個模型的複雜度,可以得到第t個CART的優化函式: \(Obj^t \approx \sum_i^n{[g_i f_t(x_i)+\frac{1}{2}h_i(f_t(x_i))^2}]+{\Omega(cart_t)}\)
【所以XGB用到了二階導數的資訊,而GBDT只用了一階的梯度】
3.3 區別3:列抽樣
XGB借鑑了隨機森林的做法,不僅僅支援樣本抽樣,還支援特徵抽樣(列抽樣),不僅可以降低過擬合,還可以減少計算。(但是這一點我個人存疑,感覺這個只是程式碼給出的功能,並不算是XGB本身演算法相對GBDT的優勢。因為XGB和GBDT明明都可以用列抽樣的方法。總之,最關鍵的區別是二階導數那個和引入正則項)
4 XGB為什麼用二階導
這個是一個關於XGB的面試進階題。第一次看到這個問題的時候,一臉懵逼。
【先說自己總結的答案】
- 使用了二階導數的資訊,加快了收斂速度。
- 減少了計算量。
4.1 為什麼減少了計算量
這個比較理解,就先從這個開始解釋。 在GBDT中,最花費時間的就是計算分裂點,選擇哪個特徵,在哪個分割點進行分裂可以得到最小的loss。假設有5個特徵,每個特徵有100個潛在分割點,那麼分類一次需要計算500次。
$loss(y,\hatt)$像之前一樣,寫成之前所有已經訓練完成的弱分類器和正在訓練的分類器$loss(y,\hat+f_t(x))$ 如果計算這個損失的話,我們需要計算500次的 \(loss(y,\hat{y}^{t-1}+f_t(x))\) 但是假設使用泰勒展開得到: \(loss(\hat{y}^{t-1})+g*f_t(x)+\frac{1}{2}h(f_t(x))^2\) 其中的$loss(\hat^)$,\(g\),$h$都是僅僅與之前已經訓練完成的決策樹相關,所以就是常數,所以是可以在500次的計算中共享,計算一次足以。
4.2 為什麼加快收斂速度
這裡要回到泰勒展開那裡: \(f(x+\Delta x) = f(x) + g(x) * \Delta x + \frac{1}{2} h(x) (\Delta x)^2\) 這個式子其實就可以看成是$F(\Delta x)$,因為$x$可以看成一個常數。我們希望$F(\Delta x)\(最小(也就是損失最小),所以我們對\)\Delta x$求導數: \(F'(\Delta x)=g(x)+h(x)\Delta x=0\) 導數為0,則是極小值(預設是凸函式) \(\Delta x=-\frac{g(x)}{h(x)}\),也就是說,更新的步長其實就是一階導數除以二階導數。
瞭解最優化演算法的朋友應該可以意識到,這個其實是跟牛頓法等價的。XGB每一次訓練一個新的基模型,其實就是再使用牛頓法來對損失函式進行最小值的優化與更新。
【小總結】 因此我個人認為,使用了二階資訊的XGB比使用了一階資訊的GBDT收斂速度快的原因,可以用牛頓法比梯度下降法收斂快來解釋。
【為什麼牛頓法收斂速度快】 其實這一塊我有些解釋不清楚了,因為我最優化演算法學的也不精(好像突然發現找不到工作的原因了2333)。能給出的是一個比較通俗的解釋: 從本質上去看,牛頓法是二階收斂,梯度下降是一階收斂,所以牛頓法就更快。如果更通俗地說的話,比如你想找一條最短的路徑走到一個盆地的最底部,梯度下降法每次只從你當前所處位置選一個坡度最大的方向走一步,牛頓法在選擇方向時,不僅會考慮坡度是否夠大,還會考慮你走了一步之後,坡度是否會變得更大。
5 牛頓法
這裡簡單介紹一下牛頓法是什麼。畢竟有的朋友可能沒學過,或者學過像我一樣忘記了。
【牛頓法的目的】 求解一個函式的根,也就是這個函式與x座標軸的交點。
這裡有一個三次曲線,我們初始點在A位置,然後做A位置的切線,可以發現這個切線相交於x軸。 然後這個焦點做一個平行於y軸的線,交於B點,然後B點做切線,然後交於x軸,然後......
然後迭代到C點
慢慢的,就逼近三次函式與x軸的交點,也就是三次函式等於0的根了。
【數學算式】 $x_n$點的切線方程: \(f(x_n)+f'(x_n)(x-x_n)=0\) 所以很簡單得到: \(x_{n+1}=x_n-\frac{f(x_n)}{f'(x_n)}\) 【為什麼這裡只用到了一階資訊?】 因為這裡的目的是求取一個函式的根,也就是函式等於0的根。我們在最優化問題中,求解的是一個函式的極小值,這就要求求取這個函式的導數等於0的根,所以在最優化問題中,是一個二階導數優化方法。
寫了4000字,太累了。歡迎大家加好友交流。