官方文檔
https://lightgbm.readthedocs.io/en/latest/index.html(微軟開源)
參考文檔:機(jī)器學(xué)習(xí)算法之LightGBM
https://www.biaodianfu.com/lightgbm.html
1 簡(jiǎn)介
LightGBM算法屬于GBDT模型的進(jìn)階,和XGBoost一樣采用損失函數(shù)的負(fù)梯度作為當(dāng)前決策樹的殘差近似值,去擬合新的決策樹。
因?yàn)镚BDT在每一次迭代的時(shí)候,都需要遍歷整個(gè)訓(xùn)練數(shù)據(jù)多次。如果把整個(gè)訓(xùn)練數(shù)據(jù)裝進(jìn)內(nèi)存則會(huì)限制訓(xùn)練數(shù)據(jù)的大??;如果不裝進(jìn)內(nèi)存,反復(fù)地讀寫訓(xùn)練數(shù)據(jù)又會(huì)消耗非常大的時(shí)間。因此,為了彌補(bǔ)普通的GBDT算法無法處理海量數(shù)據(jù)的問題,提出了LightGBM算法。
2 算法核心思想
2.1 XGBoost算法
XGBoost使用的是pre-sorted算法,能夠更精確的找到數(shù)據(jù)分隔點(diǎn)。
- 首先,對(duì)所有特征按數(shù)值進(jìn)行預(yù)排序。
- 其次,在每次的樣本分割時(shí),用O(# data)的代價(jià)找到每個(gè)特征的最優(yōu)分割點(diǎn)。
- 最后,找到最后的特征以及分割點(diǎn),將數(shù)據(jù)分裂成左右兩個(gè)子節(jié)點(diǎn)。
這種pre-sorting算法能夠準(zhǔn)確找到分裂點(diǎn),但是在空間和時(shí)間上有很大的開銷。 - 由于需要對(duì)特征進(jìn)行預(yù)排序并且需要保存排序后的索引值(為了后續(xù)快速的計(jì)算分裂點(diǎn)),因此內(nèi)存需要訓(xùn)練數(shù)據(jù)的兩倍。
- 在遍歷每一個(gè)分割點(diǎn)的時(shí)候,都需要進(jìn)行分裂增益的計(jì)算,消耗的代價(jià)大。
決策樹的生長(zhǎng)方式
XGBoost采用的是按層生長(zhǎng)level(depth)-wise生長(zhǎng)策略,能夠同時(shí)分裂同一層的葉子,從而進(jìn)行多線程優(yōu)化,不容易過擬合;但不加區(qū)分的對(duì)待同一層的葉子,帶來了很多沒必要的開銷。因?yàn)閷?shí)際上很多葉子的分裂增益較低,沒必要進(jìn)行搜索和分裂。
2.2 LightGBM算法
LightGBM使用的是histogram算法(直方圖算法),首先將連續(xù)的浮點(diǎn)數(shù)據(jù)轉(zhuǎn)換為bin數(shù)據(jù),具體過程是首先確定對(duì)于每一個(gè)特征需要多少的桶bin,然后均分,將屬于該桶的樣本數(shù)據(jù)更新為bin的值,最后用直方圖表示。(看起來很高大上,其實(shí)就是直方圖統(tǒng)計(jì),最后我們將大規(guī)模的數(shù)據(jù)放在了直方圖中)。
占用的內(nèi)存更低,數(shù)據(jù)分隔的復(fù)雜度更低。其思想是將連續(xù)的浮點(diǎn)特征離散成k個(gè)離散值,并構(gòu)造寬度為k的Histogram。然后遍歷訓(xùn)練數(shù)據(jù),統(tǒng)計(jì)每個(gè)離散值在直方圖中的累計(jì)統(tǒng)計(jì)量。在進(jìn)行特征選擇時(shí),只需要根據(jù)直方圖的離散值,遍歷尋找最優(yōu)的分割點(diǎn)。
使用直方圖算法的優(yōu)點(diǎn)
- 首先最明顯就是內(nèi)存消耗的降低,直方圖算法不僅不需要額外存儲(chǔ)預(yù)排序的結(jié)果;
- 而且可以只保存特征離散化后的值,而這個(gè)值一般用8位整型存儲(chǔ)就足夠了,內(nèi)存消耗可以降低為原來的1/8。
- 然后在計(jì)算上的代價(jià)也大幅降低,預(yù)排序算法每遍歷一個(gè)特征值就需要計(jì)算一次分裂的增益,而直方圖算法只需要計(jì)算k次(k可以認(rèn)為是常數(shù))。
決策樹的生長(zhǎng)方式
LightGBM采用leaf-wise生長(zhǎng)策略,每次從當(dāng)前所有葉子中找到分裂增益最大(一般也是數(shù)據(jù)量最大)的一個(gè)葉子,然后分裂,如此循環(huán)。因此同Level-wise相比,在分裂次數(shù)相同的情況下,Leaf-wise可以降低更多的誤差,得到更好的精度。Leaf-wise的缺點(diǎn)是可能會(huì)長(zhǎng)出比較深的決策樹,產(chǎn)生過擬合。因此LightGBM在Leaf-wise之上增加了一個(gè)最大深度的限制,在保證高效率的同時(shí)防止過擬合。
3 優(yōu)勢(shì)——相比較XGBoost
- 更快的訓(xùn)練效率
- 低內(nèi)存使用
- 更高的準(zhǔn)確率
- 支持并行化學(xué)習(xí)
- 可處理大規(guī)模數(shù)據(jù)
- 支持直接使用category特征
4 在Scikit-Learn與XGBoost對(duì)比
https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.HistGradientBoostingClassifier.html?highlight=lightgbm
histogram-based gradient boosting classification tree:基于直方圖的梯度提升分類樹
4.1 導(dǎo)入所需要的包和庫(kù)
from xgboost import XGBRegressor
import lightgbm as lgb
import numpy as np
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
4.2 加載鳶尾花數(shù)據(jù)
iris = load_iris()
data = iris.data
target = iris.target
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
4.3 分別創(chuàng)建XGB和LGB模型進(jìn)行訓(xùn)練
4.3.1 訓(xùn)練XGBoost
reg = XGBRegressor(
n_estimators = 20, # 迭代次數(shù)
learning_rate = 0.1, # 學(xué)習(xí)率
max_depth=5
)
reg.fit(X_train, y_train)
# 測(cè)試集預(yù)測(cè)
y_pred = reg.predict(X_test)
# 模型評(píng)估
print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
The rmse of prediction is: 0.2579017768469883
# feature importances
print('Feature importances:', list(reg.feature_importances_))
Feature importances: [0.008026785, 0.025713025, 0.7764279, 0.1898323]
網(wǎng)格搜索
estimator = XGBRegressor()
param_grid = {
'learning_rate':[0.2,0.5,0.8],
'n_estimators': np.arange(0,100,20)
}
reg = GridSearchCV(estimator, param_grid)
clf = reg.fit(X_train, y_train)
y_pred = clf.predict(X_test)
mean_squared_error(y_test, y_pred)
0.05894615685616801
4.3.2 LightGBM訓(xùn)練
gbm = lgb.LGBMRegressor(objective='regression', num_leaves=31, learning_rate=0.1, n_estimators=20)
gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1', early_stopping_rounds=5)
[1] valid_0's l1: 0.558965 valid_0's l2: 0.507722
Training until validation scores don't improve for 5 rounds
[2] valid_0's l1: 0.508315 valid_0's l2: 0.422938
[3] valid_0's l1: 0.469458 valid_0's l2: 0.354078
[4] valid_0's l1: 0.428637 valid_0's l2: 0.297129
[5] valid_0's l1: 0.397107 valid_0's l2: 0.251408
[6] valid_0's l1: 0.363512 valid_0's l2: 0.210417
[7] valid_0's l1: 0.334591 valid_0's l2: 0.179052
[8] valid_0's l1: 0.311293 valid_0's l2: 0.151726
[9] valid_0's l1: 0.288382 valid_0's l2: 0.130775
[10] valid_0's l1: 0.269027 valid_0's l2: 0.111078
[11] valid_0's l1: 0.250241 valid_0's l2: 0.097117
[12] valid_0's l1: 0.231755 valid_0's l2: 0.0847149
[13] valid_0's l1: 0.219546 valid_0's l2: 0.0744859
[14] valid_0's l1: 0.206336 valid_0's l2: 0.0668118
[15] valid_0's l1: 0.193833 valid_0's l2: 0.0604602
[16] valid_0's l1: 0.183163 valid_0's l2: 0.0551445
[17] valid_0's l1: 0.173473 valid_0's l2: 0.0503368
[18] valid_0's l1: 0.164622 valid_0's l2: 0.0465006
[19] valid_0's l1: 0.156789 valid_0's l2: 0.0433829
[20] valid_0's l1: 0.153458 valid_0's l2: 0.0419514
Did not meet early stopping. Best iteration is:
[20] valid_0's l1: 0.153458 valid_0's l2: 0.0419514
LGBMRegressor(n_estimators=20, objective='regression')
# 測(cè)試集預(yù)測(cè)
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)
# 模型評(píng)估
print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)
The rmse of prediction is: 0.20482033985501885
# feature importances
print('Feature importances:', list(gbm.feature_importances_))
Feature importances: [15, 9, 27, 21]
網(wǎng)格搜索,參數(shù)優(yōu)化
estimator = lgb.LGBMRegressor(num_leaves=31)
param_grid = {
'learning_rate':[0.2,0.5,0.8],
'n_estimators': np.arange(0,100,20)
}
gbm = GridSearchCV(estimator, param_grid)
clf = gbm.fit(X_train, y_train)
y_pred = clf.predict(X_test)
mean_squared_error(y_test, y_pred)
0.03318734265620019
?print('Best parameters found by grid search are:', reg.best_params_)
print('Best parameters found by grid search are:', gbm.best_params_)
Best parameters found by grid search are: {'learning_rate': 0.2, 'n_estimators': 20}
Best parameters found by grid search are: {'learning_rate': 0.2, 'n_estimators': 20}
4.4 總結(jié)
| model | 默認(rèn)參數(shù) | 網(wǎng)格搜索 | 網(wǎng)格搜索參數(shù) |
|---|---|---|---|
| XGBoost | 0.2579017768469883 | 0.05894615685616801 | 'learning_rate': 0.2, 'n_estimators': 20 |
| LightGBM | 0.20482033985501885 | 0.03318734265620019 | 'learning_rate': 0.2, 'n_estimators': 20 |
在評(píng)價(jià)標(biāo)準(zhǔn)為RMSE的情況下,從預(yù)測(cè)的精度來看,LightGBM明顯優(yōu)于XGBoost。