從結構到性能,一文概述XGBoost、Light GBM和CatBoost的同與不同

2020-12-05 機器之心Pro

儘管近年來神經網絡復興並大為流行,但是 boosting 算法在訓練樣本量有限、所需訓練時間較短、缺乏調參知識等場景依然有其不可或缺的優勢。本文從算法結構差異、每個算法的分類變量時的處理、算法在數據集上的實現等多個方面對 3 種代表性的 boosting 算法 CatBoost、Light GBM 和 XGBoost 進行了對比;雖然本文結論依據於特定的數據集,但通常情況下,XGBoost 都比另外兩個算法慢。

最近,我參加了 kaggle 競賽 WIDS Datathon,並通過使用多種 boosting 算法,最終排名前十。從那時開始,我就對這些算法的內在工作原理非常好奇,包括調參及其優劣勢,所以有了這篇文章。儘管最近幾年神經網絡復興,並變得流行起來,但我還是更加關注 boosting 算法,因為在訓練樣本量有限、所需訓練時間較短、缺乏調參知識的場景中,它們依然擁有絕對優勢。

2014 年 3 月,XGBOOST 最早作為研究項目,由陳天奇提出2017 年 1 月,微軟發布首個穩定版 LightGBM2017 年 4 月,俄羅斯頂尖技術公司 Yandex 開源 CatBoost

由於 XGBoost(通常被稱為 GBM 殺手)已經在機器學習領域出現了很久,如今有非常多詳細論述它的文章,所以本文將重點討論 CatBoost 和 LGBM,在下文我們將談到:

算法結構差異每個算法的分類變量時的處理如何理解參數算法在數據集上的實現每個算法的表現

LightGBM 和 XGBoost 的結構差異

在過濾數據樣例尋找分割值時,LightGBM 使用的是全新的技術:基於梯度的單邊採樣(GOSS);而 XGBoost 則通過預分類算法和直方圖算法來確定最優分割。這裡的樣例(instance)表示觀測值/樣本。

首先讓我們理解預分類算法如何工作:

對於每個節點,遍歷所有特徵對於每個特徵,根據特徵值分類樣例進行線性掃描,根據當前特徵的基本信息增益,確定最優分割選取所有特徵分割結果中最好的一個

簡單說,直方圖算法在某個特徵上將所有數據點劃分到離散區域,並通過使用這些離散區域來確定直方圖的分割值。雖然在計算速度上,和需要在預分類特徵值上遍歷所有可能的分割點的預分類算法相比,直方圖算法的效率更高,但和 GOSS 算法相比,其速度仍然更慢。

為什麼 GOSS 方法如此高效?

在 Adaboost 中,樣本權重是展示樣本重要性的很好的指標。但在梯度提升決策樹(GBDT)中,並沒有天然的樣本權重,因此 Adaboost 所使用的採樣方法在這裡就不能直接使用了,這時我們就需要基於梯度的採樣方法。

梯度表徵損失函數切線的傾斜程度,所以自然推理到,如果在某些意義上數據點的梯度非常大,那麼這些樣本對於求解最優分割點而言就非常重要,因為算其損失更高。

GOSS 保留所有的大梯度樣例,並在小梯度樣例上採取隨機抽樣。比如,假如有 50 萬行數據,其中 1 萬行數據的梯度較大,那麼我的算法就會選擇(這 1 萬行梯度很大的數據+x% 從剩餘 49 萬行中隨機抽取的結果)。如果 x 取 10%,那麼最後選取的結果就是通過確定分割值得到的,從 50 萬行中抽取的 5.9 萬行。

在這裡有一個基本假設:如果訓練集中的訓練樣例梯度很小,那麼算法在這個訓練集上的訓練誤差就會很小,因為訓練已經完成了。

為了使用相同的數據分布,在計算信息增益時,GOSS 在小梯度數據樣例上引入一個常數因子。因此,GOSS 在減少數據樣例數量與保持已學習決策樹的準確度之間取得了很好的平衡。

高梯度/誤差的葉子,用於 LGBM 中的進一步增長

每個模型是如何處理屬性分類變量的?

CatBoost

CatBoost 可賦予分類變量指標,進而通過獨熱最大量得到獨熱編碼形式的結果(獨熱最大量:在所有特徵上,對小於等於某個給定參數值的不同的數使用獨熱編碼)。

如果在 CatBoost 語句中沒有設置「跳過」,CatBoost 就會將所有列當作數值變量處理。

注意,如果某一列數據中包含字符串值,CatBoost 算法就會拋出錯誤。另外,帶有默認值的 int 型變量也會默認被當成數值數據處理。在 CatBoost 中,必須對變量進行聲明,才可以讓算法將其作為分類變量處理。

對於可取值的數量比獨熱最大量還要大的分類變量,CatBoost 使用了一個非常有效的編碼方法,這種方法和均值編碼類似,但可以降低過擬合情況。它的具體實現方法如下:

1. 將輸入樣本集隨機排序,並生成多組隨機排列的情況。

2. 將浮點型或屬性值標記轉化為整數。

3. 將所有的分類特徵值結果都根據以下公式,轉化為數值結果。

其中 CountInClass 表示在當前分類特徵值中,有多少樣本的標記值是「1」;Prior 是分子的初始值,根據初始參數確定。TotalCount 是在所有樣本中(包含當前樣本),和當前樣本具有相同的分類特徵值的樣本數量。

可以用下面的數學公式表示:

LightGBM

和 CatBoost 類似,LighGBM 也可以通過使用特徵名稱的輸入來處理屬性數據;它沒有對數據進行獨熱編碼,因此速度比獨熱編碼快得多。LGBM 使用了一個特殊的算法來確定屬性特徵的分割值。

注意,在建立適用於 LGBM 的數據集之前,需要將分類變量轉化為整型變量;此算法不允許將字符串數據傳給分類變量參數。

XGBoost

和 CatBoost 以及 LGBM 算法不同,XGBoost 本身無法處理分類變量,而是像隨機森林一樣,只接受數值數據。因此在將分類數據傳入 XGBoost 之前,必須通過各種編碼方式:例如標記編碼、均值編碼或獨熱編碼對數據進行處理。

超參數中的相似性

所有的這些模型都需要調節大量參數,但我們只談論其中重要的。以下是將不同算法中的重要參數按照功能進行整理的表格。

實現

在這裡,我使用了 2015 年航班延誤的 Kaggle 數據集,其中同時包含分類變量和數值變量。這個數據集中一共有約 500 萬條記錄,因此很適合用來同時評估比較三種 boosting 算法的訓練速度和準確度。我使用了 10% 的數據:50 萬行記錄。

以下是建模使用的特徵:

月、日、星期:整型數據航線或航班號:整型數據出發、到達機場:數值數據出發時間:浮點數據到達延誤情況:這個特徵作為預測目標,並轉為二值變量:航班是否延誤超過 10 分鐘距離和飛行時間:浮點數據

import pandas as pd, numpy as np, time

from sklearn.model_selection import train_test_split

data = pd.read_csv("flights.csv")

data = data.sample(frac = 0.1, random_state=10)

data = data[["MONTH","DAY","DAY_OF_WEEK","AIRLINE","FLIGHT_NUMBER","DESTINATION_AIRPORT",

"ORIGIN_AIRPORT","AIR_TIME", "DEPARTURE_TIME","DISTANCE","ARRIVAL_DELAY"]]

data.dropna(inplace=True)

data["ARRIVAL_DELAY"] = (data["ARRIVAL_DELAY"]>10)*1

cols = ["AIRLINE","FLIGHT_NUMBER","DESTINATION_AIRPORT","ORIGIN_AIRPORT"]

for item in cols:

data[item] = data[item].astype("category").cat.codes +1

train, test, y_train, y_test = train_test_split(data.drop(["ARRIVAL_DELAY"], axis=1), data["ARRIVAL_DELAY"],

random_state=10, test_size=0.25)

XGBoost

import xgboost as xgb

from sklearn import metrics

def auc(m, train, test):

return (metrics.roc_auc_score(y_train,m.predict_proba(train)[:,1]),

metrics.roc_auc_score(y_test,m.predict_proba(test)[:,1]))

# Parameter Tuning

model = xgb.XGBClassifier()

param_dist = {"max_depth": [10,30,50],

"min_child_weight" : [1,3,6],

"n_estimators": [200],

"learning_rate": [0.05, 0.1,0.16],}

grid_search = GridSearchCV(model, param_grid=param_dist, cv = 3,

verbose=10, n_jobs=-1)

grid_search.fit(train, y_train)

grid_search.best_estimator_

model = xgb.XGBClassifier(max_depth=50, min_child_weight=1, n_estimators=200,

n_jobs=-1 , verbose=1,learning_rate=0.16)

model.fit(train,y_train)

auc(model, train, test)

Light GBM

import lightgbm as lgb

from sklearn import metrics

def auc2(m, train, test):

return (metrics.roc_auc_score(y_train,m.predict(train)),

metrics.roc_auc_score(y_test,m.predict(test)))

lg = lgb.LGBMClassifier(silent=False)

param_dist = {"max_depth": [25,50, 75],

"learning_rate" : [0.01,0.05,0.1],

"num_leaves": [300,900,1200],

"n_estimators": [200]

}

grid_search = GridSearchCV(lg, n_jobs=-1, param_grid=param_dist, cv = 3, scoring="roc_auc", verbose=5)

grid_search.fit(train,y_train)

grid_search.best_estimator_

d_train = lgb.Dataset(train, label=y_train)

params = {"max_depth": 50, "learning_rate" : 0.1, "num_leaves": 900, "n_estimators": 300}

# Without Categorical Features

model2 = lgb.train(params, d_train)

auc2(model2, train, test)

#With Catgeorical Features

cate_features_name = ["MONTH","DAY","DAY_OF_WEEK","AIRLINE","DESTINATION_AIRPORT",

"ORIGIN_AIRPORT"]

model2 = lgb.train(params, d_train, categorical_feature = cate_features_name)

auc2(model2, train, test)

CatBoost

在對 CatBoost 調參時,很難對分類特徵賦予指標。因此,我同時給出了不傳遞分類特徵時的調參結果,並評估了兩個模型:一個包含分類特徵,另一個不包含。我單獨調整了獨熱最大量,因為它並不會影響其他參數。

import catboost as cb

cat_features_index = [0,1,2,3,4,5,6]

def auc(m, train, test):

return (metrics.roc_auc_score(y_train,m.predict_proba(train)[:,1]),

metrics.roc_auc_score(y_test,m.predict_proba(test)[:,1]))

params = {'depth': [4, 7, 10],

'learning_rate' : [0.03, 0.1, 0.15],

'l2_leaf_reg': [1,4,9],

'iterations': [300]}

cb = cb.CatBoostClassifier()

cb_model = GridSearchCV(cb, params, scoring="roc_auc", cv = 3)

cb_model.fit(train, y_train)

With Categorical features

clf = cb.CatBoostClassifier(eval_metric="AUC", depth=10, iterations= 500, l2_leaf_reg= 9, learning_rate= 0.15)

clf.fit(train,y_train)

auc(clf, train, test)

With Categorical features

clf = cb.CatBoostClassifier(eval_metric="AUC",one_hot_max_size=31,

depth=10, iterations= 500, l2_leaf_reg= 9, learning_rate= 0.15)

clf.fit(train,y_train, cat_features= cat_features_index)

auc(clf, train, test)

結語

為了評估模型,我們應該同時考慮模型的速度和準確度表現。

請記住,CatBoost 在測試集上表現得最好,測試集的準確度最高(0.816)、過擬合程度最小(在訓練集和測試集上的準確度很接近)以及最小的預測和調試時間。但這個表現僅僅在有分類特徵,而且調節了獨熱最大量時才會出現。如果不利用 CatBoost 算法在這些特徵上的優勢,它的表現效果就會變成最差的:僅有 0.752 的準確度。因此我們認為,只有在數據中包含分類變量,同時我們適當地調節了這些變量時,CatBoost 才會表現很好。

第二個使用的是 XGBoost,它的表現也相當不錯。即使不考慮數據集包含有轉換成數值變量之後能使用的分類變量,它的準確率也和 CatBoost 非常接近了。但是,XGBoost 唯一的問題是:它太慢了。尤其是對它進行調參,非常令人崩潰(我用了 6 個小時來運行 GridSearchCV——太糟糕了)。更好的選擇是分別調參,而不是使用 GridSearchCV。

最後一個模型是 LightGBM,這裡需要注意的一點是,在使用 CatBoost 特徵時,LightGBM 在訓練速度和準確度上的表現都非常差。我認為這是因為它在分類數據中使用了一些修正的均值編碼方法,進而導致了過擬合(訓練集準確率非常高:0.999,尤其是和測試集準確率相比之下)。但如果我們像使用 XGBoost 一樣正常使用 LightGBM,它會比 XGBoost 更快地獲得相似的準確度,如果不是更高的話(LGBM—0.785, XGBoost—0.789)。

最後必須指出,這些結論在這個特定的數據集下成立,在其他數據集中,它們可能正確,也可能並不正確。但在大多數情況下,XGBoost 都比另外兩個算法慢。

所以,你更喜歡哪個算法呢?

相關焦點

  • 大戰三回合:XGBoost、LightGBM和Catboost一決高低
    Battle 中,根據訓練和預測的時間、預測得分和可解釋性等評測指標,讓三個算法一決高下!但在大訓練樣本和高維度特徵的數據環境下,GBDT 算法的性能以及準確性卻面臨了極大的挑戰,隨後,2017 年 LightGBM 應勢而生,由微軟開源的一個機器學習框架;同年,俄羅斯的搜索巨頭 Yandex 開源 Catboost 框架。
  • 資料| 陳天奇介紹Xgboost原理的PPT
    https://xgboost.apachecn.org/  所有者:https://xgboost.apachecn.org/ 】內容簡介陳天奇介紹Xgboost原理的PPT,用於學習XGBoost是一個優化的分布式梯度增強庫,旨在實現高效,靈活和便攜。它在 Gradient Boosting 框架下實現機器學習算法。XGBoost提供並行樹提升(也稱為GBDT,GBM),可以快速準確地解決許多數據科學問題。相同的代碼在主要的分布式環境(Hadoop,SGE,MPI)上運行,並且可以解決數十億個示例之外的問題。
  • 劍指LightGBM和XGboost!斯坦福發表NGBoost算法
    該算法利用自然梯度將不確定性估計引入到梯度增強中。本文試圖了解這個新算法,並與其他流行的 boosting 算法 LightGBM 和 XGboost 進行比較,以了解它在實踐中是如何工作的。as lgbimport xgboost as xgbfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import mean_squared_errorfrom math import sqrt在這裡,我將使用上面的默認學習者
  • 30分鐘搞定數據競賽刷分奪冠神器LightGBM
    一,LightGBM和XGBoost對比正如其名字中的Light所蘊含的那樣,和XGBoost相比,LightGBM在大規模數據集上跑起來更加輕盈。模型精度:XGBoost和LightGBM相當。二,LightGBM性能優化原理概述LightGBM在XGBoost上主要有3方面的優化。1,Histogram算法:直方圖算法。2,GOSS算法:基於梯度的單邊採樣算法。3,EFB算法:互斥特徵捆綁算法。
  • XGboost算法在不同作業系統中安裝方法乾貨分享
    安裝Xgboost方法最近小編想安裝一下xgboost軟體包,用pip install xgboost 安裝有問題,今天將對主流作業系統下的安裝方法進行了匯總,用到的時候拿來即用,省事省力,內容包括三大主流作業系統的,其他系統的沒有環境,暫時不列舉。
  • boost跑鞋那麼多,哪款性價比最高?
    首先boost的本質是一顆tpu進行高溫處理髮泡,讓它像爆米花一樣的發泡膨脹。被稱作 能量膠囊 將所有的boost小球壓和成一整個中底材質的時候,就成了阿迪達斯得緩震中底。adidas和BASF化學合作開發,讓堅硬的TPU通過熱塑性工藝後獲得彈性,相對於傳統的EVA材料,boost在諸多性能上具有更好的表現:
  • 面向Kaggle 和離線比賽實用工具庫 nyaggle,解決特徵工程與驗證兩...
    數據科學思維導圖 來源:網絡而 nyaggle 就是一個特定於 Kaggle 和離線比賽的實用工具庫,它主要作用於四個部分,即:特徵工程、模型驗證、模型實驗以及模型融合,尤其在特徵工程和模型驗證方面有較強的性能
  • 中信建投證券:xgboost中證500指數增強7月持倉組合發布
    xgboost模型是一種強學習模型,其是由眾多弱學習模型集成,其採用弱學習模型為CART,即分類與回歸樹。該模型重在擬合特徵和標籤間的非線性關係。組成該模型的眾多弱學習器之間的關係是補充彌補的關係,弱學習器的訓練有先後,每個新的弱學習器的學習目標都是之前已訓練好的弱學習器的殘差。
  • 不到500元就可以體驗boost!超高顏值冷門boost鞋款推薦!
    這雙EQT Support 91/18在中底上搭載了了boost材料,為它本身就不錯的緩震增色不少。網面、皮質的搭配使得鞋子的質感超高,鞋帶處的綁帶也為鞋子的支撐性和防側翻性提供了不錯的提升。目前這雙鞋子的市場價在¥450元左右,性價比還是很高的。
  • boost科技在阿迪達斯到底站有怎樣的地位?
    adidas對於boost的依賴還是很大的。boost作為現在阿迪達斯鞋款方面的核心技術被運用到了各大鞋款設計之中。在阿迪中佔有至關重要的地位,阿迪近年的發展少不了boost的幫助。boost這一科技在跑鞋中絕對是頂級的中底技術,對於全球跑步著來說絕對的福音。就像耐克的air max氣墊和zoom氣墊一樣,boost作為阿迪達斯的核心科技,在阿迪達斯中地位是非常的高。這幾年阿迪達斯打破常規,少不了boost的功勞。
  • 搭載最厚boost,這款鞋厲害了
    這次給大家帶來的是這雙19年發售的Adidas Crazy BYW,據說是一雙從外形到腳感都能讓人驚豔的球鞋。,來做出不同模塊的反饋。單從boost的體積上來說,這雙鞋是迄今為止最大的,超越了eqt support 93/17。 鞋內搭載了舒適的OrthoLite鞋墊,OrthoLite具有良好的透氣性和輕量化的優點。
  • 性能在線,顏值有面:腳感優秀的3款跑鞋,比Boost只高不低
    自從boost誕生以來,就成了一個辨別跑鞋腳感是否夠軟彈的標杆。和boost腳感相近的,很多人都會說這雙鞋腳感不錯;和boost一樣的,會說優秀;比boost還好的,那就只能說是牛X了。面對層出不窮的軟彈類材料,boost早已沒有當年那個「叱吒風雲」的地位了。現在的boost,更大程度上被人當做是「計量單位」,是「戰力對比」的標準。
  • XGBoost 重要關鍵參數及調優步驟
    因為tree的性能比線性回歸好得多,因此我們很少用線性回歸。7. colsample_bylevel [default=1]構建每一層時,列採樣率。雖然大部分數據科學家很少用到這個參數,但是這個參數在減少過擬合上還是可以挖掘出更多用處的。
  • 阿迪達斯boost哪個系列好?
    boost是adidas非常重要的科技之一,在鞋子運用中adidas創造了非常多boost鞋款,也很實用,穿著非常舒服腳感很棒。這麼多boost鞋款中,個人認為下面這些系列是比較好的。ultra boost 19最新設計出來的boost系列鞋款,屬於ultra boost的衍生品,卻擁有著全新的體驗。超厚的boost中底將腳感提升到極致,設計也是簡約時尚,很不錯的鞋款。
  • Adidas 這款鞋厲害了,搭載最厚的 boost
    此次給大伙兒產生的是這雙19年發售的AdidasCrazyBYW,聽說是一雙從外形到腳感都能令人驚嘆的球鞋。 流暢的鞋身線條仿佛一輛出眾跑車,不同的布料拼接設計方案再加天足經典的中底層次感極強,鞋舌處是流行的螢光橙色,儘管有鞋舌,可是它總體看上去更好像一雙襪套鞋,較為包裹腳面的鞋款。
  • ADIDAS最具踩屎感的BOOST系列跑鞋,你擁有嗎?
    強大的舒適腳感給adidas boost系列鞋款帶來了非常好的口碑,一度成為世界上最舒適的鞋款。 部分boost中底鞋款按照功能不同腳感舒適度也是不同的,主要與配合使用的大底有關。那麼有哪些boost系列鞋款的踩屎感強烈呢?下面給大家總結一些踩屎感強的boost系列鞋款。
  • 同樣都是緩震,斯凱奇記憶棉、亞瑟士GEL和阿迪boost差距有多大?
    對於大部分人來說,除了品牌之外,買鞋最應該看重的其實是緩震性能。因為作為一雙日常用來走路和慢跑的鞋來說,其支撐性、穩定性和回彈性能都不如緩震效果要更容易被人感知。斯凱奇記憶棉斯凱奇的記憶鞋墊已經在多個系列中採用了,它在鞋墊中採用了柔軟的泡棉材質,而這種泡棉材質擁有慢回彈的特性,因此它可以記憶你的運動步態,因此記憶鞋墊能夠非常準確的貼合你的腳部的輪廓,並且能提供一定的穩定和支撐性能。另外斯凱奇記憶鞋墊的透氣性、吸汗性也很強,重量非常的輕,非常適合走路或者普通的慢跑。
  • 數據挖掘中的利器——XGBoost理論篇
    它是Gradient Boosting Machine的一個C++實現.創建之初為受制於現有庫的計算速度和精度,XGBoost最大的特點,它能夠自動利用CPU的多線程進行並行,同時,在算法上加以改進提高了精度[1]。