XGBoost的實現,我以爲主要仍是在於對GBDT的改良上。對於GBDT仍是不太熟悉的朋友,請看我這一篇文章《GBDT》。我我的認爲這二者區別主要仍是在於細節上,理解了GBDT我認爲就差很少等於理解了XGBoost。算法
我重點比較一下XGBoost與GBDT兩種算法的不一樣:機器學習
最基本的差距就在於XGBoost比GBDT多了兩項泰勒展開式。具體這個泰勒展開式是怎麼獲得的,是對於什麼展開的呢?咱們看:
XGBoost算法能夠當作是由K棵樹組成的加法模型:函數
其中F爲全部樹組成的函數空間(這裏的迴歸樹也就是一個分段函數,不一樣分段的不一樣取值就構成了一顆樹),與通常機器學習算法不一樣的是,加法模型不是學習d維空間的權重,而是直接學習決策樹的集合。
上述加法模型的目標函數定義爲:post
其中Ω表示決策樹的複雜度,那麼該如何定義樹的複雜度呢?好比,能夠考慮樹的節點數量、樹的深度或者葉子節點所對應的分數的L2範數等等。
如何來學習加法模型呢?
解這一優化問題,能夠用前向分佈算法(forward stagewise algorithm)。有了以前GBDT的基礎,咱們知道,加法模型的學習器每次都用函數來擬合上一棵樹沒有擬合完整的殘差,最後將這些殘差所有加起來就會獲得對於目標完整的預測,這也叫作Boosting。具體地,咱們從一個常量預測開始,每次學習一個新的函數,過程以下:
學習
這個公式看起來仍是比較拗口,想要理解的話建議看我以前的文章《GBDT》,瞭解了工做模式這公式就好理解了。優化
這就會產生一個新的問題,那個新加入的函數f到底怎麼獲得的呢?這個原則仍是最小化目標函數。咱們能夠將咱們的目標函數寫爲:3d
咱們再用平方偏差來衡量咱們的損失函數:cdn
其中 就是咱們所謂的殘差(residual)。咱們每一次使用平方函數的時候,算法都是爲了擬合這個殘差。
可能有的朋友對於泰勒公式不是很是熟悉,我將基本的泰勒公式用法寫在這:blog
咱們都知道,泰勒級數展開實際上是有無窮多項的,在無窮多項形式裏是嚴格等於,這裏咱們暫且只取了前三項省略了後面,因此就是約等於。
那有了泰勒公式的基礎,咱們將前面的目標函數變式能夠轉化爲:遞歸
其中,g與h分別是損失函數的一階偏導數和二階偏導數,具體數學形式以下:
咱們也能夠將常數項直接去掉,並不會影響,那就使得目標函數是這個樣子:
因爲要學習的函數僅僅依賴於目標函數,從「去掉常數項的目標函數」能夠看出只需爲學習任務定義好損失函數,併爲每一個訓練樣本計算出損失函數的一階導數和二階導數,經過在訓練樣本集上最小化目標函數便可求得每步要學習的函數,從而根據加法模型可得最終要學習的模型。
就簡單提一句GBDT與XGBoost的區別,明顯能夠看出,GBDT沒有采用二次泰勒展開,這個看似很簡單的區別,實際上帶來更快的擬合,也大大縮減了生成樹的規模,減小了運行時間。
咱們使用損失函數優化是爲了不欠擬合,而使用正則化項就是爲了不過擬合。正則化項與損失函數共同組成了咱們的目標函數。XGBoost比GBDT多添加了以樹複雜度構成的正則化項,也是XGBoost實際表現更爲優秀的緣由之一
何爲正則化項?正則化項的做用是什麼?
咱們都知道,咱們在優化目標函數的時候,老是但願它更加的「小」,也就是優化通常是最小化的意思。如今咱們若是給目標函數加入一個變量的平方,那麼若是這個變量一旦變大,那麼目標函數爲了「最小化」,必定很不喜歡這個變量變大的事實,選擇的時候就會刻意避開會使變量變大的路徑。這大概就是正則化的簡單解釋了。在XGBoost中,咱們是將樹的複雜度做爲正則項加入,那麼優化器在工做的時候,會盡可能不讓這個樹更加複雜,也就達到咱們的效果。
咱們假設XGBoost決策樹的葉子節點個數爲T,該決策樹是由全部葉子節點對應的值組成的向量w,以及一個把特徵向量映射到葉子節點索引(Index)的函數 組成的,咱們將樹能夠寫成:
,咱們也能夠將決策樹的複雜度定義成正則項:
則目標函數咱們能夠寫成:
用G與H代換一下原來的式子,咱們就獲得了簡化後的式子:
假設樹的結構是固定的,即函數q(x)爲固定的,令目標函數的一階導數爲0,則能夠求出葉子節點j對應的值爲:
因而在這種條件下,目標函數的值就變成了:
爲何要計算這兩個值呢?
是爲了給你們描述單棵決策樹的生成過程:
樹結構數量是無窮的,因此實際上咱們不可能枚舉全部可能的樹結構。一般狀況下,咱們採用貪心策略來生成決策樹的每一個節點。
咱們來看看這個貪心算法是怎麼工做的:
如何計算每次分裂的收益呢?假設當前節點記爲C,分裂以後左孩子節點記爲L,右孩子節點記爲R,則該分裂得到的收益定義爲當前節點的目標函數值減去左右兩個孩子節點的目標函數值之和:Gain=ObjC-ObjL-ObjR,具體地,根據目標函數值公式可得: