作者:韓信子@ShowMeAI
教程地址:http://www.showmeai.tech/tutorials/34
本文地址:http://www.showmeai.tech/article-detail/195
宣告:版權所有,轉載請聯絡平臺與作者並註明出處
引言
之前ShowMeAI對強大的boosting模型工具XGBoost做了介紹(詳見ShowMeAI文章圖解機器學習 | XGBoost模型詳解)。本篇我們來學習一下GBDT模型(詳見ShowMeAI文章 圖解機器學習 | GBDT模型詳解)的另一個進化版本:LightGBM。
LightGBM是微軟開發的boosting整合模型,和XGBoost一樣是對GBDT的優化和高效實現,原理有一些相似之處,但它很多方面比XGBoost有著更為優秀的表現。官方給出的這個工具庫模型的優勢如下:
- 更快的訓練效率
- 低記憶體使用
- 更高的準確率
- 支援並行化學習
- 可處理大規模資料
- 支援直接使用category特徵
下圖是一組實驗資料,在這份實驗中,LightGBM比XGBoost快將近10倍,記憶體佔用率大約為XGBoost的1/6,準確率也略有提升。
1.LightGBM動機
網際網路領域的演算法應用,通常背後都有海量的大資料。深度學習中一系列神經網路演算法,都是以mini-batch的方式喂資料迭代訓練的,總訓練資料量不受記憶體限制。
但我們用到的機器學習演算法,比如GBDT(參考ShowMeAI文章 GBDT詳解)在每一次迭代的時候,都需要遍歷整個訓練資料多次。
- 如果把整個訓練資料一次性裝進記憶體,會明顯限制訓練資料的大小。
- 如果不裝進記憶體,反覆地讀寫訓練資料又會消耗非常大的時間。
面對工業級海量的資料,普通的GBDT演算法無法滿足需求。LightGBM提出的主要原因之一,就是為了解決上述大資料量級下的GBDT訓練問題,以便工業實踐中能支撐大資料量並保證效率。
2.XGBoost優缺點
我們之前介紹過強大的XGBoost(詳見ShowMeAI文章圖解機器學習 | XGBoost模型詳解),但XGBoost也依舊存在一些缺點,LightGBM針對其中的一部分進行了調整優化。XGB優缺點歸納如下:
1)精確貪心演算法
輪迭代時,都需要遍歷整個訓練資料多次。如果把整個訓練資料裝進記憶體則會限制訓練資料的大小;如果不裝進記憶體,反覆地讀寫訓練資料又會消耗非常大的時間。
- 優點:可以找到精確的劃分條件。
- 缺點:計算量巨大、記憶體佔用巨大、易產生過擬合。
2)Level-wise生長方式
XGBoost採用Level-wise的增長策略:基於層進行生長,直到達到停止條件。這種增長策略方便平行計算每一層的分裂節點,提高了訓練速度,但同時也因為節點增益過小增加了很多不必要的分裂,增加了計算量。
- 優點:可以使用多執行緒、可以加速精確貪心演算法。
- 缺點:效率低下,可能產生不必要的葉結點。
3)對cache優化不友好
在預排序後,特徵對梯度的訪問是一種隨機訪問,並且不同的特徵訪問的順序不一樣,無法對cache進行優化。同時,在每一層長樹的時候,需要隨機訪問一個行索引到葉子索引的陣列,並且不同特徵訪問的順序也不一樣,也會造成較大的cache miss。
3.LightGBM優化點
上個部分其實也是LightGBM作者們,構建新演算法時著重優化的點。概括來說,LightGBM主要有以下特點:
- 基於Histogram的決策樹演算法
- 帶深度限制的Leaf-wise的葉子生長策略
- 直方圖做差加速
- 直接支援類別特徵(Categorical Feature)
- Cache命中率優化
- 基於直方圖的稀疏特徵優化
- 多執行緒優化
4.決策樹演算法
1)XGBoost:Pre-sorted演算法
XGBoost使用的是Pre-sorted演算法,能夠更精確的找到資料分隔點。
- 首先,對所有特徵按數值進行預排序。
- 其次,在每次的樣本分割時,用O(#data)的代價找到每個特徵的最優分割點。
- 最後,找到最後的特徵以及分割點,將資料分裂成左右兩個子節點。
這種pre-sorting演算法能夠準確找到分裂點,但是在空間和時間上有很大的開銷。
- 由於需要對特徵進行預排序並且需要儲存排序後的索引值(為了後續快速的計算分裂點),因此記憶體需要訓練資料的兩倍。
- 在遍歷每一個分割點的時候,都需要進行分裂增益的計算,消耗的代價大。
2)LightGBM:直方圖演算法
LightGBM使用的是直方圖演算法(histogram algorithm),佔用的記憶體更低,資料分割的複雜度更低。直方圖演算法思想是:
- 將連續的浮點特徵離散成k個離散值,並構造寬度為k的Histogram。
- 遍歷訓練資料,統計每個離散值在直方圖中的累計統計量。
- 在進行特徵選擇時,只需要根據直方圖的離散值,遍歷尋找最優的分割點。
(1)記憶體優化
直方圖演算法可以很大程度降低記憶體消耗,它不僅不需要額外儲存預排序的結果,還可以只儲存特徵離散化後的值(一般用8位整型儲存就足夠了)。
如圖所示,用8位整型儲存,記憶體消耗可以降低為原來的1/8。
(2)計算量優化
應用直方圖演算法,計算代價也大幅降低,預排序演算法每遍歷一個特徵值就需要計算一次分裂的增益,而直方圖演算法只需要計算k次(k可以認為是常數),時間複雜度從O(#data#feature)直接優化到 O(k#features)。
(3)注意點
直方圖演算法的理解和注意點如下:
-
使用分桶bin替代原始資料相當於增加了正則化。
-
使用分桶bin意味著很多資料的細節特徵丟失,相似的資料如果劃分到相同的桶中,資料之間的差異就無法捕獲了。
-
分桶bin數量決定了正則化的程度,bin越少懲罰越嚴重,欠擬合風險越高。
-
因為預先設定了bin的範圍,構建直方圖時不需要對資料進行排序。
-
直方圖儲存「劃分閾值」、「當前bin內樣本數」、「當前bin內所有樣本的一階梯度和」。
-
閾值的選取是按照直方圖從小到大遍歷,使用了上面的一階梯度和,目的是得到劃分之後△loss最大的特徵及閾值。
(4)直方圖演算法優缺點
-
Histogram演算法並不是完美的。由於特徵被離散化後,找到的並不是很精確的分割點,所以會對結果產生影響。但在實際的資料集上表明,離散化的分裂點對最終的精度影響並不大,甚至會好一些。原因在於decision tree本身就是一個弱學習器,採用Histogram演算法會起到正則化的效果,有效地防止模型的過擬合。
-
時間上的開銷由原來的O(#data#features)降到O(k#features)。由於離散化,#bin遠小於#data,因此時間上有很大的提升。
Histogram演算法還可以進一步加速。一個葉子節點的Histogram可以直接由父節點的Histogram和兄弟節點的Histogram做差得到。一般情況下,構造Histogram需要遍歷該葉子上的所有資料,通過該方法,只需要遍歷Histogram的k個捅。速度提升了一倍。
5.決策樹生長策略
1)樹生長策略調整
直方圖演算法之上,LightGBM進行進一步的優化。它沒有使用大多數GBDT工具使用的按層生長(Level-wise)的決策樹生長策略,而使用了帶有深度限制的按葉子生長(Leaf-wise)演算法。
2)XGBoost:Level-wise
XGBoost採用的是Level-wise(按層生長)策略生長的,能夠同時分裂同一層的葉子,從而進行多執行緒優化,不容易過擬合。
但不加區分的對待同一層的葉子,帶來了很多沒必要的開銷。因為實際上很多葉子的分裂增益較低,沒必要進行搜尋和分裂。
3)LightGBM:Leaf-wise
LightGBM採用Leaf-wise(按葉子生長)生長策略,每次從當前所有葉子中找到分裂增益最大(一般也是資料量最大)的一個葉子,然後分裂,如此迴圈。
同Level-wise相比,在分裂次數相同的情況下,Leaf-wise可以降低更多的誤差,得到更好的精度。Leaf-wise的缺點是可能會長出比較深的決策樹,產生過擬合。因此LightGBM在Leaf-wise之上增加了一個最大深度的限制,在保證高效率的同時防止過擬合。
6.直方圖差加速
LightGBM另一個優化是Histogram(直方圖)做差加速。整個構建過程中可以觀察到:一個葉子的直方圖可以由它的父親節點的直方圖與它兄弟的直方圖做差得到。
一般來說構造直方圖,需要遍歷該葉子上的所有資料,但直方圖做差僅需遍歷直方圖的k個桶。利用上述特徵,LightGBM可以在構造一個葉子的直方圖後,可以用非常微小的代價得到它兄弟葉子的直方圖,在速度上可以提升一倍。
7.類別型特徵支援
大多數機器學習工具都無法直接支援類別型特徵,我們會先將其編碼再做後續建模,如果使用one-hot這種編碼方式還會降低空間和時間效率。
LightGBM優化了對類別型特徵的支援,可以直接輸入類別特徵,不需要額外的編碼或one-hot 0/1展開。並在決策樹演算法上增加了類別型特徵的決策規則。
1)樹模型與one-hot編碼
one-hot編碼是處理類別特徵的一個通用方法,然而在樹模型中,這可能並不一定是一個好的方法,尤其當類別特徵中類別個數很多的情況下,主要的問題是:
問題1:可能無法在這個類別特徵上進行切分。
使用one-hot編碼的話,意味著在每一個決策節點上只能使用one vs rest(例如是不是男性,是不是一線城市等)的切分方式。當類別值很多時,每個類別上的資料可能會比較少,這時候切分會產生不平衡,這意味著切分增益也會很小。
問題2:影響決策樹的學習。
就算可以在這個類別特徵進行切分,也會把資料切分到很多零碎的小空間上,如下左圖所示。而決策樹學習時利用的是統計資訊,在這些資料量小的空間上,統計資訊不準確,學習會變差。但如果使用下右圖的分裂方式,資料會被切分到兩個比較大的空間,進一步的學習也會更好。
圈中的數值表示該結點內的資料。右圖中葉子節點 X=A || X=C 的含義是 X=A 或者 X=C 放到左孩子,其餘放到右孩子。
2)LightGBM類別型特徵處理方式
LightGBM採用了Many vs Many的切分方式解決one-hot編碼帶來的問題,實現了類別特徵的最優切分。用LightGBM可以直接輸入類別特徵,併產生上右圖的效果。
在1個k維的類別特徵中尋找最優切分,樸素的列舉演算法的複雜度是 \(O(2^k)\),而LightGBM採用瞭如 On Grouping For Maximum Homogeneity的方法實現了 \(O(k\log k)\) 的演算法。
演算法流程如圖所示:
-
①在列舉分割點之前,先把直方圖按每個類別的均值進行排序。
-
②接著按照均值的結果依次列舉最優分割點。
從下圖可以看到,Sum(y)/Count(y)為類別的均值。當然,這個方法很容易過擬合,所以在LightGBM中加入了很多對這個方法的約束和正則化。
求解類別型特徵的最優切分的具體流程如下:
① 離散特徵建立直方圖的過程
統計該特徵下每一種離散值出現的次數,並從高到低排序,並過濾掉出現次數較少的特徵值。然後為每一個特徵值,建立一個bin容器,對於在bin容器內出現次數較少的特徵值直接過濾掉,不建立bin容器。
② 計算分裂閾值的過程
-
先看該特徵下劃分出的bin容器的個數,如果bin容器的數量小於4,直接使用one vs other方式,逐個掃描每一個bin容器,找出最佳分裂點。
-
對於bin容器較多的情況,先進行過濾,只讓子集合較大的bin容器參加劃分閾值計算,對每一個符合條件的bin容器進行公式計算,得到一個值,根據該值對bin容器從小到大進行排序,然後分從左到右、從右到左進行搜尋,得到最優分裂閾值。公式如下:
這裡為什麼不是label的均值呢?其實上例中只是為了便於理解,只針對了學習一棵樹且是迴歸問題的情況。這時候一階導數是Y,二階導數是1),
- 沒有搜尋所有的bin容器,而是設定了一個搜尋bin容器數量的上限值,程式中設定是32,即引數max_num_cat。
- LightGBM中對離散特徵實行的是many vs many 策略,這32個bin中最優劃分的閾值的左邊或者右邊所有的bin容器就是一個many集合,而其他的bin容器就是另一個many集合。
③ 對於連續特徵,劃分閾值只有一個。對於離散值可能會有多個劃分閾值,每一個劃分閾值對應著一個bin容器編號。
當使用離散特徵進行分裂時,只要資料樣本對應的bin容器編號在這些閾值對應的bin集合之中,這條資料就加入分裂後的左子樹,否則加入分裂後的右子樹。
8.並行支援與優化
LightGBM原生支援並行學習,目前支援「特徵並行」和「資料並行」的兩種,LightGBM針對這兩種並行方法都做了優化。
-
特徵並行:在不同機器在不同的特徵集合上分別尋找最優的分割點,然後在機器間同步最優的分割點。
-
資料並行:讓不同的機器先在本地構造直方圖,然後進行全域性的合併,最後在合併的直方圖上面尋找最優分割點。
1)特徵並行
LightGBM在特徵並行演算法中,通過在本地儲存全部資料避免對資料切分結果的通訊。
2)資料並行
Lightgbm在資料並行中使用分散規約(Reduce scatter)把直方圖合併的任務分攤到不同的機器,降低通訊和計算,並利用直方圖做差,進一步減少了一半的通訊量。
基於投票的資料並行則進一步優化資料並行中的通訊代價,使通訊代價變成常數級別。在資料量很大的時候,使用投票並行可以得到非常好的加速效果。
更具體的內容可以看NIPS2016的文章: A Communication-Efficient Parallel Algorithm for Decision Tree。
9.網路通訊優化
XGBoost由於採用Pre-sorted演算法,直接通訊代價比較大;LightGBM採用的histogram演算法通訊代價小,通過使用集合通訊演算法,能夠實現平行計算的線性加速。
10.參考資料
- https://www.zhihu.com/question/51644470
- https://zhuanlan.zhihu.com/p/34698733
- https://lightgbm.readthedocs.io/en/latest/Features.html
- https://papers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree.pdf
- https://huangzhanpeng.github.io/2018/01/04/A-Highly-Ef%EF%AC%81cient-Gradient-Boosting-Decision-Tree/
- https://www.msra.cn/zh-cn/news/features/lightgbm-20170105
更多監督學習的演算法模型總結可以檢視ShowMeAI的文章 AI知識技能速查 | 機器學習-監督學習。
ShowMeAI相關文章推薦
- 1.機器學習基礎知識
- 2.模型評估方法與準則
- 3.KNN演算法及其應用
- 4.邏輯迴歸演算法詳解
- 5.樸素貝葉斯演算法詳解
- 6.決策樹模型詳解
- 7.隨機森林分類模型詳解
- 8.迴歸樹模型詳解
- 9.GBDT模型詳解
- 10.XGBoost模型最全解析
- 11.LightGBM模型詳解
- 12.支援向量機模型詳解
- 13.聚類演算法詳解
- 14.PCA降維演算法詳解