05.17 誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

編者按:機器學習領域的一個特點就是日新月異,在數據競賽中,一件趁手的工具對比賽結果有重要影響。boosting是一種將弱分類器組合成強分類器的方法,它包含多種算法,如GDBT、AdaBoost、XGBoost等等。如果你參加過Kaggle之類的數據競賽,你可能聽說過XGBoost在數據江湖上的領導地位,也可能好奇過LGBM的快速崛起。但是,你聽說過俄羅斯最大搜索引擎Yandex開發的CatBoost嗎?

近日,南佛羅里達大學數據科學碩士Alvira Swalin就為我們做了一份測試。以下是論智對原文的編譯:

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

最近我參加了一個Kaggle比賽(斯坦福大學的WIDS Datathon),依靠各種boosting算法,我最後擠進了前十名。雖然成績很好,但從那之後我就對模型集成學習的細節感到十分好奇:那些模型是怎麼組合的?參數怎麼調整?它們各自的優點和缺點又是什麼?

考慮到自己曾經用過許多boosting算法,我決定寫一篇文章來重點分析XGBoost、LGBM和CatBoost的綜合表現。雖然最近神經網絡很流行,但就我個人的觀點來看,boosting算法在訓練數據有限時更好用,訓練時間更短,調參所需的專業知識也較少。

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

XGBoost是陳天奇於2014年提出的一種算法,被稱為GBM Killer,因為介紹它的文章有很多,所以本文會在介紹CatBoost和LGBM上用更大的篇幅。以下是我們將要討論的幾個主題:

  • 結構差異

  • 處理分類變量

  • 參數簡介

  • 數據集實現

  • 算法性能

LightGBM和XGBoost的結構差異

雖然LightGBM和XGBoost都是基於決策樹的boosting算法,但它們之間存在非常顯著的結構差異。

LGBM採用leaf-wise生長策略,也就是基於梯度的單側採樣(GOSS)來找出用於分裂的數據實例,當增長到相同的葉子節點時,LGBM會直接找出分裂增益最大的葉子(通常是數據最大坨的那個),只分裂一個。

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

LightGBM

而XGBoost採用的則是level(depth)-wise生長策略,它用預排序算法+直方圖算法為每一層的葉子找出最佳分裂,簡而言之,就是它是不加區分地分裂同一層所有葉子。

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

XGBoost

我們先來看看預排序算法(pre-sorted)的工作方式:

  • 對每個葉子(分割點)遍歷所有特徵;

  • 對每個特徵,按特徵值對數據點進行排序;

  • 確定當前特徵的基本分裂增益,用線性掃描決定最佳分裂方法;

  • 基於所有特徵採取最佳分裂方法。

而直方圖算法的工作方式則是根據當前特徵把所有數據點分割稱離散區域,然後利用這些區域查找直方圖的分割值。雖然比起預排序算法那種在排序好的特徵值上枚舉所有可能的分割點的做法,直方圖算法的效率更高,但它在速度上還是落後於GOSS。

那麼為什麼GOSS這麼高效呢?

這裡我們需要提到經典的AdaBoost。在AdaBoost中,數據點的權重是數據點重要與否的一個直觀指標,但梯度提升決策樹(GBDT)不自帶這種權重,因此也就無法沿用AdaBoost的採樣方法。

基於梯度的採樣:梯度指的是損失函數切線的斜率,所以從邏輯上說,如果一些數據點的梯度很大,那它們對於找到最佳分裂方法來說就很重要,因為它們具有較高的誤差。

GOSS保留了所有具有大梯度的數據點,並對梯度小的數據點進行隨機採樣。例如,假設我有50萬行數據,其中1萬行梯度高,剩下的49萬行梯度低,那我的算法就會選擇1萬行+49萬行×x%(隨機)。設x=10,最終算法選出的就是50萬行數據中的5.9萬行。

這裡存在一個基本假設,即梯度較小的數據點具有更低的誤差,而且已經訓練好了

為了保持相同的數據分佈,在計算分裂增益時,GOSS會為這些梯度小的數據點引入一個常數乘數。以上就是它能在減少數據點數量和保證決策樹準確性之間取得平衡的方法。

處理分類變量

CatBoost

CatBoost在分類變量索引方面具有相當的靈活性,它可以用在各種統計上的分類特徵和數值特徵的組合將分類值編碼成數字(one_hot_max_size:如果feature包含的不同值的數目超過了指定值,將feature轉化為float)。

如果你沒有在cat_features語句中傳遞任何內容,CatBoost會把所有列視為數值變量。

注:如果在cat_features中未提供具有字符串值的列,CatBoost會報錯。此外,具有默認int類型的列在默認情況下也會被視為數字,所以你要提前手動定義。

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

對於分類值大於one_hot_max_size的那些分類變量,CatBoost也有一種有效的方法。它和均值編碼類似,但可以防止過擬合:

  • 對輸入樣本重新排序,並生成多個隨機排列;

  • 將label值從浮點或類別轉換為整型;

  • 用以下公式把所有分類特徵值轉換為數值,其中CountInClass表示截至當前樣本,label值=1的次數(相同樣本總數);Prior表示平滑因子,它由起始參數確定;而TotalCount則代表截至當前樣本,所有樣本的總數。

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

如果轉換為數學公式,它長這樣:

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

LightGBM

和CatBoost類似,LightGBM也可以通過輸入特徵名稱來處理分類特徵。它無需進行獨熱編碼(one-hot coding),而是使用一種特殊的算法直接查找分類特徵的拆分值,最後不僅效果相似,而且速度更快。

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

注:在為LGBM構造數據集之前,應將分類特徵轉換為整型數據,即便你用了categorical_feature參數,算法也無法識別字符串值。

XGBoost

XGBoost無法單獨處理分類特徵,它是基於CART的,所以只接收數值。在把分類數據提供給算法前,我們先得執行各種編碼,如標籤編碼、均值編碼、獨熱編碼等。

相似的超參數

這三種算法涉及的超參數有很多,這裡我們只介紹幾個重要的。下表是它們的對比:

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

數據集實現

我使用的是2015年航班延誤的Kaggle數據集,因為它同時包含分類特徵和數字特徵,而且大約有500萬行數據,無論是從訓練速度上看還是從模型的準確率上看,它都可以作為一個很好的性能判斷工具。

我從數據集中抽取10%(50萬行)作為實驗數據,以下是建模使用的特徵:

  • MONTH,DAY,DAY_OF_WEEK:整型數據

  • AIRLINE和FLIGHT_NUMBER:整型數據

  • ORIGIN_AIRPORT和DESTINATION_AIRPORT:字符串

  • DEPARTURE_TIME:float

  • ARRIVAL_DELAY:預測目標,航班延遲是否超過10分鐘?

  • DISTANCE和AIR_TIME:float

結果

誰是數據競賽王者?CatBoost vs. Light GBM vs. XGBoost

現在我們就能從訓練速度和準確率兩個維度對3種算法進行評價了。

如上表所示,CatBoost在測試集上的準確率高達0.816,同時過擬合程度最低,訓練時長短,預測時間也最少。但它真的打敗其他兩種算髮了嗎?很可惜,沒有。0.816這個準確率的前提是我們考慮了分類變量,而且單獨調整了one_hot_max_size。如果沒有充分利用算法的特性,CatBoost的表現是最差的,準確率只有0.752。

所以我們可以得出這樣一個結論:

如果數據中存在分類變量,我們可以充分利用CatBoost的特性得到一個更好的訓練結果

接著就是我們的數據競賽王者XGBoost。它的表現很穩定,如果忽略之前的數據轉換工作,單從準確率上看它和CatBoost非常接近。但是XGBoost的缺點是太慢了,尤其是調參過程,簡直令人絕望(我花了6小時擺弄GridSearchCV)。

最後就是Light GBM,這裡我想提一點,就是用cat_features時它的速度和準確率會非常糟糕,我猜測這可能是因為這時算法會在分類數據中用某種改良過的均值編碼,之後就過擬合了。如果我們能像XGBoost一樣操作,它也許可以在速度秒殺XGBoost的同時達到後者的精度。

綜上所述,這些觀察結果都是對應這個數據集得出的結論,它們可能不適用於其他數據集。我在文中沒有展示交叉驗證過程,但我確實嘗試了,結果差不多。話雖如此,但有一個結果是千真萬確的:XGBoost確實比其他兩種算法更慢


分享到:


相關文章: