導語
LightGBM 作為近兩年微軟開源的模型,相比XGBoost有如下優點:
-
更快的訓練速度和更高的效率:LightGBM使用基於直方圖的演算法。例如,它將連續的特徵值分桶(buckets)裝進離散的箱子(bins),這是的訓練過程中變得更快。還有一點是LightGBM的分裂節點的方式與XGBoost不一樣。LGB避免了對整層節點分裂法,而採用了對增益最大的節點進行深入分解的方法。這樣節省了大量分裂節點的資源。下圖一是XGBoost的分裂方式,圖二是LightGBM的分裂方式。
-
更低的記憶體佔用:使用離散的箱子(bins)儲存並替換連續值導致更少的記憶體佔用。
-
更高的準確率(相比於其他任何提升演算法):它通過leaf-wise分裂方法產生比level-wise分裂方法更復雜的樹,這就是實現更高準確率的主要因素。然而,它有時候或導致過擬合,但是我們可以通過設定 max-depth 引數來防止過擬合的發生。
-
大資料處理能力:相比於XGBoost,由於它在訓練時間上的縮減,它同樣能夠具有處理大資料的能力。
-
支援並行學習
LightGBM 核心引數介紹
我們都知道,XGBoost 一共有三類引數通用引數,學習目標引數,Booster引數,那麼對於LightGBM,我們有核心引數,學習控制引數,IO引數,目標引數,度量引數,網路引數,GPU引數,模型引數,這裡我常修改的便是核心引數,學習控制引數,度量引數等。更詳細的請看LightGBM中文文件
核心引數
-
boosting
:也稱boost
,boosting_type
.預設是gbdt
。LGB裡面的boosting引數要比xgb多不少,我們有傳統的
gbdt
,也有rf
,dart
,doss
,最後兩種不太深入理解,但是試過,還是gbdt的效果比較經典穩定 -
num_thread
:也稱作num_thread
,nthread
.指定執行緒的個數。這裡官方文件提到,數字設定成cpu核心數比執行緒數訓練效更快(考慮到現在cpu大多超執行緒)。並行學習不應該設定成全部執行緒,這反而使得訓練速度不佳。
-
application
:預設為regression
。,也稱objective
,app
這裡指的是任務目標- regression
regression_l2
, L2 loss, alias=regression, mean_squared_error, mseregression_l1
, L1 loss, alias=mean_absolute_error, maehuber
, Huber lossfair
, Fair losspoisson
, Poisson regressionquantile
, Quantile regressionquantile_l2
, 類似於 quantile, 但是使用了 L2 loss
- binary, binary log loss classification application
- multi-class classification
multiclass
, softmax 目標函式, 應該設定好num_class
multiclassova
, One-vs-All 二分類目標函式, 應該設定好num_class
- cross-entropy application
xentropy
, 目標函式為 cross-entropy (同時有可選擇的線性權重), alias=cross_entropyxentlambda
, 替代引數化的 cross-entropy, alias=cross_entropy_lambda- 標籤是 [0, 1] 間隔內的任意值
- lambdarank, lambdarank application
- 在 lambdarank 任務中標籤應該為 int type, 數值越大代表相關性越高 (e.g. 0:bad, 1:fair, 2:good, 3:perfect)
label_gain
可以被用來設定 int 標籤的增益 (權重)
- regression
-
valid
:驗證集選用,也稱test
,valid_data
,test_data
.支援多驗證集,以,
分割 -
learning_rate
:也稱shrinkage_rate
,梯度下降的步長。預設設定成0.1,我們一般設定成0.05-0.2
之間 -
num_leaves
:也稱num_leaf
,新版lgb將這個預設值改成31,這代表的是一棵樹上的葉子數 -
device
:default=cpu, options=cpu, gpu- 為樹學習選擇裝置, 你可以使用 GPU 來獲得更快的學習速度
- Note: 建議使用較小的 max_bin (e.g. 63) 來獲得更快的速度
- Note: 為了加快學習速度, GPU 預設使用32位浮點數來求和. 你可以設定 gpu_use_dp=true 來啟用64位浮點數, 但是它會使訓練速度降低
- Note: 請參考 安裝指南 來構建 GPU 版本
學習控制引數
feature_fraction
:default=1.0, type=double, 0.0 < feature_fraction < 1.0, 也稱sub_feature
,colsample_bytree
- 如果 feature_fraction 小於 1.0, LightGBM 將會在每次迭代中隨機選擇部分特徵. 例如, 如果設定為 0.8, 將會在每棵樹訓練之前選擇 80% 的特徵
- 可以用來加速訓練
- 可以用來處理過擬合
bagging_fraction
:default=1.0, type=double, 0.0 < bagging_fraction < 1.0, 也稱sub_row
,subsample
- 類似於 feature_fraction, 但是它將在不進行重取樣的情況下隨機選擇部分資料
- 可以用來加速訓練
- 可以用來處理過擬合
- Note: 為了啟用 bagging, bagging_freq 應該設定為非零值
bagging_freq
: default=0, type=int, 也稱subsample_freq
- bagging 的頻率, 0 意味著禁用 bagging. k 意味著每 k 次迭代執行bagging
- Note: 為了啟用 bagging, bagging_fraction 設定適當
lambda_l1
:預設為0,也稱reg_alpha,表示的是L1正則化,double型別lambda_l2
:預設為0,也稱reg_lambda,表示的是L2正則化,double型別cat_smooth
: default=10, type=double- 用於分類特徵
- 這可以降低噪聲在分類特徵中的影響, 尤其是對資料很少的類別
度量函式
metric
: default={l2 for regression}, {binary_logloss for binary classification}, {ndcg for lambdarank}, type=multi-enum, options=l1, l2, ndcg, auc, binary_logloss, binary_error …l1
, absolute loss, alias=mean_absolute_error, mael2
, square loss, alias=mean_squared_error, msel2_root
, root square loss, alias=root_mean_squared_error, rmsequantile
, Quantile regressionhuber
, Huber lossfair
, Fair losspoisson
, Poisson regressionndcg
, NDCGmap
, MAPauc
, AUCbinary_logloss
, log lossbinary_error
, 樣本: 0 的正確分類, 1 錯誤分類multi_logloss
, mulit-class 損失日誌分類multi_error
, error rate for mulit-class 出錯率分類xentropy
, cross-entropy (與可選的線性權重), alias=cross_entropyxentlambda
, “intensity-weighted” 交叉熵, alias=cross_entropy_lambdakldiv
, Kullback-Leibler divergence, alias=kullback_leibler- 支援多指標, 使用 , 分隔
總的來說,我還是覺得LightGBM比XGBoost用法上差距不大。引數也有很多重疊的地方。很多XGBoost的核心原理放在LightGBM上同樣適用。
同樣的,Lgb也是有train()函式和LGBClassifier()與LGBRegressor()函式。後兩個主要是為了更加貼合sklearn的用法,這一點和XGBoost一樣。
GridSearch 調參
GridSearch 我在這裡有介紹,可以戳進去看看。我主要講講LGBClassifier的調參用法。
資料我上傳在這裡:直接上程式碼!
import pandas as pd
import lightgbm as lgb
from sklearn.grid_search import GridSearchCV # Perforing grid search
from sklearn.model_selection import train_test_split
train_data = pd.read_csv(`train.csv`) # 讀取資料
y = train_data.pop(`30`).values # 用pop方式將訓練資料中的標籤值y取出來,作為訓練目標,這裡的‘30’是標籤的列名
col = train_data.columns
x = train_data[col].values # 剩下的列作為訓練資料
train_x, valid_x, train_y, valid_y = train_test_split(x, y, test_size=0.333, random_state=0) # 分訓練集和驗證集
train = lgb.Dataset(train_x, train_y)
valid = lgb.Dataset(valid_x, valid_y, reference=train)
parameters = {
`max_depth`: [15, 20, 25, 30, 35],
`learning_rate`: [0.01, 0.02, 0.05, 0.1, 0.15],
`feature_fraction`: [0.6, 0.7, 0.8, 0.9, 0.95],
`bagging_fraction`: [0.6, 0.7, 0.8, 0.9, 0.95],
`bagging_freq`: [2, 4, 5, 6, 8],
`lambda_l1`: [0, 0.1, 0.4, 0.5, 0.6],
`lambda_l2`: [0, 10, 15, 35, 40],
`cat_smooth`: [1, 10, 15, 20, 35]
}
gbm = lgb.LGBMClassifier(boosting_type=`gbdt`,
objective = `binary`,
metric = `auc`,
verbose = 0,
learning_rate = 0.01,
num_leaves = 35,
feature_fraction=0.8,
bagging_fraction= 0.9,
bagging_freq= 8,
lambda_l1= 0.6,
lambda_l2= 0)
# 有了gridsearch我們便不需要fit函式
gsearch = GridSearchCV(gbm, param_grid=parameters, scoring=`accuracy`, cv=3)
gsearch.fit(train_x, train_y)
print("Best score: %0.3f" % gsearch.best_score_)
print("Best parameters set:")
best_parameters = gsearch.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
print(" %s: %r" % (param_name, best_parameters[param_name]))
複製程式碼