LPA标签传播算法是由Usha Nandini Raghavan等人在2007年提出的。是一种半监督聚类算法;它在聚类算法中的特点是聚类速度快,但聚类结果随机。
其算法的过程如下:
其过程比较简单:
1.为所有节点指定一个唯一的标签;
2.逐轮刷新所有节点的标签,直到达到收敛要求为止。对于每一轮刷新,节点标签刷新的规则如下:
对于某一个节点,考察其所有邻居节点的标签,并进行统计,将出现个数最多的那个标签赋给当前节点。当个数最多的标签不唯一时,随机选一个。
注:算法中的记号 N_n^k 表示节点 n 的邻居中标签为 k 的所有节点构成的集合。
[ 以上资料来源于:] (http://blog.csdn.net/cleverlzc/article/details/39494957)
[标签传播算法原著:] (http://arxiv.org/abs/0709.2938)
标签传播算法过程简单,对于一些大牛们来说要是写这个算法可能需要两个小时就可以搞定。但是对于我这个初学者来说不是一件很容易的事情。
在我彻底理解标签传播算法之后,要开始用python实现整个过程。这对于我来说目前是一项不小的挑战。之后在导师的帮助下我先找到了python中igraph包里有关于LPA算法。这让我看到了曙光!!!
在igraph包里定义的标签传播:
def community_label_propagation(self, weights = None, initial = None,fixed = None):
if isinstance(fixed, basestring):
fixed = [bool(o) for o in g.vs[fixed]]
cl = GraphBase.community_label_propagation(self,weights, initial, fixed)
return VertexClustering(self,cl,modularity_params=dict(weights=weights))
[代码资源来自于] (http://igraph.org/python/doc/igraph.Graph-class.html#community_label_propagation)
对于我这种初学者来说看到这样的代码,我不知道该如何下手。如何建立数据,如何建立数据之间的关系,如何建立关系图等等这一类问题在我脑海中出现。我以为快要看到黎明的曙光,谁知道这种结果被厚重的乌云遮的严严实实!!!
那接下来就应该是下载数据集以及如何分析数据最后在有数据集的基础上建立一个社交网络图!数据集很好下载,在CSDN上有关于社交网络数据的数据集。下载好之后需要你做整理。(我下载好之后利用两个数据集来做实验)
数据整理好之后的形式:
下面需要做的就是把这些数据导入进去,建立网络关系图做实验。
f = open('yourtest.txt','r')
test = {}
for i in f.readlines()[1:]:
people,friends = i.split()[0],i.split()[1:] //根据自己数据集去索引相应内容
test.setdefault(people,friends)
g = Graph()
for i in test.keys():
g.add_vertices(str(i))
edges = []
for i in test.keys():
for j in test[i]:
edges.append((str(i),str(j)))
#去重
new = []
for i in edges:
new.append(tuple(sorted(list(i))))
g.add_edges(set(new))
然后调用igraph包里现有的LPA函数;
print g.community_label_propagation()
plot(g)
空手道网络(n=34,v=78)结果如下:
作者合作网络(n=1589.v=2742)结果如下:
虽然LPA算法已经基本可以实现,但是对于我来说这短短的几行代码并不能让我看到这其中的过程,它是怎么构建Graphbase的?它是怎么进行VertexClustering的?这其中的过程都是什么?
最终还是得找到igraph包中,找到它们定义的方法。
对于GraphBase类中:
class Graph(GraphBase):
GraphBase.__init__(self, nverts, edges, directed)
for key, value in graph_attrs.iteritems():
if isinstance(key, (int, long)): //判断指针类型
key = str(key) //返回字符串型
self[key] = value
for key, value in vertex_attrs.iteritems():
if isinstance(key, (int, long)):
key = str(key)
self.vs[key] = value
for key, value in edge_attrs.iteritems():
if isinstance(key, (int, long)):
key = str(key)
self.es[key] = value
对于GraphBase类库里面有很多处理图形的方法,我只找出我需要的这些定义的方法。
[以上资源来自于:] (http://igraph.org/python/doc/igraph-pysrc.html#GraphBase)
对于VertexClustering类中:
class VertexClustering(Clustering):
def __init__(self, graph, membership = None, modularity = None,params = None, modularity_params = None):
if membership is None:
Clustering.__init__(self, [0]*graph.vcount(), params) //返回一个空的字典存储成员
else:
if len(membership) != graph.vcount():
raise ValueError("membership list has invalid length")
Clustering.__init__(self, membership, params)
self._graph = graph
self._modularity = modularity
if modularity_params is None:
self._modularity_params = {}
else:
self._modularity_params = dict(modularity_params)
VertexClustering类中还有很多可以直接调用的方法。
在这里可以找到:
http://igraph.org/python/doc/igraph.clustering-pysrc.html#
LPA算法应用广泛,尤其对于研究社交网络关系方面提供了很大的帮助。但是它的缺点也很明显,随机性直接影响着研究结果的不确定。所以在对于它的改进也有很多,尤其是对于初始化标签和对边标签的研究对社区发现的准确性都有很大的提高。
这里有两篇标签传播算法的改进:
1.Community Detection Using A Neighborhood strenghth driven
(http://arxiv.org/abs/1105.3264)
2.融入节点重要性和标签影响力的标签传播社区发现算法
(http://xwxt.sict.ac.cn/CN/abstract/abstract2843.shtml
以上就是我对LPA算法的实现在基于igraph包中的一个小节,还有很多不足需要改善,同时也感谢我导师和同学的耐心指导!
小弟初来乍到,欢迎批评指正!