XGBoost算法原理及代碼(代碼持續更新。。。)

前言:有監督算法的組成:模型,參數和目標函數
(1)模型:給入指定的Xi如何去預測Yi,姑且認爲是一個Y關於X的函數吧,如線性迴歸Y=∑Wi*Xi
(2)參數:就是指係數W
(3)目標函數(損失+正則):目標函數的作用是找到比較好的參數W,來更好地預測,基本形式如下:
這裏寫圖片描述
常見的誤差函數有:
(1)平方誤差:
這裏寫圖片描述
(2)logistic誤差函數:
這裏寫圖片描述
正則化有L2和L1正則化(其區別可以看我另一篇博客)
XGBoost基本原理:實質上就是迴歸樹(也稱分類迴歸樹,一下簡稱CART)的迭代算法。每迭代一次生成一顆CART,然後作者對算法的優化做了很多事情,下面會具體講到,首先來講一下CART舉個經典的例子:
這裏寫圖片描述
如圖所示,我們需要判斷一個人是否喜歡打遊戲,已知age,gender,occupation等信息,假如只用一顆CART,如圖所示的分裂方式,最終一個樣本會被分到一個葉子結點中,對應着該葉子結點的值,對於二分類問題,該值通過sigmoid函數轉化爲概率,該概率表示分類爲1的概率;對於迴歸問題,該值就是預測值。(單個樹模型不考慮多分類問題)
(2)Tree Ensemble:多顆CART迭代
這裏寫圖片描述
如圖所示,對於一個樣本,每棵樹都會預測出一個結果(暫時稱這個結果爲分數),對於二分類問題來說,將所有樹的分數相加,經過sigmoid轉換,得到預測爲1的概率;對於迴歸問題,將所有樹的分數相加,得到的就是預測值。
很明顯,xgboost的結果輸出方式就是第二種,下面具體講一下原理
xgboost目標函數形式爲(training loss+正則項):
這裏寫圖片描述
模型學習:additive training
模型訓練過程:
在這裏插入圖片描述
還有一個問題,我們怎麼加入f,以什麼樣的標準呢?我們的準則就是:選取一個f使得目標函數儘量最大的降低
這裏寫圖片描述
可以把上面的公式寫的具體一點:實際上就是把公式拆開,一步步來,很簡單,
這裏寫圖片描述
注:殘差實際上就是每一輪的預測值和真實值的差,殘差的使用面挺廣的,也很有效,如ResNet在2015年就火了一把
有時候使用的不是平方誤差,我們就用泰勒展開來近似目標函數,方便計算:
這裏寫圖片描述
不考慮常數項,仔細看公式發現,中括號裏面的表示誤差函數,我們發現,好像就是在前一個誤差函數下加上了一個一階導數和二階導數(實際上這就是泰勒公式的妙處)
這裏寫圖片描述
這樣可以得到什麼呢?是不是意味着,我們前面得到了t-1個函數模型(樹),我們要構建第t個模型(樹)時,是不是隻要求前t-1函數的一階和二階導數和前t-1的函數模型的乘積即可。這樣是不是意味着我們不僅可以用這個模型來做分類,還可以迴歸等,增強了泛化性。
(4)樹的複雜度:
前面我們討論了目標函數的訓練誤差部分,接下來討論如何定義樹的複雜度。我們先對f的定義做一下細化,把樹拆分成結構部分q和葉子權重部分w。結構函數q把輸入映射到葉子的索引號上去,而w給定了每個索引號對應的葉子分數
這裏寫圖片描述
我們定義一棵樹的複雜度:這個複雜度包含了一棵樹的節點數和每個葉子節點輸出分數的模的平方(L2)。當然,不止這一種定義,如下:
這裏寫圖片描述
看這個圖應該還是比較好理解的
(5)關鍵步驟
我們可以對目標函數進行如下改寫,其中I被定義爲每個葉子節點上樣本集合:
這裏寫圖片描述
注:i代表第i個樣本,j代表第j個葉子節點,整個代表在所有葉子節點上的樣本的集合,集合的元素是單個葉子節點的樣本的集合
這裏寫圖片描述
上式包含了T(模型/樹的個數)個相互獨立的單變量二次函數,我們可以定義
這裏寫圖片描述
那麼目標函數又可以改寫:只把w看成未知變量,假設樹的結構我們知道
這裏寫圖片描述
有了這個目標函數,我們可以很容易求w的最優解,直接對w求導
這裏寫圖片描述
(6)打分函數舉例(具體的表述待以後更新,樓主也不是很明白)
Obj代表了當我們指定一個樹的結構的時候,我們在目標上面最多減少多少,
這裏寫圖片描述
注:因爲目標函數實際上是loss function,目的是爲了逼近真實值,這裏的分數就是Obj,實際上就是loss,當然是越小越好,這裏的分數實際上每個樹的評分
(7)枚舉所有不同樹結構的貪心算法
我們不斷枚舉樹的結構,利用這個打分函數來尋找最優樹,加入到我們的模型中,不斷重複這個操作。不過這種枚舉操作不太可行,所以常用貪心算法。每一次嘗試去對已有的葉子加入一個分割。對於一個具體的分割方案,我們可以獲得的增益可以由如下公式計算
這裏寫圖片描述
對於每次擴展,我們還是要枚舉所有可能的分割方案,如何高效地枚舉所有的分割呢?我假設我們要枚舉所有 x<a 這樣的條件,對於某個特定的分割a我們要計算a左邊和右邊的導數和。
這裏寫圖片描述
我們可以發現對於所有的aa,我們只要做一遍從左到右的掃描就可以枚舉出所有分割的梯度和GL和GR。然後用上面的公式計算每個分割方案的分數就可以了。
觀察這個目標函數,大家會發現第二個值得注意的事情就是引入分割不一定會使得情況變好,因爲我們有一個引入新葉子的懲罰項。優化這個目標對應了樹的剪枝, 當引入的分割帶來的增益小於一個閥值的時候,我們可以剪掉這個分割。大家可以發現,當我們正式地推導目標的時候,像計算分數和剪枝這樣的策略都會自然地出現,而不再是一種因爲heuristic而進行的操作了。
講到這裏文章進入了尾聲,雖然有些長,希望對大家有所幫助,這篇文章介紹瞭如何通過目標函數優化的方法比較嚴格地推導出boosted tree的學習。因爲有這樣一般的推導,得到的算法可以直接應用到迴歸,分類排序等各個應用場景中去。
centos系統下xgboost,python安裝:
http://xgboost.readthedocs.io/en/latest/build.html#python-package-installation
參考鏈接:
1.XGBoost 與 Boosted Tree:http://www.52cs.org/?p=429

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章