XGBoost 和 LightGBM 對比

Ref:20道XGBoost面試題  https://mp.weixin.qq.com/s?__biz=MzI1MzY0MzE4Mg==&mid=2247485159&idx=1&sn=d429aac8370ca5127e1e786995d4e8ec&chksm=e9d01626dea79f30043ab80652c4a859760c1ebc0d602e58e13490bf525ad7608a9610495b3d&scene=21#wechat_redirect

深入理解LightGBM  https://blog.csdn.net/program_developer/article/details/103838846

LightGBM 的介紹:

記憶寶典:43(3) 原則:  lgb 不是要解決海量數據嗎,(3)所以採用goss算法減少樣本,(4)採用互斥特徵捆綁較少特徵,以便於計算,(1)先是樹的生長策略level/leaf wise;(2)然後節點分裂的算法-直方圖算法/預排序算法;  工程上的優化:(1)支持類別特徵(2)高效並行:特徵並行 、數據並行、投票並行(3)cache命中率有化

 

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共享一個直方圖(每個樣本的權重是二階導),所以每一層都要重新構建直方圖。比如local策略下,根節點有data個樣本,對n個特徵創建n個直方圖,直方圖的劃分是根據樣本的2階梯度作爲權重得到的,每次分裂後,樣本的2階梯度就會發生變化,就需要重新計算更新直方圖。

有點疑問:XGB應該也是針對每個特徵都分別構建一個直方圖,分桶的依據是樣本的二級梯度;完成一次分裂後,樣本的二階梯度發生變化,就需要重新計算,重新構建每個特徵的直方圖。

lightgbm中對每個特徵都有一個直方圖,所以構建一次直方圖就夠了。(1)根節點包含所有樣本data,對n個特徵,構建n個直方圖,(2)根節點分裂爲左右兩個子節點,可以先對右節點創建n個直方圖,右節點的樣本數量爲data/2,再用根節點的對應的n個直方圖減去右節點的n個直方圖,就得到左節點的n個直方圖,(3)如果一棵樹有m層深,則就需要構建m次直方圖,對應的樣本量分別爲data,data/2,data/4....

(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中要廣播樣本索引。

  • 數據並行 :傳統的數據並行策略主要爲水平劃分數據,讓不同的機器先在本地構造直方圖,然後進行全局的合併,最後在合併的直方圖上面尋找最優分割點。這種數據劃分有一個很大的缺點:通訊開銷過大。如果使用點對點通信,一臺機器的通訊開銷大約爲 O(#machine∗#feature∗#bin)O(\#machine * \#feature *\#bin )O(#machine∗#feature∗#bin) ;如果使用集成的通信,則通訊開銷爲 O(2∗#feature∗#bin)O(2 * \#feature *\#bin )O(2∗#feature∗#bin) 。

    LightGBM在數據並行中使用分散規約 (Reduce scatter) 把直方圖合併的任務分攤到不同的機器,降低通信和計算; 在節點分裂時利用直方圖做差,進一步減少了一半的通信量。

     

  • 投票並行(LGB):基於投票的數據並行則進一步優化數據並行中的通信代價,使通信代價變成常數級別。在數據量很大的時候,使用投票並行的方式只合並部分特徵的直方圖從而達到降低通信量的目的,可以得到非常好的加速效果。具體過程如下圖所示。大致步驟爲兩步:

    (1)本地找出 Top K 特徵,並基於投票篩選出可能是最優分割點的特徵;
    (2)合併時只合並每個機器選出來的特徵。
     

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