【機器學習】深度剖析 LightGBM vs XGBOOST 哪個更勝一籌
今天就 LightGBM 和 XGBOOST?放在一起對比學習下,以便加深印象。
寫在前面
作為一個機器學習研習者,大概會了解 Boosting Machines 及其功能。Boosting Machines 的發(fā)展從 AdaBoost 開始,發(fā)展到一度很受歡迎的 XGBOOST,因其非常強大而成為在 Kaggle 上贏得比賽的常用算法。但在大量的數(shù)據(jù)的情況下,XGBOOST 也需要很長時間來訓練。
另外一個強大的集成算法 Light Gradient Boosting,他是一種怎樣的提升機器算法?是否優(yōu)于 XGBOOST?這是很多初學者在剛接觸這兩個算法時,通常是比較迷茫的。
接下來我們就來一起研習 LightGBM 相關問題。并深度對比分析它與XGBOOST的優(yōu)劣。

01 什么是LightGBM
LightGBM 是一種基于決策樹算法的快速、分布式、高性能梯度提升框架,用于排序、分類和許多其他機器學習任務。
雖然它同樣是基于決策樹算法,而它以最佳擬合方式分割樹的葉子,而其他提升算法則是按深度或級別而不是按葉分割樹。因此,當在 LightGBM 中的同一片葉子上生長時,leaf-wise 算法比 level-wise 算法在計算損失時將減少的更多,從而達到更好的精度,這是任何現(xiàn)有的 boosting 算法都很難實現(xiàn)的。此外,它的速度非???,這也是 "light "這個詞的由來。
下面是 LightGBM 和 XGBOOST 的樹模型生長的示意圖,從圖中可以清楚地看到它們之間的差異。

XGBOOST 中的 level-wise 樹生長。

LightGBM 中的leaf-wise 的樹生長。
雖然逐葉拆分會導致復雜性增加,并可能導致過度擬合,但可以通過調(diào)整參數(shù) max-depth 來克服該問題,該參數(shù)設定樹葉子節(jié)點將發(fā)生拆分的深度。
02 安裝 Light GBM
下面,我們一起安裝 LightGBM 及使用其建立模型的步驟。我們會將其得到的結(jié)果與 XGBOOST 的結(jié)果進行比較,這樣可以對 LightGBM 模型理解更加深刻。
Windows
事先安裝 git for windows[1] , cmake[2]
git?clone?--recursive?https://github.com/Microsoft/LightGBM
cd?LightGBM
mkdir?build
cd?build
cmake?-DCMAKE_GENERATOR_PLATFORM=x64?..
cmake?--build?.?--target?ALL_BUILD?--config?Release
exe 和 dll 將在 LightGBM/Release 文件夾中。
Linux
Light GBM 使用 cmake 構(gòu)建。
git?clone?--recursive?https://github.com/Microsoft/LightGBM?
cd?LightGBM?
mkdir?build?
cd?build?
cmake?..?
make?-j4
OSX
LightGBM 依賴 OpenMP 編譯,Apple Clang 不支持,請改用 gcc/g++。
brew?install?cmake?
brew?install?gcc?--without-multilib?
git?clone?--recursive?https://github.com/Microsoft/LightGBM?
cd?LightGBM?
mkdir?build?
cd?build?
cmake?..?
make?-j4
03 XGBOOST 優(yōu)勢
這種算法在預測模型中引入了提升能力。當我們繼續(xù)深入探索其高精度背后機制時,會發(fā)現(xiàn)不少優(yōu)點:
引入正則化
標準的 GBM 實現(xiàn)沒有像 XGBOOST 那樣的正則化,因此它也有助于減少過擬合。
XGBOOST 也被稱為 "正則化提升" 技術。
并行處理
XGBOOST 實現(xiàn)了并行處理,并且與 GBM 相比速度要快得多。
XGBOOST 還支持在 Hadoop 上實現(xiàn)。
高靈活性
XGBOOST 允許用戶定義自定義優(yōu)化目標和評估標準,這使得模型的限制更小。
處理缺失值
XGBOOST 有一個內(nèi)置的方法來處理缺失值。并且可以通過提供與其他觀察不同的值并將其作為參數(shù)傳遞,以此處理缺失值。
樹剪枝
當一個 GBM 在分裂中遇到負損失時,它會停止分裂一個節(jié)點。因此它更像是一種貪心算法。
另一方面,XGBOOST 使樹分裂達到指定的 max_depth,然后開始向后修剪樹并移除沒有正增益的分枝。
另一個優(yōu)點是,有時負損失的拆分可能會跟隨正損失的拆分 +10。GBM 會在遇到 -2 時停止。但是 XGBOOST 會更深入,它將看到分裂的 +8 的組合效果并保留兩者。
內(nèi)置交叉驗證
XGBOOST 允許在提升過程的每次迭代中運行交叉驗證,因此很容易在單次運行中獲得準確的最佳提升迭代次數(shù)。
這與 GBM 不同,在 GBM 中必須運行網(wǎng)格搜索并且只能測試有限的值。
繼續(xù)現(xiàn)有模型
用戶可以從上次運行的最后一次迭代開始訓練 XGBOOST 模型。這在某些特定應用中可能具有顯著優(yōu)勢。
04 LightGBM 的優(yōu)勢
更快的訓練速度和更高的效率
LightGBM 使用基于直方圖的算法(如HGBT),即將連續(xù)的特征值存儲到離散的 bin 中,從而加快了訓練過程。
較低的內(nèi)存使用量
將連續(xù)值替換為離散的 bin,從而降低內(nèi)存使用量。
比其他 boosting 算法準確性更好
它通過遵循葉方式拆分方法而不是級別方法生成更復雜的樹,這是實現(xiàn)更高準確性的主要因素。然而,它有時會導致過度擬合,這可以通過設置 max_depth 參數(shù)來避免。
與大型數(shù)據(jù)集的兼容性
與 XGBOOST 相比,在 大型數(shù)據(jù)集 上表現(xiàn)更加出色。因為其支持并行學習,顯著減少訓練時間。
05 LightGBM的參數(shù)
在開始構(gòu)建第一個 LightGBM 模型之前,我們先一起看看 LightGBM 的一些重要參數(shù),以便更好地了解其底層邏輯。
task:value = train,options = train,prediction。指定我們希望執(zhí)行的任務是訓練還是預測。 application:default=regression,type=enum,options=options regression:執(zhí)行回歸任務 binary : 二元分類 multiclass:多類分類 lambdarank : lambdarank 應用程序 data:type=string;訓練數(shù)據(jù),LightGBM 將根據(jù)這些數(shù)據(jù)進行訓練。 num_iterations:default=100,type=int。要執(zhí)行的 boosting 迭代次數(shù)。 num_leaves:default = 31,type=int。葉一個樹的數(shù)量。 device:default= cpu;options = gpu, cpu。我們要在其上訓練模型的設備??蛇x擇 GPU 以加快訓練速度。 max_depth:指定樹將生長的最大深度。該參數(shù)用于處理過擬合。 min_data_in_leaf:一片葉子中的最小數(shù)據(jù)數(shù)。 feature_fraction:default =1。指定每次迭代要采用的特征分數(shù) bagging_fraction:default = 1。指定每次迭代要使用的數(shù)據(jù)比例,通常用于加速訓練并避免過度擬合。 min_gain_to_split:default = 0.1。執(zhí)行分裂的最小增益。 max_bin:存儲特征值的最大 bin 數(shù)量。 min_data_in_bin:一個 bin 中的最小數(shù)據(jù)數(shù)。 num_threads:default=OpenMP_default,type=int。LightGBM 的線程數(shù)。 label:type=string。指定標簽列。 categorical_feature:type=string。指定我們要用于訓練模型的分類特征。 num_class:default=1,type=int。僅用于多類分類。
06 調(diào)參對比
LightGBM調(diào)參的一般方法
對于基于決策樹的模型,調(diào)參的方法都是大同小異。一般都需要如下步驟:
首先選擇較高的學習率(大概0.1附近),以加快收斂速度; 對決策樹基本參數(shù)調(diào)參,以提供模型精度; 正則化參數(shù)調(diào)參,以防止模型過擬合; 最后降低學習率,最后提高準確率。
LightGBM 使用逐葉分割而不是深度分割,這使它能夠更快地收斂,但也會導致過度擬合。所以這里有一個快速指南來調(diào)整 LightGBM 中的參數(shù)。
default=
-?{l2?for?regression},
-?{binary_logloss?for?binary?classification},
-?{ndcg?for?lambdarank},
-?type=multi-enum,
options=l1,?l2,?ndcg,?auc,?binary_logloss,?binary_error?…
為了更好的擬合
num_leaves:此參數(shù)用于設置要在樹中形成的葉子數(shù)。 num_leaves和max_depth之間的理論上關系是num_leaves= 2^(max_depth)。然而這并不太適合 Light GBM ,因為分裂發(fā)生在葉方向而不是深度方向。因此num_leaves必須設置小于2^(max_depth),否則可能會導致過擬合。Light GBM 在num_leaves和max_depth之間沒有直接關系,因此兩者不能相互關聯(lián)。min_data_in_leaf:也是處理過擬合的重要參數(shù)之一。將其值設置得較小可能會導致過擬合。大型數(shù)據(jù)集中,它的值應該是數(shù)百到數(shù)千,具體需要根據(jù)實際情況調(diào)整。 max_depth:它指定樹可以生長的最大深度。
為了更快的速度
bagging_fraction:用于執(zhí)行袋裝以獲得更快的結(jié)果 feature_fraction:設置要在每次迭代中使用的特征的分數(shù) max_bin:較小的 max_bin值可以節(jié)省很多時間,因為它將特征值存儲在離散的容器中,計算成本較低。
為了更好的準確性
使用更大的訓練數(shù)據(jù)。 num_leaves:將其設置為高值會產(chǎn)生更深的樹,并提高準確性,但會導致過度擬合。因此,不優(yōu)選其較高的值。 max_bin:將其設置為高值與增加 num_leaves值產(chǎn)生的效果類似,也會減慢我們的訓練過程。
XGBOOST 調(diào)參的一般方法
我們將在這里使用類似于 GBM 的方法。要執(zhí)行的各個步驟是:
選擇一個比較高的學習率。一般來說,0.1 的學習率是較為常用的,而根據(jù)不同的問題,學習率的選用范圍一般在 0.05 到 0.3 之間。 接下來需確定此學習率的最佳集成樹數(shù)。XGBOOST 有一個非常有用的函數(shù),稱為“cv”,它在每次提升迭代時執(zhí)行交叉驗證,從而返回所需的最佳樹數(shù)。 調(diào)整特定于樹的參數(shù) ( max_depth、min_child_weight、gamma、subsample、colsample_bytree)以決定學習率和樹的數(shù)量。調(diào)整正則化參數(shù)( lambda、alpha),這有助于降低模型復雜性并提高性能。降低學習率并決定最優(yōu)參數(shù)。
07 應用對比
現(xiàn)在我們通過將這兩種算法應用于數(shù)據(jù)集,通過比較其性能優(yōu)劣,以此來比較 LightGBM 和 XGBoost 兩個算法。
該數(shù)據(jù)集包含來自不同國家的個人信息。其目標是根據(jù)其他可用信息預測一個人的年收入是小于或等于50k還是大于50k。該數(shù)據(jù)集由 32561 個樣本和 14 個特征組成。需要數(shù)據(jù)集的讀者在公眾號【機器學習研習院】后臺聯(lián)系作者獲取。
數(shù)據(jù)探索
#?導入庫
import?numpy?as?np?
import?pandas?as?pd?
from?pandas?import?Series,?DataFrame?
import?lightgbm?as?lgb?
import?xgboost?as?xgb?
#?使用pandas加載我們的訓練數(shù)據(jù)集'adult.csv',名稱為'data'
data=pd.read_csv('adult.csv',header=None)?
#?為列分配名稱
data.columns=['age','workclass','fnlwgt','education',
??????????????'education-num','marital_Status','occupation',
??????????????'relationship','race','sex','capital_gain',
??????????????'capital_loss','hours_per_week','native_country','Income']?
data.head()?

對目標變量進行編碼
from?sklearn.preprocessing?import?LabelEncoder,OneHotEncoder
l=LabelEncoder()
l.fit(data.Income)?
l.classes_?
array([' <=50K', ' >50K'], dtype=object)
一個熱編碼的分類特征
one_hot_workclass=pd.get_dummies(data.workclass)?
one_hot_education=pd.get_dummies(data.education)?
one_hot_marital_Status=pd.get_dummies(data.marital_Status)?
one_hot_occupation=pd.get_dummies(data.occupation)
one_hot_relationship=pd.get_dummies(data.relationship)?
one_hot_race=pd.get_dummies(data.race)?
one_hot_sex=pd.get_dummies(data.sex)?
one_hot_native_country=pd.get_dummies(data.native_country)?
#?刪除分類特征?
data.drop(['workclass','education','marital_Status',
???????????'occupation','relationship','race','sex',
???????????'native_country'],axis=1,inplace=True)?
#?與我們的數(shù)據(jù)集'data'合并一個熱編碼特性
data=pd.concat([data,one_hot_workclass,one_hot_education,
????????????????one_hot_marital_Status,one_hot_occupation,
????????????????one_hot_relationship,one_hot_race,one_hot_sex,
????????????????one_hot_native_country],axis=1)?
#?刪除dulpicate列
_,?i?=?np.unique(data.columns,?return_index=True)?
data=data.iloc[:,?i]?
data

這里我們的目標變量是"Income",其值為1或0。然后將數(shù)據(jù)分為特征數(shù)據(jù)集x和目標數(shù)據(jù)集y。
x=data.drop('Income',?axis=1)?
y=data.Income
#?將缺失的值輸入到目標變量中
y.fillna(y.mode()[0],inplace=True)?
#?現(xiàn)在將我們的數(shù)據(jù)集分為test和train
from?sklearn.model_selection?import?train_test_split?
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=.3)
XGBOOST 應用
數(shù)據(jù)存儲在一個 DMatrix 對象中,參數(shù) label 用于定義結(jié)果變量。
dtrain=xgb.DMatrix(x_train,label=y_train)?
dtest=xgb.DMatrix(x_test)
#設置xgboost
parameters={'max_depth':7,?'eta':1,?'silent':1,
????????'objective':'binary:logistic',
????????'eval_metric':'auc','learning_rate':.05?}
#?訓練模型?
num_round=50?
from?datetime?import?datetime?
start?=?datetime.now()?
xg=xgb.train(parameters,dtrain,num_round)?
stop?=?datetime.now()
#?模型執(zhí)行時間
execution_time_xgb?=?stop-start?
execution_time_xgb
datetime.timedelta(seconds=3,
microseconds=721741)
datetime.timedelta( , , ) 表示( 天, 秒, 微秒)?,F(xiàn)在用模型對測試集進行預測。
ypred=xg.predict(dtest)?
ypred
array([0.0600442, 0.1247908, 0.6246425, ...,
0.157481 , 0.0610904, 0.6457621 ],
dtype=float32)
將概率轉(zhuǎn)換為1 或 0 ,將閾值設置為 0.5 ,并模型的計算精度。
for?i?in?range(0,9769):?
????if?ypred[i]>=.5:?
???????ypred[i]=1?
????else:?
???????ypred[i]=0?
from?sklearn.metrics?import?accuracy_score?
accuracy_xgb?=?accuracy_score(y_test,ypred)?
accuracy_xgb
0.8626266762206981
LightGBM 應用
準備訓練數(shù)據(jù)及設置 LightGBM 的參數(shù),并訓練模型。這里將 XGBOOST 和 LightGBM 中的 max_depth 設置均為 7,這樣運用控制變量思想以更好地比較兩個算法。
train_data=lgb.Dataset(x_train,label=y_train)
param?=?{'num_leaves':150,?'objective':'binary',
?????????'max_depth':7,'learning_rate':.05,'max_bin':200}?
param['metric']?=?['?auc',?'binary_logloss']
num_round=50?
start=datetime.now()?
lgbm=lgb.train(param,train_data,num_round)?
stop=datetime.now()
#模型執(zhí)行時間
execution_time_lgbm?=?stop-start?
execution_time_lgbm

在測試集上預測數(shù)據(jù)
ypred2=lgbm.predict(x_test)?
#?ypred2[0:5]?
#?顯示前?5?個預測
#?將概率轉(zhuǎn)換為?0?或?1
?for?i?in?range(0,9769):?
????if?ypred2[i]>=.5:?#?將閾值設置為?.5?
???????ypred2[i]=1?
????else:???
???????ypred2[i]=0
#?計算精度
accuracy_lgbm?=accuracy_score(ypred2,y_test)?
y_test.value_counts()
0 7376
1 2393
Name: Income, dtype: int64
計算 XGBOOST 的 roc_auc_score
from?sklearn.metrics?import?roc_auc_score?
auc_xgb?=?roc_auc_score(y_test,ypred)?
auc_xgb
0.7670270211471818
計算 LightGBM 的 roc_auc_score
auc_lgbm?=?roc_auc_score(y_test,ypred2)
auc_lgbm
0.761978912192376
comparison_dict?=?{'accuracy?score':(accuracy_lgbm,accuracy_xgb),
???????????????????'auc?score':(auc_lgbm,auc_xgb),
???????????????????'execution?time':(execution_time_lgbm,execution_time_xgb)}
#?創(chuàng)建一個數(shù)據(jù)幀'comparison_df'來比較Lightgbm和xgb的性能。?
comparison_df?=DataFrame(comparison_dict)
comparison_df.index?=?[?'LightGBM',?'xgboost']?
性能對比
通過在 XGBOOST 上應用 LightGBM,準確性和 auc 分數(shù)僅略有增加,但訓練過程的執(zhí)行時間存在顯著差異。LightGBM 比 XGBOOST 快近 7 倍,并且在處理大型數(shù)據(jù)集時是一種更好的方法。
當在限時比賽中處理大型數(shù)據(jù)集時,這將是一個巨大的優(yōu)勢。
08 寫在最后
本文簡單介紹了 LightGBM 的基本概念。LightGBM 算法除了比 XGBOOST 更準確和更省時外,還優(yōu)于現(xiàn)有的其他 boosting 算法。比較建議你在使用其他 boosting 算法時,也嘗試使用 LightGBM 算法,然后比較它們的優(yōu)劣。
參考資料
git for windows: https://git-scm.com/download/win
[2]cmake: https://cmake.org/
往期精彩回顧
適合初學者入門人工智能的路線及資料下載 (圖文+視頻)機器學習入門系列下載 中國大學慕課《機器學習》(黃海廣主講) 機器學習及深度學習筆記等資料打印 《統(tǒng)計學習方法》的代碼復現(xiàn)專輯 AI基礎下載 機器學習交流qq群955171419,加入微信群請掃碼:
