基于随机游走的社团划分算法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文件,不是平均度分布,也不知道是个啥形状的…

你可能感兴趣的:(mapreduce,mapreduce,hadoop,hadoop,算法,社区发现)