推荐:数据竞赛的利器XGBoost的常见面试题
XGBoost的威名想必大家都有所耳聞,它不僅是數據科學競賽神器,在工業界中也被廣泛地使用。本文給大家分享珍藏了多年的XGBoost高頻面試題,希望能夠加深大家對XGBoost的理解,更重要的是能夠在找機會時提供一些幫助。
1. 簡單介紹一下XGBoost?
首先需要說一說GBDT,它是一種基于boosting增強策略的加法模型,訓練的時候采用前向分布算法進行貪婪的學習,每次迭代都學習一棵CART樹來擬合之前 t-1 棵樹的預測結果與訓練樣本真實值的殘差。
XGBoost對GBDT進行了一系列優化,比如損失函數進行了二階泰勒展開、目標函數加入正則項、支持并行和默認缺失值處理等,在可擴展性和訓練速度上有了巨大的提升,但其核心思想沒有大的變化。
2. XGBoost與GBDT有什么不同
基分類器:XGBoost的基分類器不僅支持CART決策樹,還支持線性分類器,此時XGBoost相當于帶L1和L2正則化項的Logistic回歸(分類問題)或者線性回歸(回歸問題)。
導數信息:XGBoost對損失函數做了二階泰勒展開,GBDT只用了一階導數信息,并且XGBoost還支持自定義損失函數,只要損失函數一階、二階可導。
正則項:XGBoost的目標函數加了正則項, 相當于預剪枝,使得學習出來的模型更加不容易過擬合。
列抽樣:XGBoost支持列采樣,與隨機森林類似,用于防止過擬合。
缺失值處理:對樹中的每個非葉子結點,XGBoost可以自動學習出它的默認分裂方向。如果某個樣本該特征值缺失,會將其劃入默認分支。
并行化:注意不是tree維度的并行,而是特征維度的并行。XGBoost預先將每個特征按特征值排好序,存儲為塊結構,分裂結點時可以采用多線程并行查找每個特征的最佳分割點,極大提升訓練速度。
3. XGBoost為什么使用泰勒二階展開
精準性:相對于GBDT的一階泰勒展開,XGBoost采用二階泰勒展開,可以更為精準的逼近真實的損失函數
可擴展性:損失函數支持自定義,只需要新的損失函數二階可導。
4. XGBoost為什么可以并行訓練
XGBoost的并行,并不是說每棵樹可以并行訓練,XGB本質上仍然采用boosting思想,每棵樹訓練前需要等前面的樹訓練完成才能開始訓練。
XGBoost的并行,指的是特征維度的并行:在訓練之前,每個特征按特征值對樣本進行預排序,并存儲為Block結構,在后面查找特征分割點時可以重復使用,而且特征已經被存儲為一個個block結構,那么在尋找每個特征的最佳分割點時,可以利用多線程對每個block并行計算。
5. XGBoost為什么快
分塊并行:訓練前每個特征按特征值進行排序并存儲為Block結構,后面查找特征分割點時重復使用,并且支持并行查找每個特征的分割點
候選分位點:每個特征采用常數個分位點作為候選分割點
CPU cache 命中優化: 使用緩存預取的方法,對每個線程分配一個連續的buffer,讀取每個block中樣本的梯度信息并存入連續的Buffer中。
Block 處理優化:Block預先放入內存;Block按列進行解壓縮;將Block劃分到不同硬盤來提高吞吐
6. XGBoost防止過擬合的方法
XGBoost在設計時,為了防止過擬合做了很多優化,具體如下:
目標函數添加正則項:葉子節點個數+葉子節點權重的L2正則化
列抽樣:訓練的時候只用一部分特征(不考慮剩余的block塊即可)
子采樣:每輪計算可以不使用全部樣本,使算法更加保守
shrinkage: 可以叫學習率或步長,為了給后面的訓練留出更多的學習空間
7. XGBoost如何處理缺失值
XGBoost模型的一個優點就是允許特征存在缺失值。對缺失值的處理方式如下:
在特征k上尋找最佳 split point 時,不會對該列特征 missing 的樣本進行遍歷,而只對該列特征值為 non-missing 的樣本上對應的特征值進行遍歷,通過這個技巧來減少了為稀疏離散特征尋找 split point 的時間開銷。
在邏輯實現上,為了保證完備性,會將該特征值missing的樣本分別分配到左葉子結點和右葉子結點,兩種情形都計算一遍后,選擇分裂后增益最大的那個方向(左分支或是右分支),作為預測時特征值缺失樣本的默認分支方向。
如果在訓練中沒有缺失值而在預測中出現缺失,那么會自動將缺失值的劃分方向放到右子結點。
find_split時,缺失值處理的偽代碼
8. XGBoost中葉子結點的權重如何計算出來
XGBoost目標函數最終推導形式如下:
利用一元二次函數求最值的知識,當目標函數達到最小值Obj*時,每個葉子結點的權重為wj*。具體公式如下:
9. XGBoost中的一棵樹的停止生長條件
當新引入的一次分裂所帶來的增益Gain<0時,放棄當前的分裂。這是訓練損失和模型結構復雜度的博弈過程。
當樹達到最大深度時,停止建樹,因為樹的深度太深容易出現過擬合,這里需要設置一個超參數max_depth。
當引入一次分裂后,重新計算新生成的左、右兩個葉子結點的樣本權重和。如果任一個葉子結點的樣本權重低于某一個閾值,也會放棄此次分裂。這涉及到一個超參數:最小樣本權重和,是指如果一個葉子節點包含的樣本數量太少也會放棄分裂,防止樹分的太細。
10. RF和GBDT的區別
相同點:
都是由多棵樹組成,最終的結果都是由多棵樹一起決定。
不同點:
集成學習:RF屬于bagging思想,而GBDT是boosting思想
偏差-方差權衡:RF不斷的降低模型的方差,而GBDT不斷的降低模型的偏差
訓練樣本:RF每次迭代的樣本是從全部訓練集中有放回抽樣形成的,而GBDT每次使用全部樣本
并行性:RF的樹可以并行生成,而GBDT只能順序生成(需要等上一棵樹完全生成)
最終結果:RF最終是多棵樹進行多數表決(回歸問題是取平均),而GBDT是加權融合
數據敏感性:RF對異常值不敏感,而GBDT對異常值比較敏感
泛化能力:RF不易過擬合,而GBDT容易過擬合
11. XGBoost如何處理不平衡數據
對于不平衡的數據集,例如用戶的購買行為,肯定是極其不平衡的,這對XGBoost的訓練有很大的影響,XGBoost有兩種自帶的方法來解決:
第一種,如果你在意AUC,采用AUC來評估模型的性能,那你可以通過設置scale_pos_weight來平衡正樣本和負樣本的權重。例如,當正負樣本比例為1:10時,scale_pos_weight可以取10;
第二種,如果你在意概率(預測得分的合理性),你不能重新平衡數據集(會破壞數據的真實分布),應該設置max_delta_step為一個有限數字來幫助收斂(基模型為LR時有效)。
原話是這么說的:
For?common?cases?such?as?ads?clickthrough?log,?the?dataset?is?extremely?imbalanced.?This?can?affect?the?training?of?xgboost?model,? and?there?are?two?ways?to?improve?it.If?you?care?only?about?the?ranking?order?(AUC)?of?your?predictionBalance?the?positive?and?negative?weights,?via?scale_pos_weightUse?AUC?for?evaluationIf?you?care?about?predicting?the?right?probabilityIn?such?a?case,?you?cannot?re-balance?the?datasetIn?such?a?case,?set?parameter?max_delta_step?to?a?finite?number?(say?1)?will?help?convergence那么,源碼到底是怎么利用scale_pos_weight來平衡樣本的呢,是調節權重還是過采樣呢?請看源碼:
可以看出,應該是增大了少數樣本的權重。
除此之外,還可以通過上采樣、下采樣、SMOTE算法或者自定義代價函數的方式解決正負樣本不平衡的問題。
12. 比較LR和GBDT,說說什么情景下GBDT不如LR
先說說LR和GBDT的區別:
LR是線性模型,可解釋性強,很容易并行化,但學習能力有限,需要大量的人工特征工程
GBDT是非線性模型,具有天然的特征組合優勢,特征表達能力強,但是樹與樹之間無法并行訓練,而且樹模型很容易過擬合;
當在高維稀疏特征的場景下,LR的效果一般會比GBDT好。原因如下:
先看一個例子:
假設一個二分類問題,label為0和1,特征有100維,如果有1w個樣本,但其中只要10個正樣本1,而這些樣本的特征 f1的值為全為1,而其余9990條樣本的f1特征都為0(在高維稀疏的情況下這種情況很常見)。
我們都知道在這種情況下,樹模型很容易優化出一個使用f1特征作為重要分裂節點的樹,因為這個結點直接能夠將訓練數據劃分的很好,但是當測試的時候,卻會發現效果很差,因為這個特征f1只是剛好偶然間跟y擬合到了這個規律,這也是我們常說的過擬合。
那么這種情況下,如果采用LR的話,應該也會出現類似過擬合的情況呀:y = W1*f1 + Wi*fi+….,其中 W1特別大以擬合這10個樣本。為什么此時樹模型就過擬合的更嚴重呢?
仔細想想發現,因為現在的模型普遍都會帶著正則項,而 LR 等線性模型的正則項是對權重的懲罰,也就是 W1一旦過大,懲罰就會很大,進一步壓縮 W1的值,使他不至于過大。但是,樹模型則不一樣,樹模型的懲罰項通常為葉子節點數和深度等,而我們都知道,對于上面這種 case,樹只需要一個節點就可以完美分割9990和10個樣本,一個結點,最終產生的懲罰項極其之小。
這也就是為什么在高維稀疏特征的時候,線性模型會比非線性模型好的原因了:帶正則化的線性模型比較不容易對稀疏特征過擬合。
13. XGBoost中如何對樹進行剪枝
在目標函數中增加了正則項:使用葉子結點的數目和葉子結點權重的L2模的平方,控制樹的復雜度。
在結點分裂時,定義了一個閾值,如果分裂后目標函數的增益小于該閾值,則不分裂。
當引入一次分裂后,重新計算新生成的左、右兩個葉子結點的樣本權重和。如果任一個葉子結點的樣本權重低于某一個閾值(最小樣本權重和),也會放棄此次分裂。
XGBoost 先從頂到底建立樹直到最大深度,再從底到頂反向檢查是否有不滿足分裂條件的結點,進行剪枝。
14. XGBoost如何選擇最佳分裂點??
XGBoost在訓練前預先將特征按照特征值進行了排序,并存儲為block結構,以后在結點分裂時可以重復使用該結構。
因此,可以采用特征并行的方法利用多個線程分別計算每個特征的最佳分割點,根據每次分裂后產生的增益,最終選擇增益最大的那個特征的特征值作為最佳分裂點。
如果在計算每個特征的最佳分割點時,對每個樣本都進行遍歷,計算復雜度會很大,這種全局掃描的方法并不適用大數據的場景。XGBoost還提供了一種直方圖近似算法,對特征排序后僅選擇常數個候選分裂位置作為候選分裂點,極大提升了結點分裂時的計算效率。
15. XGBoost的Scalable性如何體現
基分類器的scalability:弱分類器可以支持CART決策樹,也可以支持LR和Linear。
目標函數的scalability:支持自定義loss function,只需要其一階、二階可導。有這個特性是因為泰勒二階展開,得到通用的目標函數形式。
學習方法的scalability:Block結構支持并行化,支持 Out-of-core計算。
16. XGBoost如何評價特征的重要性
我們采用三種方法來評判XGBoost模型中特征的重要程度:
官方文檔: (1)weight?-?the?number?of?times?a?feature?is?used?to?split?the?data?across?all?trees.? (2)gain?-?the?average?gain?of?the?feature?when?it?is?used?in?trees.? (3)cover?-?the?average?coverage?of?the?feature?when?it?is?used?in?trees.weight?:該特征在所有樹中被用作分割樣本的特征的總次數。
gain?:該特征在其出現過的所有樹中產生的平均增益。
cover?:該特征在其出現過的所有樹中的平均覆蓋范圍。
注意:覆蓋范圍這里指的是一個特征用作分割點后,其影響的樣本數量,即有多少樣本經過該特征分割到兩個子節點。
17. XGBooost參數調優的一般步驟
首先需要初始化一些基本變量,例如:
max_depth = 5
min_child_weight = 1
gamma = 0
subsample, colsample_bytree = 0.8
scale_pos_weight = 1
(1) 確定learning rate和estimator的數量
learning rate可以先用0.1,用cv來尋找最優的estimators
(2) max_depth和 min_child_weight
我們調整這兩個參數是因為,這兩個參數對輸出結果的影響很大。我們首先將這兩個參數設置為較大的數,然后通過迭代的方式不斷修正,縮小范圍。
max_depth,每棵子樹的最大深度,check from range(3,10,2)。
min_child_weight,子節點的權重閾值,check from range(1,6,2)。
如果一個結點分裂后,它的所有子節點的權重之和都大于該閾值,該葉子節點才可以劃分。
(3) gamma
也稱作最小劃分損失min_split_loss,check from 0.1 to 0.5,指的是,對于一個葉子節點,當對它采取劃分之后,損失函數的降低值的閾值。
如果大于該閾值,則該葉子節點值得繼續劃分
如果小于該閾值,則該葉子節點不值得繼續劃分
(4) subsample, colsample_bytree
subsample是對訓練的采樣比例
colsample_bytree是對特征的采樣比例
both check from 0.6 to 0.9
(5) 正則化參數
alpha 是L1正則化系數,try 1e-5, 1e-2, 0.1, 1, 100
lambda 是L2正則化系數
(6) 降低學習率
降低學習率的同時增加樹的數量,通常最后設置學習率為0.01~0.1
18. XGBoost模型如果過擬合了怎么解決
當出現過擬合時,有兩類參數可以緩解:
第一類參數:用于直接控制模型的復雜度。包括max_depth,min_child_weight,gamma?等參數
第二類參數:用于增加隨機性,從而使得模型在訓練時對于噪音不敏感。包括subsample,colsample_bytree
還有就是直接減小learning rate,但需要同時增加estimator?參數。
19.為什么XGBoost相比某些模型對缺失值不敏感
對存在缺失值的特征,一般的解決方法是:
離散型變量:用出現次數最多的特征值填充;
連續型變量:用中位數或均值填充;
一些模型如SVM和KNN,其模型原理中涉及到了對樣本距離的度量,如果缺失值處理不當,最終會導致模型預測效果很差。
而樹模型對缺失值的敏感度低,大部分時候可以在數據缺失時時使用。原因就是,一棵樹中每個結點在分裂時,尋找的是某個特征的最佳分裂點(特征值),完全可以不考慮存在特征值缺失的樣本,也就是說,如果某些樣本缺失的特征值缺失,對尋找最佳分割點的影響不是很大。
XGBoost對缺失數據有特定的處理方法,詳情參考上篇文章第7題。
因此,對于有缺失值的數據在經過缺失處理后:
當數據量很小時,優先用樸素貝葉斯
數據量適中或者較大,用樹模型,優先XGBoost
數據量較大,也可以用神經網絡
避免使用距離度量相關的模型,如KNN和SVM
20. XGBoost和LightGBM的區別
(1)樹生長策略:XGB采用level-wise的分裂策略,LGB采用leaf-wise的分裂策略。XGB對每一層所有節點做無差別分裂,但是可能有些節點增益非常小,對結果影響不大,帶來不必要的開銷。Leaf-wise是在所有葉子節點中選取分裂收益最大的節點進行的,但是很容易出現過擬合問題,所以需要對最大深度做限制 。
(2)分割點查找算法:XGB使用特征預排序算法,LGB使用基于直方圖的切分點算法,其優勢如下:
減少內存占用,比如離散為256個bin時,只需要用8位整形就可以保存一個樣本被映射為哪個bin(這個bin可以說就是轉換后的特征),對比預排序的exact greedy算法來說(用int_32來存儲索引+ 用float_32保存特征值),可以節省7/8的空間。
計算效率提高,預排序的Exact greedy對每個特征都需要遍歷一遍數據,并計算增益,復雜度為????(#????????????????????????????×#????????????????)。而直方圖算法在建立完直方圖后,只需要對每個特征遍歷直方圖即可,復雜度為????(#????????????????????????????×#????????????????)。
LGB還可以使用直方圖做差加速,一個節點的直方圖可以通過父節點的直方圖減去兄弟節點的直方圖得到,從而加速計算
但實際上xgboost的近似直方圖算法也類似于lightgbm這里的直方圖算法,為什么xgboost的近似算法比lightgbm還是慢很多呢?
xgboost在每一層都動態構建直方圖, 因為xgboost的直方圖算法不是針對某個特定的feature,而是所有feature共享一個直方圖(每個樣本的權重是二階導),所以每一層都要重新構建直方圖,而lightgbm中對每個特征都有一個直方圖,所以構建一次直方圖就夠了。
(3)支持離散變量:無法直接輸入類別型變量,因此需要事先對類別型變量進行編碼(例如獨熱編碼),而LightGBM可以直接處理類別型變量。
(4)緩存命中率:XGB使用Block結構的一個缺點是取梯度的時候,是通過索引來獲取的,而這些梯度的獲取順序是按照特征的大小順序的,這將導致非連續的內存訪問,可能使得CPU cache緩存命中率低,從而影響算法效率。而LGB是基于直方圖分裂特征的,梯度信息都存儲在一個個bin中,所以訪問梯度是連續的,緩存命中率高。
(5)LightGBM 與 XGboost 的并行策略不同:
特征并行?:LGB特征并行的前提是每個worker留有一份完整的數據集,但是每個worker僅在特征子集上進行最佳切分點的尋找;worker之間需要相互通信,通過比對損失來確定最佳切分點;然后將這個最佳切分點的位置進行全局廣播,每個worker進行切分即可。XGB的特征并行與LGB的最大不同在于XGB每個worker節點中僅有部分的列數據,也就是垂直切分,每個worker尋找局部最佳切分點,worker之間相互通信,然后在具有最佳切分點的worker上進行節點分裂,再由這個節點廣播一下被切分到左右節點的樣本索引號,其他worker才能開始分裂。二者的區別就導致了LGB中worker間通信成本明顯降低,只需通信一個特征分裂點即可,而XGB中要廣播樣本索引。
數據并行?:當數據量很大,特征相對較少時,可采用數據并行策略。LGB中先對數據水平切分,每個worker上的數據先建立起局部的直方圖,然后合并成全局的直方圖,采用直方圖相減的方式,先計算樣本量少的節點的樣本索引,然后直接相減得到另一子節點的樣本索引,這個直方圖算法使得worker間的通信成本降低一倍,因為只用通信以此樣本量少的節點。XGB中的數據并行也是水平切分,然后單個worker建立局部直方圖,再合并為全局,不同在于根據全局直方圖進行各個worker上的節點分裂時會單獨計算子節點的樣本索引,因此效率賊慢,每個worker間的通信量也就變得很大。
投票并行(LGB):當數據量和維度都很大時,選用投票并行,該方法是數據并行的一個改進。數據并行中的合并直方圖的代價相對較大,尤其是當特征維度很大時。大致思想是:每個worker首先會找到本地的一些優秀的特征,然后進行全局投票,根據投票結果,選擇top的特征進行直方圖的合并,再尋求全局的最優分割點。
參考:
1.https://blog.csdn.net/u010665216/article/details/78532619
2.https://blog.csdn.net/jamexfx/article/details/93780308
本站簡介↓↓↓?
“機器學習初學者”是幫助人工智能愛好者入門的個人公眾號(創始人:黃海廣)
初學者入門的道路上,最需要的是“雪中送炭”,而不是“錦上添花”。
本站的知識星球(黃博的機器學習圈子)ID:92416895
目前在機器學習方向的知識星球排名第一(上圖二維碼)
往期精彩回顧
良心推薦:機器學習入門資料匯總及學習建議
黃海廣博士的github鏡像下載(機器學習及深度學習筆記及資源)
機器學習小抄-(像背托福單詞一樣理解機器學習)
首發:深度學習入門寶典-《python深度學習》原文代碼中文注釋版及電子書
機器學習必備寶典-《統計學習方法》的python代碼實現、電子書及課件
重磅 | 完備的 AI 學習路線,最詳細的資源整理!
圖解word2vec(原文翻譯)
斯坦福CS229機器學習課程的數學基礎(概率論和線性)
備注:本站qq群:865189078(共8個群,不用重復加)。
加入本站微信群,請加黃博的助理微信,說明:公眾號用戶加群。
總結
以上是生活随笔為你收集整理的推荐:数据竞赛的利器XGBoost的常见面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 强烈推荐10 个机器学习教程!(含视频链
- 下一篇: 分享:我是怎么在github上找到优秀的