XGBoost


殘差~貸款~2y~obj~$\Omega$~泰勒

例子~遍歷~GH~衡量~分裂~遞歸

一、XGBoost起源

 XGBoost的全稱是ExtremeGradient Boosting,2014年2月誕生,作者為華盛頓大學研究機器學習的大牛——陳天奇。

 他在研究中深深的體會到現有庫的計算速度和精度問題,為此而着手搭建完成 xgboost 項目。

 XGBoost問世后,因其優良的學習效果以及高效的訓練速度而獲得廣泛的關注,並在各種算法大賽上大放光彩。

二、參數解析

 XGBoost的作者把所有的參數分成了三類:

  通用參數:宏觀函數控制。

  Booster參數:控制每一步的booster(tree/regression)。

  學習目標參數:控制訓練目標的表現

 

 1)通用參數

 booster[默認gbtree]

  選擇每次迭代的模型,有兩種選擇: 

   gbtree:基於樹的模型 

   gbliner:線性模型

  盡管有兩種booster可供選擇,tree booster的表現遠遠勝過linear booster,所以linear booster很少用到

 silent[默認0]

  當這個參數值為1時,靜默模式開啟,不會輸出任何信息。

  一般這個參數就保持默認的0,因為這樣能幫我們更好地理解模型。

 nthread[默認值為最大可能的線程數]

  這個參數用來進行多線程控制,應當輸入系統的核數。

  如果你希望使用CPU全部的核,那就不要輸入這個參數,算法會自動檢測它。

 

 2)booster參數

  • 1. learning_rate[默認0.3]

    典型值為0.01-0.2。

  • 2. min_child_weight[默認1]

    決定最小葉子節點樣本權重和。這個參數用於避免過擬合。當它的值較大時,可以避免模型學習到局部的特殊樣本。但是如果這個值過高,會導致欠擬合。這個參數需要使用CV來調整。

  • 3. max_depth[默認6]

    這個值也是用來避免過擬合的。max_depth越大,模型會學到更具體更局部的樣本。需要使用CV函數來進行調優。典型值:3-10

  • 4. max_leaf_nodes

    樹上最大的節點或葉子的數量。可以替代max_depth的作用。因為如果生成的是二叉樹,一個深度為n的樹最多生成n2個葉子。

  • 5. gamma[默認0]

    在節點分裂時,只有分裂后損失函數的值下降了,才會分裂這個節點。Gamma指定了節點分裂所需的最小損失函數下降值。這個參數的值越大,算法越保守。這個參數的值和損失函數息息相關,所以是需要調整的。

  • 6. max_delta_step[默認0]

    這參數限制每棵樹權重改變的最大步長。如果這個參數的值為0,那就意味着沒有約束。如果它被賦予了某個正值,那么它會讓這個算法更加保守。通常,這個參數不需要設置。但是當各類別的樣本十分不平衡時,它對邏輯回歸是很有幫助的。

    這個參數一般用不到,但是你可以挖掘出來它更多的用處。

  • 7. subsample[默認1]

    這個參數控制對於每棵樹,隨機采樣的比例。減小這個參數的值,算法會更加保守,避免過擬合。但是,如果這個值設置得過小,它可能會導致欠擬合。典型值:0.5-1

  • 8. colsample_bytree[默認1]

    用來控制每棵隨機采樣的列數的占比(每一列是一個特征)。典型值:0.5-1

  • 9. colsample_bylevel[默認1]

    用來控制樹的每一級的每一次分裂,對列數的采樣的占比。

    我個人一般不太用這個參數,因為subsample參數和colsample_bytree參數可以起到相同的作用。但是如果感興趣,可以挖掘這個參數更多的用處。

  • 10. lambda[默認1]

    權重的L2正則化項。(和Ridge regression類似)。這個參數是用來控制XGBoost的正則化部分的。雖然大部分數據科學家很少用到這個參數,但是這個參數在減少過擬合上還是可以挖掘出更多用處的。

  • 11. alpha[默認0]

    權重的L1正則化項。(和Lasso regression類似)。可以應用在很高維度的情況下,使得算法的速度更快。

  • 12. scale_pos_weight[默認1]

    在各類別樣本十分不平衡時,把這個參數設定為一個正值,可以使算法更快收斂。

 

 3)學習目標參數:這個參數用來控制理想的優化目標和每一步結果的度量方法。

  objective(默認reg:linear):這個參數定義需要被最小化的損失函數。最常用的值有: 

   binary:logistic 二分類的邏輯回歸,返回預測的概率(不是類別)。

   multi:softmax 使用softmax的多分類器,返回預測的類別(不是概率)。 在這種情況下,你還需要多設一個參數:num_class(類別數目)。

   multi:softprob 和multi:softmax參數一樣,但是返回的是每個數據屬於各個類別的概率。

 

  eval_metric(默認值取決於objective參數的取值)

   對於有效數據的度量方法。

   對於回歸問題,默認值是rmse,對於分類問題,默認值是error。

   典型值有: 

  seed(默認0):隨機數的種子

 

三、Xgboost原理推導

 1)基本原理

  首先使用訓練集(包含:標准答案,即標簽)訓練一棵樹,然后使用這棵樹預測訓練集,得到每個樣本的預測值,由於預測值與真值存在偏差,所以真值與預測值相減可以得到“殘差”(這里相當於用訓練集訓練模型,再反過來作用於訓練集-不要以為就能完全學到所有樣本的真值,那樣會過擬合的)

  接下來訓練第二棵樹,此時不再使用真值,而是使用殘差作為標准答案。兩棵樹訓練完成后,可以再次得到每個樣本的殘差

  然后進一步訓練第三棵樹,以此類推。樹的總棵數可以人為指定,也可以監控某些指標(例如驗證集上的誤差)來停止訓練

 

 2)示例

  a)預測客戶去銀行審批貸款的額度,假設客戶的額度為1000

  使用第一顆樹預測,其目標函數為1000。假設模型預測的結果為920,則殘差為80

  構造第二課樹預測,這時其目標函數就要基於第一顆樹的預測結果,第二顆樹的目標函數為80。假設第二顆樹預測的結果為50,則與真實值的殘差還剩下30,即會作為第三顆樹的目標值

  構造第三棵樹預測,此時的目標函數為30,假設第三課樹又找回來12

  依次類推,串行構造,需要把前一顆樹的結果當成一個整體。最終結果值為n棵樹的結果相加。比如例中,如果只做三顆樹預測,最終結果為982

 

  b)用兩顆樹來預測一個人是否喜歡玩游戲。最下面的一行數2、0.1、-1為得分值

模型的結果為兩顆樹的值相加。比如男孩愛玩游戲的得分為2.9,老人愛玩游戲的得分為-1.9

 

 3)簡單流程

  假設我們構造k顆樹,則對於樣本i來說,輸出值就是k顆樹的輸出值累加:

其中K表示總共K個決策樹,k表示第k個決策樹,F表示決策樹的函數空間

每一個決策樹都有獨立的樹結構q和葉節點權重w

   

  首先,我們想問“樹的參數是什么”?我們需要學習的是函數\(f_k\)包含獨立的樹結構q和葉節點權重w這比傳統的利用梯度法求解的優化問題要難得多

  由於同時訓練所有的樹不容易,我們選用另一策略:將已經學習的樹固定,每次向其中添加一棵新的樹在第t顆樹后獲得的預測值記為:,因此我們構建流程如下:

所以整個流程就是每一輪增加一顆什么樣的樹\(f_t(x_i)\),才能使模型最優

 

 4)推導

  我們希望每輪增加的樹可以優化目標函數:

這里要注意:Constant是前t-1棵樹的懲罰項,前t-1樹結構已經確定

 

  懲罰項主要防止樹模型過大,由葉子數量和L2正則組成:

  

  其中懲罰項計算如下:注意-葉子節點權重w(其實就是預測值)

  在推導之前,需要讀者先了解泰勒公式

這里可以這么理解:$x$為原來的模型,紅框內的$\Delta x$當作新的樹模型,即新增加一個模型

這樣我們就可以進行如下泰勒展開

  而我們的目標函數是:

  如果用MSE-平方損失作為損失函數,將上式展開(注意:將平方項展開后的常數項已經用新的constant代替):

  但是對於其他的損失函數,我們未必能得出如此漂亮的式子,所以,對於一般的損失函數,我們可以采用如下的泰勒展開近似來定義一個近似的目標函數,如下所示:

值得注意的是,損失函數l是給定的,y的真實值是知道的,預測值是根據前t-1顆樹知道的,則gihi是可算的

這里如果我們的損失函數是平方損失函數,則gihi計算如下:

  這里有必要再明確一下,gi和hi的含義。gi怎么理解呢?現有t-1棵樹是不是?這t-1棵樹組成的模型對第i個訓練樣本有一個預測值\(y_i\)是不是?

  這個預測值與第i個樣本的真實標簽\(yi\)肯定有差距是不是?這個差距可以用上面的損失函數來衡量是不是?現在gi和hi的含義你已經清楚了是不是?

  我們來看一個實例,假設我們正在優化第11棵CART樹,也就是說前10棵 CART樹已經確定了。這10棵樹對樣本\((x_i,y_i=1)\)的預測值是\(y_i=-1\),假設我們現在是做分類,我們的損失函數是:

  我們可以求出這個損失函數在\(y_i=-1\)點的梯度:

  將\(y_i=-1\)帶入上式,計算得到-0.2689。這個-0.2689就是g_i。該值是負的,也就是說,如果我們想要減小這10棵樹在該樣本點上的預測損失,我們應該沿着梯度的反方向去走,也就是要增大

  來答一個小問題,在優化第t棵樹時,有多少個gi和hi要計算?嗯,沒錯就是各有N個,N是訓練樣本的數量。如果有10萬樣本,在優化第t棵樹時,就需要計算出個10萬個gi和hi

  感覺好像很麻煩是不是?但是你再想一想,這10萬個gi之間是不是沒有啥關系?是不是可以並行計算呢?聰明的你想必再一次感受到了,為什么xgboost會辣么快!

 

  好,現在我們來審視下這個式子,哪些是常量,哪些是變量。式子最后有一個constant項,聰明如你,肯定猜到了,它就是前t-1棵樹的正則化項。l(yi, yi^t-1)也是常數項

  剩下的三個變量項分別是第t棵CART樹的一次式,二次式,和整棵樹的正則化項。再次提醒,這里所謂的樹的一次式,二次式,其實都是某個葉子節點的值的一次式,二次式

  我們的目標是讓這個目標函數最小化,常數項顯然沒有什么用,我們把它們去掉,就變成了下面這樣:

 

 5)重新定義決策樹

 

一個xi的樣本進入決策樹分類是由最終的的葉子權值決定,即黑色實心圓,而中間的空心圓只是決定的 xi 樣本落入到哪一個葉子 

q(x)表示樣本x落入的葉子,即是q是將每個樣本分配到相應葉子的函數

Wq(x)表示樣本x落入葉子的權值,即W是葉節點上的得分向量

 

所以一顆決策樹的核心是:“樹結構”與“葉權值”,如下:

 

 6)正則項定義

  決策樹的復雜度可參考葉節點數和葉權值(在XGBoost里,如下定義復雜度):

  舉例:

注意:當然,不止一種方式可以定義復雜度,但實踐中上面提到的就能很好得起作用。正則化項在很多樹模型包里都沒有很好地處理,甚至直接忽略

這是因為,傳統樹模型只強調提升模型的純度,而模型復雜度控制采用啟發式方法。通過公式定義,我們可以更好得理解學習器訓練過程,並起獲得較好的實踐結果

 

  下面是公式推導里神奇的部分!將樹模型重新公式化表示之后,可以將第t棵樹的目標值記作:

也就是下面的解釋:

  也就是衡量了我們當前樹的模型效果的好壞

 

 7)目標函數計算總結:

定義如下式子:

得:

對W求偏導:

代入目標函數:

 

  舉例:XGBoost公式做的事情

 

 

 8)找出最優的樹結構

  有了評判樹的結構好壞的標准,我們就可以先求最佳的樹結構,這個定出來后,最佳的葉子結點的值實際上在上面已經求出來了

  問題是:樹的結構近乎無限多,一個一個去測算它們的好壞程度,然后再取最好的顯然是不現實的。所以,我們仍然需要采取一點策略,這就是逐步學習出最佳的樹結構

 

  這與我們將K棵樹的模型分解成一棵一棵樹來學習是一個道理,只不過從一棵一棵樹變成了一層一層節點而已。如果此時你還是有點蒙,沒關系,下面我們就來看一下具體的學習過程

  我們以上文提到過的判斷一個人是否喜歡計算機游戲為例子。最簡單的樹結構就是一個節點的樹。我們可以算出這棵單節點的樹的好壞程度obj*。假設我們現在想按照年齡將這棵單節點樹進行分叉,我們需要知道:

  1、按照年齡分是否有效,也就是是否減少了obj的值

  2、如果可分,那么以哪個年齡值來分

  為了回答上面兩個問題,我們可以將這一家五口人按照年齡做個排序。如下圖所示:

  按照這個圖從左至右掃描,我們就可以找出所有的切分點。對每一個確定的切分點,我們衡量切分好壞的標准如下:

 

  這個Gain實際上就是單節點的obj*減去切分后的兩個節點的樹obj*,Gain如果是正的,並且值越大,表示切分后obj*越小於單節點的obj*,就越值得切分

  同時,我們還可以觀察到,Gain的左半部分如果小於右側的γ,則Gain就是負的,表明切分后obj反而變大了。γ在這里實際上是一個臨界值,它的值越大,表示我們對切分后obj下降幅度要求越嚴

  這個值也是可以在xgboost中設定的。 掃描結束后,我們就可以確定是否切分,如果切分,對切分出來的兩個節點,遞歸地調用這個切分過程,我們就能獲得一個相對較好的樹結構

  注意:xgboost的切分操作和普通的決策樹切分過程是不一樣的。普通的決策樹在切分的時候並不考慮樹的復雜度,而依賴后續的剪枝操作來控制。xgboost在切分的時候就已經考慮了樹的復雜度,就是那個γ參數。所以,它不需要進行單獨的剪枝操作

 

四、感謝

 Xgboost基本原理好理解,但是推導過程比較復雜抽象,自己也花了幾天的時間去看博客和文章,這里感謝下面的博客,正是你們的抽象變具體,才讓我加深了對Xgboost的理解,真誠的感謝!

 1.https://blog.csdn.net/xinzhi8/article/details/73466554

 2.https://blog.csdn.net/PbGc396Dwxjb77F2je/article/details/78786959

 3.https://blog.csdn.net/cymy001/article/details/79037785

 4.https://www.cnblogs.com/kuangsyx/p/9043168.html

 視頻參考:https://www.bilibili.com/video/BV1KE411M7Pi?p=1(講的不錯哦)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM