Ⅰ LightGBM(lgb)介紹
GBDT (Gradient Boosting Decision Tree) 是機器學習中一個長盛不衰的模型,其主要思想是利用弱分類器(決策樹)迭代訓練以得到最優模型,該模型具有訓練效果好、不易過擬合等優點。GBDT不僅在工業界應用廣泛,通常被用於多分類、點擊率預測、搜索排序等任務;在各種數據挖掘競賽中也是致命武器,據統計Kaggle上的比賽有一半以上的冠軍方案都是基於GBDT。而LightGBM(Light Gradient Boosting Machine)是一個實現GBDT演算法的框架,支持高效率的並行訓練,並且具有更快的訓練速度、更低的內存消耗、更好的准確率、支持分布式可以快速處理海量數據等優點。
1.1 LightGBM提出的動機
常用的機器學習演算法,例如神經網路等演算法,都可以以mini-batch的方式訓練,訓練數據的大小不會受到內存限制。而GBDT在每一次迭代的時候,都需要遍歷整個訓練數據多次。如果把整個訓練數據裝進內存則會限制訓練數據的大小;如果不裝進內存,反復地讀寫訓練數據又會消耗非常大的時間。尤其面對工業級海量的數據,普通的GBDT演算法是不能滿足其需求的。
LightGBM提出的主要原因就是為了解決GBDT在海量數據遇到的問題,讓GBDT可以更好更快地用於工業實踐。
1.2 XGBoost的缺點及LightGBM的優化
(1)XGBoost的缺點
在LightGBM提出之前,最有名的GBDT工具就是XGBoost了,它是基於預排序方法的決策樹演算法。這種構建決策樹的演算法基本思想是:
這樣的預排序演算法的優點是能精確地找到分割點。但是缺點也很明顯:
首先,空間消耗大。這樣的演算法需要保存數據的特徵值,還保存了特徵排序的結果(例如,為了後續快速的計算分割點,保存了排序後的索引),這就需要消耗訓練數據兩倍的內存。
其次,時間上也有較大的開銷,在遍歷每一個分割點的時候,都需要進行分裂增益的計算,消耗的代價大。
最後,對cache優化不友好。在預排序後,特徵對梯度的訪問是一種隨機訪問,並且不同的特徵訪問的順序不一樣,無法對cache進行優化。同時,在每一層長樹的時候,需要隨機訪問一個行索引到葉子索引的數組,並且不同特徵訪問的順序也不一樣,也會造成較大的cache miss。
(2)LightGBM的優化
為了避免上述XGBoost的缺陷,並且能夠在不損害准確率的條件下加快GBDT模型的訓練速度,lightGBM在傳統的GBDT演算法上進行了如下優化:
下面我們就詳細介紹以上提到的lightGBM優化演算法。
2.1 基於Histogram的決策樹演算法
(1)直方圖演算法
Histogram algorithm應該翻譯為直方圖演算法,直方圖演算法的基本思想是:先把連續的浮點特徵值離散化成 個整數,同時構造一個寬度為 的直方圖。在遍歷數據的時候,根據離散化後的值作為索引在直方圖中累積統計量,當遍歷一次數據後,直方圖累積了需要的統計量,然後根據直方圖的離散值,遍歷尋找最優的分割點。
直方圖演算法簡單理解為:首先確定對於每一個特徵需要多少個箱子(bin)並為每一個箱子分配一個整數;然後將浮點數的范圍均分成若干區間,區間個數與箱子個數相等,將屬於該箱子的樣本數據更新為箱子的值;最後用直方圖(#bins)表示。看起來很高大上,其實就是直方圖統計,將大規模的數據放在了直方圖中。
我們知道特徵離散化具有很多優點,如存儲方便、運算更快、魯棒性強、模型更加穩定等。對於直方圖演算法來說最直接的有以下兩個優點:
當然,Histogram演算法並不是完美的。由於特徵被離散化後,找到的並不是很精確的分割點,所以會對結果產生影響。但在不同的數據集上的結果表明,離散化的分割點對最終的精度影響並不是很大,甚至有時候會更好一點。原因是決策樹本來就是弱模型,分割點是不是精確並不是太重要;較粗的分割點也有正則化的效果,可以有效地防止過擬合;即使單棵樹的訓練誤差比精確分割的演算法稍大,但在梯度提升(Gradient Boosting)的框架下沒有太大的影響。
(2)直方圖做差加速
LightGBM另一個優化是Histogram(直方圖)做差加速。一個葉子的直方圖可以由它的父親節點的直方圖與它兄弟的直方圖做差得到,在速度上可以提升一倍。通常構造直方圖時,需要遍歷該葉子上的所有數據,但直方圖做差僅需遍歷直方圖的k個桶。在實際構建樹的過程中,LightGBM還可以先計算直方圖小的葉子節點,然後利用直方圖做差來獲得直方圖大的葉子節點,這樣就可以用非常微小的代價得到它兄弟葉子的直方圖。
注意:XGBoost 在進行預排序時只考慮非零值進行加速,而 LightGBM 也採用類似策略:只用非零特徵構建直方圖。
2.2 帶深度限制的 Leaf-wise 演算法
在Histogram演算法之上,LightGBM進行進一步的優化。首先它拋棄了大多數GBDT工具使用的按層生長 (level-wise) 的決策樹生長策略,而使用了帶有深度限制的按葉子生長 (leaf-wise) 演算法。
XGBoost 採用 Level-wise 的增長策略,該策略遍歷一次數據可以同時分裂同一層的葉子,容易進行多線程優化,也好控制模型復雜度,不容易過擬合。但實際上Level-wise是一種低效的演算法,因為它不加區分的對待同一層的葉子,實際上很多葉子的分裂增益較低,沒必要進行搜索和分裂,因此帶來了很多沒必要的計算開銷。
LightGBM採用Leaf-wise的增長策略,該策略每次從當前所有葉子中,找到分裂增益最大的一個葉子,然後分裂,如此循環。因此同Level-wise相比,Leaf-wise的優點是:在分裂次數相同的情況下,Leaf-wise可以降低更多的誤差,得到更好的精度;Leaf-wise的缺點是:可能會長出比較深的決策樹,產生過擬合。因此LightGBM會在Leaf-wise之上增加了一個最大深度的限制,在保證高效率的同時防止過擬合。
Gradient-based One-Side Sampling 應該被翻譯為單邊梯度采樣(GOSS)。GOSS演算法從減少樣本的角度出發,排除大部分小梯度的樣本,僅用剩下的樣本計算信息增益,它是一種在減少數據量和保證精度上平衡的演算法。
AdaBoost中,樣本權重是數據重要性的指標。然而在GBDT中沒有原始樣本權重,不能應用權重采樣。幸運的是,我們觀察到GBDT中每個數據都有不同的梯度值,對采樣十分有用。即梯度小的樣本,訓練誤差也比較小,說明數據已經被模型學習得很好了,直接想法就是丟掉這部分梯度小的數據。然而這樣做會改變數據的分布,將會影響訓練模型的精確度,為了避免此問題,提出了GOSS演算法。
GOSS是一個樣本的采樣演算法,目的是丟棄一些對計算信息增益沒有幫助的樣本留下有幫助的。根 據計算信息增益的定義,梯度大的樣本對信息增益有更大的影響。因此,GOSS在進行數據采樣的 時候只保留了梯度較大的數據,但是如果直接將所有梯度較小的數據都丟棄掉勢必會影響數據的總 體分布。所以,GOSS首先將要進行分裂的特徵的所有取值按照絕對值大小降序排序(XGBoost一 樣也進行了排序,但是LightGBM不用保存排序後的結果),選取絕對值最大的 個數 據。然後在剩下的較小梯度數據中隨機選擇 個數據。接著將這 個數據乘 以一個常數 這樣演算法就會更關注訓練不足的樣本, 而不會過多改變原數據集的分布。最 後使用這 個數據來計算信息增益。下圖是GOSS的具體演算法。
2.4 互斥特徵捆綁演算法
高維度的數據往往是稀疏的,這種稀疏性啟發我們設計一種無損的方法來減少特徵的維度。通常被 抹綁的特徵都是互斥的(即特徵不會同時為非零值,像one-hot),這樣兩個特徵描綁起來才不會 丟失信息。如果兩個特徵並不是完全互斥 (部分情況下兩個特徵都是非零值),可以用一個指標對 特徵不互斥程度進行像量,稱之為沖突比率,當這個值較小時,我們可以選擇把不完全互斥的兩個 特徵肺綁,而不影響最後的精度。
互斥特徵肺綁演算法 (Exclusive Feature Bundling, EFB) 指出如 果將一些特徵進行融合綁定,則可以降低特徵數量。這樣在構建直方圖時的時間復雜度從O(#data* # feature)變為 O(#data* # bundle), 這里 bundle 指特徵融合綁 定後特徵包的個數, 且 #bundle 遠小於 # feature 。
我們將論文《Lightgbm: A highly efficient gradient boosting decision tree》中沒有提到的優化方案,而在其相關論文《A communication-efficient parallel algorithm for decision tree》中提到的優化方案,放到本節作為LightGBM的工程優化來向大家介紹。
3.1 直接支持類別特徵
實際上大多數機器學習工具都無法直接支持類別特徵,一般需要把類別特徵,通過 one-hot 編碼,轉化到多維的0/1特徵,降低了空間和時間的效率。但我們知道對於決策樹來說並不推薦使用 one-hot 編碼,尤其當類別特徵中類別個數很多的情況下,會存在以下問題:
1,會產生樣本切分不平衡問題,導致切分增益非常小(即浪費了這個特徵)。使用 one-hot編碼,意味著在每一個決策節點上只能使用one vs rest(例如是不是狗,是不是貓等)的切分方式。
例如,動物類別切分後,會產生是否狗,是否貓等一系列特徵,這一系列特徵上只有少量樣本為 1,大量樣本為 0,這時候切分樣本會產生不平衡,這意味著切分增益也會很小。較小的那個切分樣本集,它占總樣本的比例太小,無論增益多大,乘以該比例之後幾乎可以忽略;較大的那個拆分樣本集,它幾乎就是原始的樣本集,增益幾乎為零。比較直觀的理解就是不平衡的切分和不切分沒有區別。
2,會影響決策樹的學習。因為就算可以對這個類別特徵進行切分,獨熱編碼也會把數據切分到很多零散的小空間上,如下圖左邊所示。而決策樹學習時利用的是統計信息,在這些數據量小的空間上,統計信息不準確,學習效果會變差。但如果使用下圖右邊的切分方法,數據會被切分到兩個比較大的空間,進一步的學習也會更好。下圖右邊葉子節點的含義是X=A或者X=C放到左孩子,其餘放到右孩子。
演算法流程如下圖所示,在枚舉分割點之前,先把直方圖按照每個類別對應的label均值進行排序; 然後按照排序的結果依次枚舉最優分割點。從下圖可以看到, 為類別的均值。當然,這個方法很容易過擬合,所以LightGBM裡面還增加了很多對於這個方法的約束和正則化。
在Expo數據集上的實驗結果表明,相比0/1展開的方法,使用LightGBM支持的類別特徵可以使訓練速度加速8倍,並且精度一致。更重要的是,LightGBM是第一個直接支持類別特徵的GBDT工具。
3.2 支持高效並行
(1)特徵並行
特徵並行的主要思想是不同機器在不同的特徵集合上分別尋找最優的分割點,然後在機器間同步最優的分割點。XGBoost使用的就是這種特徵並行方法。這種特徵並行方法有個很大的缺點:就是對數據進行垂直劃分,每台機器所含數據不同,然後使用不同機器找到不同特徵的最優分裂點,劃分結果需要通過通信告知每台機器,增加了額外的復雜度。
LightGBM 則不進行數據垂直劃分,而是在每台機器上保存全部訓練數據,在得到最佳劃分方案後可在本地執行劃分而減少了不必要的通信。具體過程如下圖所示。
(2)數據並行
傳統的數據並行策略主要為水平劃分數據,讓不同的機器先在本地構造直方圖,然後進行全局的合 並,最後在合並的直方圖上面尋找最優分割點。這種數據劃分有一個很大的缺點:通訊開銷過大。 如果使用點對點通信,一台機器的通訊開銷大約為 O(#machine* # feature*#bin) 如果使用集成的通信,則通訊開銷為
LightGBM在數據並行中使用分散規約 (Rece scatter) 把直方圖合並的任務分攤到不同的機器,降低通信和計算,並利用直方圖做差,進一步減少了一半的通信量。具體過程如下圖所示。
(3)投票並行
基於投票的數據並行則進一步優化數據並行中的通信代價,使通信代價變成常數級別。在數據量很大的時候,使用投票並行的方式只合並部分特徵的直方圖從而達到降低通信量的目的,可以得到非常好的加速效果。具體過程如下圖所示。
大致步驟為兩步:
XGBoost對cache優化不友好,如下圖所示。在預排序後,特徵對梯度的訪問是一種隨機訪問,並且不同的特徵訪問的順序不一樣,無法對cache進行優化。同時,在每一層長樹的時候,需要隨機訪問一個行索引到葉子索引的數組,並且不同特徵訪問的順序也不一樣,也會造成較大的cache miss。為了解決緩存命中率低的問題,XGBoost 提出了緩存訪問演算法進行改進。
而 LightGBM 所使用直方圖演算法對 Cache 天生友好:
4.1 優點
這部分主要總結下 LightGBM 相對於 XGBoost 的優點,從內存和速度兩方面進行介紹。
(1)速度更快
(2)內存更小
4.2 缺點
訓練配置 :
6307410個樣本做訓練集
訓練出的LightGBM模型文件及其含義解析:
第1棵樹
樹的結構
第二棵樹,含義參考第一棵樹
特徵重要性
重要性值是統計特徵在所有樹中作為中間節點(分裂節點)的分裂特徵且分裂增益為正的次數,可以理解成是對分裂作用越大的特徵越重要
參考自:
Microstrong
魚達爾
Ⅱ 易語言怎樣寫植物大戰僵屍(含源碼)
在使用易語言編寫植物大戰僵屍的輔助工具時,關鍵步驟涉及內存操作和地址查找。首先,通過游戲內存遍歷找到陽光值的基地址和偏移,這需要在游戲進程下使用內存分析工具CE,如4位元組搜索來定位150的地址。
接著,要實時追蹤陽光地址的變化,設置內存寫入斷點。在匯編指令中,通過分析add [eax+5560], ecx的代碼,確定一級偏移為5560,繼續尋找EAX的值。之後,使用十六進制搜索和經驗挑選出可能的基地址,如前綴不重復的地址,如001292AC和00FE7E60。
在找到可能的基地址後,通過添加指針並讀取數據驗證,如動態地址的計算公式:006A9EC0 + 768 + 5560。一旦確認正確,陽光數值在游戲和CE工具中應顯示一致,表明輔助工具已經成功生成。
在易語言中,創建窗口應用並集成內存讀寫模塊是實現輔助的核心步驟,通過繪制界面並編寫讀寫代碼來測試。最後,將這些代碼整合,生成的作弊器即可用於游戲。相比VC++,易語言提供了更為便捷的開發體驗。
以上是利用易語言編寫植物大戰僵屍輔助的基本過程,源碼和詳細教程可以在相關博客cnblogs.com/LyShark/p/1...找到。
Ⅲ 龍龍內存遍歷工具有毒嗎
龍龍內存遍歷工具
內存遍歷工具是一款安全的cpu檢測工具
用於對內存塊的數據進行逐個掃描