1. 程式人生 > >我理解的GBDT跟XGBOOST

我理解的GBDT跟XGBOOST

面試的時候被問了太多GBDT跟XGBOOST的原理問題,網上推導公式的帖子已經很多很完善了,把自己在面試過程中的一些思路和對模型的理解,簡單的寫一寫,拋磚引玉,有不合適的還請各位指出。

個人建議,可以先看一下週志華那本機器學習的整合模型那一個章節,裡面有boosting演算法(包括GBDT、XGBOOST、ADABOOST等)跟bagging演算法(比如隨機森林)的區分:

Boosting跟bagging簡單來講,boosting就是每次把所有樣本拿來運算,然後每一輪運算都把上一輪運算的結果作為輸入,最後生成n個模型,再加起來,所以又叫加性模型;

Bagging演算法就更簡單了,帶有一種隨機取樣,生成弱決策樹,然後呢,採用多數服從少數的表決方式進行投票,這種決策樹互相不作為輸入,所以又叫做投票式演算法。

隨機森林是一個老先生在70歲高齡開發的演算法模型,所以說幹這行 年齡不是問題

這是整合模型的兩個大類。

而目前工程上比較常用的GBDT、XGBOOST都屬於是boosting演算法,ok,那就來看看boosting演算法的原理。

在訓練模型中其實主要就關注兩個東西,一個是我的模型訓練的到底夠不夠徹底,能不能把所有該表現的東西都表現出來;另一個就是訓練模型的東西用到別的地方是不是也能無縫插入,效果跟訓練模型差不多,這就是模型的泛化效能。訓練模型最為關注的AUC/KS都代表了模型的區分度(對於二分類模型而言),而通過取樣、驗證集、test集等等的一系列方式都是為了確保模型的泛化效能。這樣就對訓練模型有了兩個要求,一個呢就是訓練速度,另一個就是不能過擬合(overfit)。而GBDT與XGBOOST都在這兩個方面進行了自己的努力跟嘗試,包括boosting演算法的鼻祖ADABOOST,都有這方面努力(最好也看一下adaboost原理,周的書有講,簡單說就是每一輪訓練後,會把預測錯誤的樣本權重調高,正確的調低,這樣使得最終能夠最大化預測準確率)。

 

先來看GBDT,其實說起來很簡單,有一個樣本,本身y值是100,我開始預估它,這玩意應該80,然後一看,差了20,那好,到了第二步,我就直接來預估差出來的這20,我估計有15,那到第三步再去預估剩下的,就只有5了,不斷迭代下去,就是所謂的對殘差的預估,然後回到剛剛說的訓練模型的兩個角度,一個是速度怎麼保證,另一個是過擬合怎麼避免,速度的保證在物理裡面其實已經學過了,也就是梯度下降的推導,說的直白一點,就是在曲線的點上去找切線,然後這些東西總歸都是靠偏微分方程來實現的,另一個,過擬合怎麼保證,就像剛才說的100到殘差只有5,用了兩步,是不是跑的太快了,鄧小平說,不光要跑的快還要跑的好,跑得快容易掉鏈子,那好了,我把每一步的步子都給你限制住,你不要太快了,太快的話樣本偏差比較厲害,到test跟驗證集上效果不會太好,這就是shinkage的概念,就是GBDT裡面一個最重要引數學習率,學習率、樹顆數再加上一共梯度下降,基本上就構成了GBDT最重要的幾個概念(面試的時候把這段話原封不動背出來,應該是能矇住他們的)。——除了這個,他們會問你GBDT每一步是怎麼挑選最佳變數和最佳切割點,那你就必須搬出GBDT的基決策樹——CART樹了,給他講,CART樹挑選最佳切割點靠的是GINI係數,除了GINI係數以外,還有資訊熵跟資訊增益三大法寶,其實都是為了判斷切分以後樣本是不是區分的更開,分別對應CART樹、ID3樹,還有一個我忘了。這個就是切分點的概念,GBDT的重點基本就是這些。

 

再來看XGBOOST,xgboost演算法算得上吸收了前人很多的重要概念做出來的一個比較集大成的東西,簡單的看,至少有三個方面:並行化計算(簡單看就是把hive多開幾個視窗同時insert表資料)、GBDT、隨機森林。先來一步步看,首先是模型就必須解決的兩個問題,訓練速度和防止過擬合,看看xgboost在這兩方面都做了哪些努力。在呼叫xgboost包的時候,有一個引數是booster,預設的是gbtree,我們一般也不會改,這表示啥呢,表示在最基礎的弱學習器上,xgboost是可以採用與gbdt同樣的決策樹來進行決策,就是剛剛說的cart樹,另外呢,也可以選擇邏輯迴歸作為基學習器,這個相對來講用的比較少,所以從基礎原理上來講,他跟gbdt沒有太大區別,而且都是boosting演算法,在進行第t個擬合之前,都要幹完t-1的擬合,然後呢,有意思的事情來了,剛剛說了GBDT在進行訓練時,用的是梯度下降的思路,也就是每一步都是把偏微分方程的第一階作為x的擬合項,而xgboost玩了個小花招,為毛只有一階呢,我感覺兩階的更好,還平滑一些,所以就有了所謂的泰勒展開式,把f(x)通過泰勒展開式,展開到兩階,把他用進去,目的也是為了求這個東西跟真實的y樣本的差值。這就是你看的公式的前面那一部分,訓練速度這塊就差不多這樣(除了他所謂的並行化)。接下來就是防止過擬合,剛剛說了GBDT為了防止過擬合在訓練時採用了shinkage的思路,就是把步子邁的稍微小一點,xgboost則認為,過擬合不光是步子邁太大,還有一種可能是因為樹搞得太複雜,劃太細,細細思考,好像有道理哦,於是就把樹的本身(兩個東西)作為了模型的正則項,就是所謂的L1跟L2,一個簡單說就是這個樹葉子的節點個數,另一個就是在此輪完成時,對每個節點的打分情況,分別都進行了一定處理,得到了兩個正則項,扔進去。除了這個以外,xgboost在進行基決策樹劃分的時候,也對資訊增益進行了限制,假如我劃分了以後跟不劃分一樣,那我肯定不劃分了,另外,還可以限制一個閾值,比方說劃分了以後,資訊增益太小,只有0.1(隨便猜的一個數字),不划算啊,折騰成這樣,效果沒啥太大提升,也就停止劃分,這個是在基學習時候做的一些工作。

然後再看他的並行化,從學習器是加性模型的角度來看,每一輪都是需要上一輪的結果作為輸入,所以在這塊你不可能有什麼花頭,那什麼地方能搞一搞並行化呢,ok,劃分最佳分割點的時候,在訓練之前,我就把每個變數+y值作為數值對分在很多個塊中(spark裡面的map概念),然後為了看最佳劃分點,這些我可以同時去運算,並行化就體現在這裡。

另外一個說xgboost吸收了隨機森林的思想,是因為隨機森林最基本的一個思想就是每一個訓練器可以從所有變數裡面抽取一部分變數,這是防止過擬合的一個好方法,因為可以避免強變數每次都是最強的,這樣沒有意義了,把姚明跟一堆小學生放在一塊去找籃球打的好的,每次都被姚明影響,那隻好用這種思想把這個影響稍微降低一些。

除了這個以外,在樣本本身的取樣方面,xgboost和gbdt都做了類似的事情,可以對訓練樣本進行取樣,一般這個資料取0.5到0.8,太小容易遺漏,太大又給人感覺容易過擬合,這兩塊是差不多的。

總體而言就是這樣,兩個模型的主要區別也就在這裡了。