1.簡介
lightGBM包含兩個關鍵點:light即輕量級,GBM 梯度提升機
LightGBM 是一個梯度 boosting 框架,使用基於學習算法的決策樹。它可以說是分布式的,高效的,有以下優勢:
-
更快的訓練效率
-
低內存使用
-
更高的准確率
-
支持並行化學習
-
可處理大規模數據
與常用的機器學習算法進行比較:速度飛起
LightGBM 垂直地生長樹,即 leaf-wise,它會選擇最大 delta loss 的葉子來增長。

而以往其它基於樹的算法是水平地生長,即 level-wise

當生長相同的葉子時,Leaf-wise 比 level-wise 減少更多的損失。
高速,高效處理大數據,運行時需要更低的內存,支持 GPU
不要在少量數據上使用,會過擬合,建議 10,000+ 行記錄時使用。
2.特點
1)xgboost缺點
-
每輪迭代時,都需要遍歷整個訓練數據多次。如果把整個訓練數據裝進內存則會限制訓練數據的大小;如果不裝進內存,反復地讀寫訓練數據又會消耗非常大的時間。
-
預排序方法(pre-sorted):首先,空間消耗大。這樣的算法需要保存數據的特征值,還保存了特征排序的結果(例如排序后的索引,為了后續快速的計算分割點),這里需要消耗訓練數據兩倍的內存。其次時間上也有較大的開銷,在遍歷每一個分割點的時候,都需要進行分裂增益的計算,消耗的代價大。
-
對cache優化不友好。在預排序后,特征對梯度的訪問是一種隨機訪問,並且不同的特征訪問的順序不一樣,無法對cache進行優化。同時,在每一層長樹的時候,需要隨機訪問一個行索引到葉子索引的數組,並且不同特征訪問的順序也不一樣,也會造成較大的cache miss。
2)LightGBM優點
Histogram算法
直方圖算法的基本思想:先把連續的浮點特征值離散化成k個整數,同時構造一個寬度為k的直方圖。遍歷數據時,根據離散化后的值作為索引在直方圖中累積統計量,當遍歷一次數據后,直方圖累積了需要的統計量,然后根據直方圖的離散值,遍歷尋找最優的分割點。
帶深度限制的Leaf-wise的葉子生長策略
Level-wise過一次數據可以同時分裂同一層的葉子,容易進行多線程優化,也好控制模型復雜度,不容易過擬合。但實際上Level-wise是一種低效算法,因為它不加區分的對待同一層的葉子,帶來了很多沒必要的開銷,因為實際上很多葉子的分裂增益較低,沒必要進行搜索和分裂。
Leaf-wise則是一種更為高效的策略:每次從當前所有葉子中,找到分裂增益最大的一個葉子,然后分裂,如此循環。因此同Level-wise相比,在分裂次數相同的情況下,Leaf-wise可以降低更多的誤差,得到更好的精度。
Leaf-wise的缺點:可能會長出比較深的決策樹,產生過擬合。因此LightGBM在Leaf-wise之上增加了一個最大深度限制,在保證高效率的同時防止過擬合。
3.安裝
需要安裝64位的python才能進行安裝
自己進行編譯的方法參照:https://blog.csdn.net/testcs_dn/article/details/54176824
使用python可以直接pip安裝:
pip install lightgbm
4.參數
- max_depth, default=-1, type=int,樹的最大深度限制,防止過擬合
- min_data_in_leaf, default=20, type=int, 葉子節點最小樣本數,防止過擬合
- feature_fraction, default=1.0, type=double, 0.0 < feature_fraction < 1.0,隨機選擇特征比例,加速訓練及防止過擬合
- feature_fraction_seed, default=2, type=int,隨機種子數,保證每次能夠隨機選擇樣本的一致性
- bagging_fraction, default=1.0, type=double, 類似隨機森林,每次不重采樣選取數據
- lambda_l1, default=0, type=double, L1正則
- lambda_l2, default=0, type=double, L2正則
- min_split_gain, default=0, type=double, 最小切分的信息增益值
- top_rate, default=0.2, type=double,大梯度樹的保留比例
- other_rate, default=0.1, type=int,小梯度樹的保留比例
- min_data_per_group, default=100, type=int,每個分類組的最小數據量
- max_cat_threshold, default=32, type=int,分類特征的最大閾值
- num_leaves:默認 31,因為LightGBM使用的是leaf-wise的算法,因此在調節樹的復雜程度時,使用的是num_leaves而不是max_depth。
大致換算關系:num_leaves = 2^(max_depth)。它的值的設置應該小於2^(max_depth),否則可能會導致過擬合。 - 對於非平衡數據集:可以param['is_unbalance']='true’
- early_stopping_round:如果一次驗證數據的一個度量在最近的
early_stopping_round回合中沒有提高,模型將停止訓練,加速分析,減少過多迭代 - application(objective):選擇 regression: 回歸時,binary: 二分類時,multiclass: 多分類時
- num_class:多分類的分類數
- learning_rate:如果一次驗證數據的一個度量在最近的
early_stopping_round回合中沒有提高,模型將停止訓練,常用 0.1, 0.001, 0.003… - verbose_eval:type=int,輸出日志詳細情況,多少條數據輸出一條記錄
5.比較

6.調參
下表對應了 Faster Speed ,better accuracy ,over-fitting 三種目的時,可以調的參數
| Faster Speed | better accuracy | over-fitting |
|---|---|---|
將 max_bin 設置小一些 |
用較大的 max_bin |
max_bin 小一些 |
num_leaves 大一些 |
num_leaves 小一些 |
|
用 feature_fraction 來做 sub-sampling |
用 feature_fraction |
|
用 bagging_fraction 和 bagging_freq |
設定 bagging_fraction 和 bagging_freq |
|
| training data 多一些 | training data 多一些 | |
用 save_binary 來加速數據加載 |
直接用 categorical feature | 用 gmin_data_in_leaf 和 min_sum_hessian_in_leaf |
| 用 parallel learning | 用 dart | 用 lambda_l1, lambda_l2 ,min_gain_to_split 做正則化 |
num_iterations 大一些,learning_rate 小一些 |
用 max_depth 控制樹的深度 |
7.例子
params={ "learning_rate":0.1, "lambda_l1":0.1, "lambda_l2":0.2, 'num_leaves':20, "max_depth":4, "objective":"multiclass", "num_class":11, } param['is_unbalance']='true' param['metric'] = 'auc' clf=lgb.train(params,train_data,num_boost_round=100000,early_stopping_rounds=50,verbose_eval=20) pred = clf.predict(X_test,num_iteration=clf.best_iteration)
8.自動尋優調參
現在最新的lightgbm python包已經更新到了0.2版本,支持sklearn的自動尋優調參
import lightgbm as lgb import pandas as pd from sklearn.metrics import mean_squared_error from sklearn.model_selection import GridSearchCV estimator = lgb.LGBMRegressor(objective='regression',colsample_bytree=0.8,subsample=0.9,subsample_freq=5) param_grid={ 'learning_rate':[0.01,0.02,0.05,0.1], 'n_estimators' :[1000,2000,3000,4000,5000], 'num_leaves':[128,1024,4096] } fit_param={'categorical_feature':[0,1,2,3,4,5]} gbm = GridSearchCV(estimator,param_grid,fit_params=fit_param,n_jobs=5,refit=True) gbm.fit(X_lgb,y_lgb) print('.....................................cv results.......................') print(gbm.cv_results_)
9.特征重要性
# 放入訓練的屬性以及分類的特征值 import_rate = clf.feature_importance() # 轉化為百分比 importance = np.array(import_rate)/sum(import_rate)
