一步一步理解GB、GBDT、xgboost
GBDT和xgboost在競賽和工業(yè)界使用都非常頻繁,能有效的應(yīng)用到分類、回歸、排序問題,雖然使用起來不難,但是要能完整的理解還是有一點(diǎn)麻煩的。本文嘗試一步一步梳理GB、GBDT、xgboost,它們之間有非常緊密的聯(lián)系,GBDT是以決策樹(CART)為基學(xué)習(xí)器的GB算法,xgboost擴(kuò)展和改進(jìn)了GDBT,xgboost算法更快,準(zhǔn)確率也相對高一些。? ??
1.?Gradient boosting(GB)
? ? ? 機(jī)器學(xué)習(xí)中的學(xué)習(xí)算法的目標(biāo)是為了優(yōu)化或者說最小化loss Function, Gradient boosting的思想是迭代生多個(gè)(M個(gè))弱的模型,然后將每個(gè)弱模型的預(yù)測結(jié)果相加,后面的模型Fm+1(x)基于前面學(xué)習(xí)模型的Fm(x)的效果生成的,關(guān)系如下:
? ? ?
? ? ? GB算法的思想很簡單,關(guān)鍵是怎么生成h(x)?
? ? ? 如果目標(biāo)函數(shù)是回歸問題的均方誤差,很容易想到最理想的h(x)應(yīng)該是能夠完全擬合?,這就是常說基于殘差的學(xué)習(xí)。殘差學(xué)習(xí)在回歸問題中可以很好的使用,但是為了一般性(分類,排序問題),實(shí)際中往往是基于loss Function 在函數(shù)空間的的負(fù)梯度學(xué)習(xí),對于回歸問題殘差和負(fù)梯度也是相同的。中的f,不要理解為傳統(tǒng)意義上的函數(shù),而是一個(gè)函數(shù)向量,向量中元素的個(gè)數(shù)與訓(xùn)練樣本的個(gè)數(shù)相同,因此基于Loss Function函數(shù)空間的負(fù)梯度的學(xué)習(xí)也稱為“偽殘差”。
GB算法的步驟:
1.初始化模型為常數(shù)值:
2.迭代生成M個(gè)基學(xué)習(xí)器
1.計(jì)算偽殘差
2.基于生成基學(xué)習(xí)器
3.計(jì)算最優(yōu)的
? ? ? 4.更新模型
?2. Gradient boosting Decision Tree(GBDT)
GB算法中最典型的基學(xué)習(xí)器是決策樹,尤其是CART,正如名字的含義,GBDT是GB和DT的結(jié)合。要注意的是這里的決策樹是回歸樹,GBDT中的決策樹是個(gè)弱模型,深度較小一般不會超過5,葉子節(jié)點(diǎn)的數(shù)量也不會超過10,對于生成的每棵決策樹乘上比較小的縮減系數(shù)(學(xué)習(xí)率<0.1),有些GBDT的實(shí)現(xiàn)加入了隨機(jī)抽樣(subsample 0.5<=f <=0.8)提高模型的泛化能力。通過交叉驗(yàn)證的方法選擇最優(yōu)的參數(shù)。因此GBDT實(shí)際的核心問題變成怎么基于使用CART回歸樹生成?
CART分類樹在很多書籍和資料中介紹比較多,但是再次強(qiáng)調(diào)GDBT中使用的是回歸樹。作為對比,先說分類樹,我們知道CART是二叉樹,CART分類樹在每次分枝時(shí),是窮舉每一個(gè)feature的每一個(gè)閾值,根據(jù)GINI系數(shù)找到使不純性降低最大的的feature以及其閥值,然后按照feature<=閾值,和feature>閾值分成的兩個(gè)分枝,每個(gè)分支包含符合分支條件的樣本。用同樣方法繼續(xù)分枝直到該分支下的所有樣本都屬于統(tǒng)一類別,或達(dá)到預(yù)設(shè)的終止條件,若最終葉子節(jié)點(diǎn)中的類別不唯一,則以多數(shù)人的類別作為該葉子節(jié)點(diǎn)的性別。回歸樹總體流程也是類似,不過在每個(gè)節(jié)點(diǎn)(不一定是葉子節(jié)點(diǎn))都會得一個(gè)預(yù)測值,以年齡為例,該預(yù)測值等于屬于這個(gè)節(jié)點(diǎn)的所有人年齡的平均值。分枝時(shí)窮舉每一個(gè)feature的每個(gè)閾值找最好的分割點(diǎn),但衡量最好的標(biāo)準(zhǔn)不再是GINI系數(shù),而是最小化均方差--即(每個(gè)人的年齡-預(yù)測年齡)^2 的總和 / N,或者說是每個(gè)人的預(yù)測誤差平方和 除以 N。這很好理解,被預(yù)測出錯(cuò)的人數(shù)越多,錯(cuò)的越離譜,均方差就越大,通過最小化均方差能夠找到最靠譜的分枝依據(jù)。分枝直到每個(gè)葉子節(jié)點(diǎn)上人的年齡都唯一(這太難了)或者達(dá)到預(yù)設(shè)的終止條件(如葉子個(gè)數(shù)上限),若最終葉子節(jié)點(diǎn)上人的年齡不唯一,則以該節(jié)點(diǎn)上所有人的平均年齡做為該葉子節(jié)點(diǎn)的預(yù)測年齡。
3. Xgboost
Xgboost是GB算法的高效實(shí)現(xiàn),xgboost中的基學(xué)習(xí)器除了可以是CART(gbtree)也可以是線性分類器(gblinear)。下面所有的內(nèi)容來自原始paper,包括公式。
(1).?xgboost在目標(biāo)函數(shù)中顯示的加上了正則化項(xiàng),基學(xué)習(xí)為CART時(shí),正則化項(xiàng)與樹的葉子節(jié)點(diǎn)的數(shù)量T和葉子節(jié)點(diǎn)的值有關(guān)。
(2). GB中使用Loss Function對f(x)的一階導(dǎo)數(shù)計(jì)算出偽殘差用于學(xué)習(xí)生成fm(x),xgboost不僅使用到了一階導(dǎo)數(shù),還使用二階導(dǎo)數(shù)。
第t次的loss:
對上式做二階泰勒展開:g為一階導(dǎo)數(shù),h為二階導(dǎo)數(shù)
(3). 上面提到CART回歸樹中尋找最佳分割點(diǎn)的衡量標(biāo)準(zhǔn)是最小化均方差,xgboost尋找分割點(diǎn)的標(biāo)準(zhǔn)是最大化,lamda,gama與正則化項(xiàng)相關(guān)
? xgboost算法的步驟和GB基本相同,都是首先初始化為一個(gè)常數(shù),gb是根據(jù)一階導(dǎo)數(shù)ri,xgboost是根據(jù)一階導(dǎo)數(shù)gi和二階導(dǎo)數(shù)hi,迭代生成基學(xué)習(xí)器,相加更新學(xué)習(xí)器。
xgboost與gdbt除了上述三點(diǎn)的不同,xgboost在實(shí)現(xiàn)時(shí)還做了許多優(yōu)化:
- 在尋找最佳分割點(diǎn)時(shí),考慮傳統(tǒng)的枚舉每個(gè)特征的所有可能分割點(diǎn)的貪心法效率太低,xgboost實(shí)現(xiàn)了一種近似的算法。大致的思想是根據(jù)百分位法列舉幾個(gè)可能成為分割點(diǎn)的候選者,然后從候選者中根據(jù)上面求分割點(diǎn)的公式計(jì)算找出最佳的分割點(diǎn)。
- xgboost考慮了訓(xùn)練數(shù)據(jù)為稀疏值的情況,可以為缺失值或者指定的值指定分支的默認(rèn)方向,這能大大提升算法的效率,paper提到50倍。
- 特征列排序后以塊的形式存儲在內(nèi)存中,在迭代中可以重復(fù)使用;雖然boosting算法迭代必須串行,但是在處理每個(gè)特征列時(shí)可以做到并行。
- 按照特征列方式存儲能優(yōu)化尋找最佳的分割點(diǎn),但是當(dāng)以行計(jì)算梯度數(shù)據(jù)時(shí)會導(dǎo)致內(nèi)存的不連續(xù)訪問,嚴(yán)重時(shí)會導(dǎo)致cache miss,降低算法效率。paper中提到,可先將數(shù)據(jù)收集到線程內(nèi)部的buffer,然后再計(jì)算,提高算法的效率。
- xgboost 還考慮了當(dāng)數(shù)據(jù)量比較大,內(nèi)存不夠時(shí)怎么有效的使用磁盤,主要是結(jié)合多線程、數(shù)據(jù)壓縮、分片的方法,盡可能的提高算法的效率。
? 參考資料:
1.?維基百科 Gradient boosting
2.?XGBoost: A Scalable Tree Boosting System
3.?陳天奇的slides
4.?xgboost導(dǎo)讀和實(shí)戰(zhàn).pdf
總結(jié)
以上是生活随笔為你收集整理的一步一步理解GB、GBDT、xgboost的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring boot项目整合Hadoo
- 下一篇: xgboost原理及应用