LightGBM參數及分佈式

Xgboost的缺點

(1)在每一次迭代的時候,都需要遍歷整個訓練數據多次。如果把整個訓練數據裝進內存則會限制訓練數據的大小;如果不裝進內存,反覆地讀寫訓練數據又會消耗非常大的時間。
(2)預排序方法(pre-sorted):首先,空間消耗大。這樣的算法需要保存數據的特徵值,還保存了特徵排序的結果(例如排序後的索引,爲了後續快速的計算分割點),這裏需要消耗訓練數據兩倍的內存。其次,時間上也有較大的開銷,在遍歷每一個分割點的時候,都需要進行分裂增益的計算,消耗的代價大。最後,對cache優化不友好。在預排序後,特徵對梯度的訪問是一種隨機訪問,並且不同的特徵訪問的順序不一樣,無法對cache進行優化。同時,在每一層長樹的時候,需要隨機訪問一個行索引到葉子索引的數組,並且不同特徵訪問的順序也不一樣,也會造成較大的cache miss。

很多 boosting 工具使用 pre-sorted based 算法進行決策樹學習。這是一種簡單的解決方案,但不易於優化。LightGBM 使用 histogram based 算法,將連續特徵(屬性)值裝進離散的容器中,從而加速訓練流程並減少內存使用。

LightGBM的優化

基於Histogram的決策樹算法
直方圖做差加速
基於直方圖的稀疏特徵優化
直接支持類別特徵(Categorical Feature)
帶深度限制的Leaf-wise的葉子生長策略
Cache命中率優化
多線程優化

基於Histogram的決策樹算法:把連續的浮點特徵值離散化成 k 個整數,同時構造一個寬度爲 k 的直方圖。在遍歷數據的時候,根據離散化後的值作爲索引在直方圖中累積統計量,當遍歷一次數據後,直方圖累積了需要的統計量,然後根據直方圖的離散值,遍歷尋找最優的分割點。 當然, histogram 算法也有缺點,它不能找到很精確的分割點,訓練誤差沒有 pre-sorted 好。但從實驗結果來看, histogram 算法在測試集的誤差和 pre-sorted 算法差異並不是很大,甚至有時候效果更好。實際上可能決策樹對於分割點的精確程度並不太敏感,而且較「粗」的分割點也自帶正則化的效果。

直方圖做差加速:一個葉子的直方圖可以由它的父親節點的直方圖與它兄弟節點的直方圖做差得到,提升一倍速度。

基於直方圖的稀疏特徵優化:對於稀疏特徵,只需要 O ( 2 # n o n _ z e r o _ d a t a ) O(2 * \#non\_zero\_data) 來構建直方圖。

直接支持類別特徵(Categorical Feature):LightGBM 可以直接輸入類別特徵,不需要額外的 0/1 展開,並在決策樹算法上增加了類別特徵的決策規則。

Level-wise分裂:過一次數據可以同時分裂同一層的葉子,容易進行多線程優化,也好控制模型複雜度,不容易過擬合。但實際上Level-wise是一種低效的算法,因爲它不加區分的對待同一層的葉子,帶來了很多沒必要的開銷,因爲實際上很多葉子的分裂增益較低,沒必要進行搜索和分裂
Leaf-wise分裂:一種更高效的策略,每次找到當前所有葉子中,分裂增益最大的一個葉子,然後分裂,如此循環。因此同Level-wise相比,在分裂次數相同的情況下,Leaf-wise可以降低更多的誤差,得到更好的精度。Leaf-wise的缺點是可能會長出比較深的決策樹,產生過擬合。因此LightGBM在Leaf-wise之上增加了一個最大深度的限制,在保證高效率的同時防止過擬合。

多線程優化:在特徵並行時,在本地保存全部數據,避免對數據切分結果的通信。在數據並行時,使用分散規約(Reduce scatter)——把直方圖合併的任務、分攤到不同的機器,降低通信和計算,並利用直方圖做差,進一步減少了一半的通信量。基於投票的數據並行(Parallel Voting)則進一步優化數據並行中的通信代價,使通信代價變成常數級別。
特徵並行:在不同機器的各份全量的特徵集合上,分別尋找最優的分割點,然後在機器間同步最優的分割點數據並行:讓不同的機器先在本地構造直方圖,然後進行全局的合併,最後在合併的直方圖上面尋找最優分割點。

LightGBM調參

https://lightgbm.readthedocs.io/en/latest/
https://github.com/Microsoft/LightGBM/
application:目標函數/損失函數。

boosting‘gbdt’, traditional Gradient Boosting Decision Tree;‘dart’, Dropouts meet Multiple Additive Regression Trees;‘goss’, Gradient-based One-Side Sampling;‘rf’, Random Forest。

earning_rate:學習率,默認值:0.1。最開始可以設置得大一些,如0.1。調整完其他參數之後,再將此參數調小。取值範圍:0.01~0.3。

max_depth:樹的深度,默認值:-1。取值範圍3~8,不超過10。

num_leaves:葉子節點數,該參數樹控制樹模型複雜性的重要參數,默認值31。可以設置爲2的n次冪,如 2 m a x _ d e p t h 2^{max\_{depth}} ,但要大於分類的類別數。理論上,可以通過設定 n u m _ l e a v e s = 2 m a x _ d e p t h num\_{leaves} = 2^{max\_{depth}} 去轉變成爲depth-wise tree。但這樣容易過擬合,因爲當這兩個參數相等時,leaf-wise tree的深度要遠超depth-wise tree。因此在調參時,往往會把 num_leaves的值設置得小於 2 m a x _ d e p t h 2^{max\_{depth}} 。例如當max_depth=6時,depth-wise tree可以有個好的準確率,但如果把 num_leaves 設成 127 會導致過擬合,要是把這個參數設置成 70或 80 卻有可能獲得比depth-wise tree有更好的準確率。事實上,當使用 leaf-wise tree時,可以忽略depth這個概念,畢竟leaves跟depth之間沒有一個確切的關係。

min_data_in_leaf:一個葉子上的最少樣本數,該參數是避免leaf-wise tree算法過擬合的重要參數,默認值20。在分析大型數據集時,該值取值在 [ , ] [數百,數千] 較爲合適。該值受到訓練集數量和num_leaves這兩個值的影響。把該參數設的更大、能避免生長出過深的樹,但也要避免欠擬合。

min_sum_hessian_in_leaf:使一個結點分裂的最小海森值之和,即葉子節點的最小權重和。

feature_fraction:特徵列隨機採樣比例,默認值:1.0。通常在0.5-0.9之間調節。
bagging_fraction:不進行重採樣的情況下,樣本數據隨機採樣比例,默認值:1.0。通常在0.5-0.9之間調節。

bagging_freq:bagging的頻次,默認值:0。0表示禁用bagging,正整數表示每k輪迭代,進行一次 bagging,通常取值3-5。

lambda_l1:對參數的L1正則化限制。
lambda_l2:對參數的L2正則化限制。

min_split_to_gain:分裂的最小增益,默認值:0.1。

early_stopping_round:早停輪次。如果一個驗證數據的某個度量,在最近的early_stopping_round 次中沒有提高,模型將停止訓練。

max_cat_group:在 group 邊界上找到分割點;當類別數量很多時,找分割點很容易過擬合。

drop_rate:Dart 的丟棄率。
skip_drop:Dart 的跳過丟棄步驟的概率。
max_drop:Dart 每次迭代最大丟棄數量。

max_bin:表示 feature 將存入的 bin 的最大數量。LightGBM 將根據 max_bin 自動壓縮內存。 例如, 如果 maxbin=255, 那麼 LightGBM 將使用 uint8t 的特性值。
categorical_feature:如果 categorical_features = 0,1,2, 則列 0,1,2是 categorical 變量。
ignore_column:與 categorical_features 類似,只不過不是將特定的列視爲categorical,而是完全忽略。
save_binary:這個參數爲 true 時,則數據集被保存爲二進制文件,下次讀數據時速度會變快。

https://lightgbm.readthedocs.io/en/latest/Parameters-Tuning.html

在這裏插入圖片描述

對於非平衡數據集:可以param[‘is_unbalance’]='true’