基於隨機遊走的社團劃分算法hadoop MR實現

繼上篇介紹的算法和單機實現。這篇介紹一下mapreduce實現。

其實python的實現已經用的mapreduce的思路了,改成在真實分佈式環境並不難,我在hadoop平臺上簡單的實現了這個算法。

 

Map端完成邊的propagation效應,即input(fromId, toId) -> output(toId,labelinfo)。

每輪計算需要上一輪節點的Label結果,一次性讀到mapper中,供map時計算。

我用了一個二維數組int[3][#nodes]來存, 其中3行,第一行存的所有label隸屬度。

第一行是隸屬度最大的,第三行最小。每行的數組的index爲NodeID。例如id=100的節點的3個裏數組分別是 int[0][100], int[1][100], int[2][100]。

每個int有4個字節32位,第一個字節存可以表示256的範圍,0~1的隸屬度可以離散化255個區間;後三個字節可以表示2^24個數,即1600萬+,也就是nodeid表示範圍。

那麼1000W的二維數組,實際需要160M左右的空間,完全可以放進內存。

 

Reduce 端完成label確定的工作,即 input (toId,labelinfo…) -> ouput(toId,newlabelinfo)

Reduce的工作比較直接,計算以後最後把label直接寫出去。

 

這次我的Label文件放到HDFS上進行讀取,因此Reduce就沒有直接用context.write 。

 

我生成了個小規模的網絡100W的節點,邊約1000W,只有ID的網絡文件大小隻有150M-。map階段花了1分鐘左右,reducer因爲只有1個,所以時間稍長;MR一次job大概2分到2分半。

 

由於網絡規模問題,我沒有對結果進行檢驗,只是關注了程序運行情況,因此也可以討論一下可優化或是值得注意的地方。

1.  網絡圖的輸入格式是一行一條邊,對於簡單propagate方式是沒問題的,直接吧結果寫出去就行,但是如果考慮複雜一些的方式就需要一行包含所有的鄰居。

2.  Mapper的輸出可能會比較多,因此合併結果減少網絡傳輸能提高任務的運行速度,比如在Mapper中合併,或者寫Combiner(代碼中有)。

 

那麼這個算法的效果到底好不好呢?我也不清楚,按照算法思想,應該是異步計算的方式更靠譜,同步方式容易產生類標不能很好的收斂,例如如果3個點ABC互相連接的連通分量,那麼每次label都會收斂成{a:0.33,b:33,c:0.33} …這個問題其實也值得考慮,畢竟同步方法可以直接利用hadoop的mapreduce優勢。

 

如果對圖挖掘的算法實現有興趣,可以再參考2篇論文:

Pregel: A System for large-scale graph processing

PEGASUS: A Peta-Scale Graph Mining System - Implementation and Observations

最近發現的,沒來得及看…

 

算法java代碼在這,還是那句話:不規範,但是不難看懂。http://download.csdn.net/source/3424779

還有生成網絡的py文件,不是平均度分佈,也不知道是個啥形狀的…

發佈了36 篇原創文章 · 獲贊 27 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章