機器學習競賽王者演算法:XGBoost、LightGBM、CatBoost
若是有參加過機器學習競賽的人應該都會聽過 XGBoost 這個橫掃各種競賽的演算法,其實後來也有衍生出 LightGBM 和 Cat boost 這兩種演算法可以使用,只是比較少人聽過,又鑒於這方面資料似乎比較少,就自己吃了一些學習資源來介紹,順便推動自己的學習,希望才疏學淺的本人可以幫助你更了解這三個常見演算法。
The map of machine Learning algorithms
不論是 XGBoost, LightGBM 還是 Catboost,他們都屬於 Ensemble learning (集成式學習)中的 Boosting 方法。Ensemble learning 的基本想法就是一個不夠,你有沒有試過兩個?兩個不夠,你有沒有試過三個?也就是將多種學習方法都集合在一起使用,彼此互相補足,讓演算法的架構更加靈活。
Boosting
Boosting 是循序的演算法,一開始會先產生多個弱學習器(Weak learner)並讓它們不斷改正舊模型的錯誤,最後合成起來變成一個強學習器(Strong learner)。而所謂的弱學習器是指比隨機猜的表現還要更好一點的模型,這種學習器的訓練成本低、複雜度也低,同時也不易 Overfitting。正因為這些特性,所以我們才可以在短時間內訓練很多種弱學習器,彼此組合起來得到一個強力的模型。
Gradient Boosting
Gradient boosting 指的則是將梯度下降法(Gradient descent)應用到這些弱學習器的學習上,幫助最小化 error。這個方法的主要問題在於每跑一次 Gradient descent都需要重新建立一次學習器,這樣非常沒有效率,也因此 XGboost 出現了。
Gradient Boosting Decision Tree (GBDT)
當我們剛剛所提到的每一個弱學習器都是一個決策樹的時候,這個意圖學習並組合出最好的決策樹的Gradient Boosting就叫做GBDT。這也是我們目前最常見用來實作Gradient boosting的做法,同時,這樣做也正好緩和了決策樹容易Overfitting 的問題。今天的三大主題 XGBoost, LightGBM, CatBoost 都是基於 GBDT 的改進方法。
XGBoost
XGBoost的全名是 eXtreme Gradient Boosting,聽起來就很強很極限,實際上也真的很強很極限,可以比喻成是吃了類固醇的 Gradient Boosting。相較於循序學習的GBDT,XGBoost更加有效率、有彈性並且更輕量化,這是因為他能提供平行的決策樹Boosting,讓整個學習的過程不再是循序而是平行的。
XGBoost 的學習過程基於 level-wise tree pruning,在學習的時候它是在不同tree的同一個level上利用資訊獲利 ( information gain ) 的方式作為指標來挑選節點出來組合,雖然已經可以達到平行學習,但在資料量大時要去計算所有可能的 split 還是有點耗時,所以才會衍生出 LightGBM 和 CatBoost。
LightGBM
LightGBM 採用 Level-wise 和 leaf-wise 並行訓練,並且用 Gradient-based One-Side Sampling (GOSS)和 Exclusive Feature Bundling (EFB)兩種演算法來降低計算量。
其中,GOSS 是一種下採樣的抽樣演算法,首先它會先計算出所有樣本的 gradient並排序,接下來它會保留一些 gradient 較大的樣本並從剩下的 gradient 較小的樣本中隨機抽樣幾個出來留下。這是因為 gradient 大的表示還沒有經過充分的訓練,而gradient小表示已經有充分的訓練過,也因此,繼續對 gradient 小的樣本訓練非常沒有效率,所以才會以下採樣的方式減少它們的數量。而以隨機採樣的方式的原因是為了避免資料分布在過程中被改變,這麼做不僅可以減少計算量也能確保模型的準確度。
EFB是用來降維的演算法,主要用途在於將多個 features 合併起來壓縮成一個。這是因為高維度的資料通常會有稀疏(sparse)的特色,這表示裡面有許多資料其實是多餘、不需要的,就像 One-hot encoding 中的0一樣。而 EFB 就是利用貪婪演算法找到這些稀疏的特徵,並將稀疏的特徵和真正的特徵做合併,達到降維的效果。
CatBoost
以結果來說,Catboost 的計算量是三者裡面需求最低的。
Important parameter of XGBoost, LightGBM and CatBoost
既然都提到它們是機器學習競賽的寵兒,當然要介紹一下這三者重要的參數有哪些,以便打比賽的時候可以有效率的硬 train 一波啊!
需要注意的是這邊提到 XGBoost 沒有針對 catrgorical values 的參數的意思並不是說XGBoost 不能做分類問題,而是它沒有針對分類問題能調整的參數。三者不管在分類問題還是回歸問題上都可以使用,不然要怎麼當王者呢?
Implementing XGBoost, LightGBM and CatBoost
Data Preprocessing
import pandas as pd
import numpy as np
import time
from sklearn.model_selection import train_test_split
# Read data
data = pd.read_csv("flights.csv")
data = data.sample(frac = 0.1, random_state=10)
# Data preprocessing
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
print(data.head())
# train test split
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
# Example of XGBoost
import xgboost as xgb
from sklearn import metrics
from sklearn.model_selection import GridSearchCV
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)
LightGBM
# Example of LightGBM
import lightgbm as lgb
from sklearn import metrics
from sklearn.model_selection import GridSearchCV
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
# Example of 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]))
# n_estimator of LightGBM is called iterations
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)
# Without 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)
Conclusion
從實驗結果可以看到,不論是訓練還是預測,耗費的時間不意外的是CatBoost最少,準確率方面也是它最高,
但 CatBoost 其實只有在加入 categorical features 的時候才能達到最高的0.816,在不考慮 categorical features 的情況下會是 XGBoost 表現比 LightGBM 還好一點。
References:
- https://xgboost.readthedocs.io/en/latest/tutorials/model.html
- https://towardsdatascience.com/what-makes-lightgbm-lightning-fast-a27cf0d9785e
- https://towardsdatascience.com/catboost-vs-light-gbm-vs-xgboost-5f93620723db
- https://www.analyticsvidhya.com/blog/2017/06/which-algorithm-takes-the-crown-light-gbm-vs-xgboost/
- https://www.kdnuggets.com/2020/06/lightgbm-gradient-boosting-decision-tree.html
- https://towardsdatascience.com/an-example-of-hyperparameter-optimization-on-xgboost-lightgbm-and-catboost-using-hyperopt-12bc41a271e
- https://towardsdatascience.com/from-zero-to-hero-in-xgboost-tuning-e48b59bfaf58
留言
張貼留言