Spark隨機森林實現學習


前言

最近閱讀了spark mllib(版本:spark 1.3)中Random Forest的實現,發現在分布式的數據結構上實現迭代算法時,有些地方與單機環境不一樣。單機上一些直觀的操作(遞歸),在分布式數據上,必須進行優化,否則I/O(網絡,磁盤)會消耗大量時間。本文整理spark隨機森林實現中的相關技巧,方便后面回顧。

 

隨機森林算法概要

隨機森林算法的詳細實現和細節,可以參考論文Breiman 2001。這里簡單說說大體思路,方便理解代碼。

隨機森林是一個組裝(ensemble model)模型,內部的模型使用決策樹。基本思想是生成很多很多決策樹(構成森林),最后由這些決策數一起投票決定最終結果。生成樹的過程中,從行和列兩個方向添加隨機過程。行方向,在構建每棵樹前,使用有放回抽樣(稱為Bootstrapping),得到訓練數據。列方向,每次選擇切分點時,對feature進行無放回隨機抽樣,得到一個feature子集,在當前節點上,只使用這些子集對應的數據計算最優切分點。這也是為什么此算法稱為隨機森林,是不是很直觀。相比於單一決策樹,隨機森林有以下一些優點:

  1. 結果比較穩定,不容易出現過擬合;
  2. Out-Of-Bag error評估模型效果,無需交叉檢驗;
  3. 可得到feature重要性。

當然,為了得到上面的優點,必須付出計算開銷作為代價。在單機時代,使用隨機森林(R或scikit-learn)往往成本很高,但是現在有了spark,使得大規模,分布式迭代計算成為了可能,所以在spark上運用隨機森林是技術發展的必然結果!

 

Spark實現優化

spark在實現隨機森林時,采用了下面幾個優化策略:

  1. 切分點抽樣
  2. feature裝箱(bin)
  3. 分區統計
  4. 逐層計算(level-wise)

使用這些策略,原因在於RDD的數據時分布在不同服務器上,為了避免過多的I/O,必須在原始算法上做出一些優化,否則執行時間可能難以接受。下面分別詳細討論這三個優化策略。

 

切分點抽樣

此優化主要針對連續變量。先回憶一下一般的決策樹是如何對連續變量進行切分點選擇的。一般是先對feature進行排序,然后選取相鄰兩個數據之間的點作為切分點。如果在RDD上執行這個操作,不可避免會使用shuffle過程,此過程會帶來大量的網絡通訊。而且,一般RDD上的數據都很大,少則幾百萬,多則幾億到幾十億,甚至更多。在這樣的數量級上進行排序操作,想想也是醉了。所以,為了避免排序操作,mllib通過抽樣的方法,在樣本上進行排序,並且根據樣本,獲取切分點。據spark團隊反饋,使用此策略雖然犧牲了部分精度,但是在實際運用過程中,並沒有帶來過多的影響,模型效果可以接受。

 

feature裝箱

根據抽樣,得到切分點后,接下來是對feature進行裝箱操作,箱子就是由相鄰的樣本切分點構成。箱子的個數是非常小的,一般實際中采用30個左右。計算每個箱子中不同種類的占比,可以很快計算出最優切分點。

舉個例子,參考上面的示例數據,第一行是每個切分點的比例統計。基於上面的數據,可能生成3中切分情況,分別有棕,紅和綠色三行表示。如果需要計算棕色的切分情況,只需要按照第一行的組合方式,就可以很快的計算所出來。

 

分區統計

RDD分區中裝箱數據單獨統計后,可以通過reduce將每個分區的數據合並,得到總體的裝箱數據(通過mapPartition實現分區統計)。正是由於裝箱統計數據可以合並,所以可以很好的適應分布式數據環境,最后需要合並的數據也只是一些統計數據,不會帶來很大的網絡通訊開銷。

 

逐層計算

單機版本的決策數生成過程是通過遞歸調用(本質上是深度優先)的方式構造樹,在構造樹的同事,需要移動數據,將同一個子節點的數據移動到一起。此方法在分布式數據結構上無法有效的執行,而且也無法執行,因為數據太大,無法放在一起,所以在分布式存儲。mlib采用的策略是逐層構建樹節點(本質上是廣度優先),這樣遍歷所有數據的次數等於所有樹的最大層數。每次遍歷時,只需要計算每個節點所有feature的裝箱統計參數,遍歷完后,根據節點裝箱統計量,決定是否切分,以及如何切分。

 

以上就是spark mllib實現的隨機森林的關鍵技巧。當然還有很多實現細節這里沒有描述,不過如果理解了這些技巧,對閱讀spark mllib隨機森林源代碼會有很大幫助,希望對讀者有用。

 

Spark Random Forest實現的不足

截止到spark 1.3,mllib的隨機森林仍然不支持OOB error和variable importance的支持,也有一些網友在spark社區咨詢此問題,但是目前沒有得到官方的回應。希望后面,spark可以支持此特性。

 

應用案例

目前,在網絡游戲流失預測的場景下,使用spark隨機森林模型(1000棵樹)和單機c50模型做了對比試驗。試驗中覆蓋5款不同類型的游戲,共執行608輪,試驗周期跨度為4個月。采用了相同的數據,由於單機數據量計算限制,C50使用了10%的采樣建模,而spark使用了全量數據(計算能力秒殺)。試驗結果是隨機森林的模型效果明顯優於C50。F1值有37%的提升,而F2(召回率優先)提升度高達72%

提升可能的原因有兩個:

1 隨機森林模型效果確實優於C50

2 隨機森林建模數據量有質的飛躍,導致性能提升

 

參考資料

  1. Spark源代碼
  2. Spark峰會關於分布式決策樹實現的分享


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM