【知识图谱】Louvain、LPA等5类经典社区发现算法 Python 实战
一、社區發現概述
根據圖論,加權網絡表示為𝐺=(𝑉,𝐸,𝑊),未加權網絡表示為𝐺=(𝑉,𝐸),其中𝑉和𝐸表示節點和邊的集合,𝑊分別表示𝐸相應的權重,以連接的強度或容量為單位。在未加權的網絡中,𝑊被視為1。子圖𝑔?𝐺是保留原始網絡結構的圖劃分。子圖的劃分遵循預定義(pre-define)的規則,不同的規則可能會導致不同形式的子圖。
社區是代表真實社會現象的一種子圖。換句話說,社區是一組具有共同特征的人或對象。
社區是網絡中節點密集連接的子圖,稀疏連接的節點溝通了不同的社區,使用𝐶={𝐶1,𝐶2,?,𝐶𝑘}表示將網絡𝐺劃分為𝑘個社區的集合,其中𝐶𝑖是社區劃分的第𝑖個社區。
節點𝑣屬于社區𝐶𝑖滿足如下條件:社區內部每個節點的內部度大于其外部度。
因此,社區發現的目標是發現網絡𝐺中的社區𝐶。
技術交流
目前開通了技術交流,群友已超過3000人,添加時最好的備注方式為:來源+興趣方向,方便找到志同道合的朋友,資料、代碼獲取也可以加入
方式1、添加微信號:dkl88191,備注:來自CSDN
方式2、微信搜索公眾號:Python學習與數據挖掘,后臺回復:加群
二、KL社區發現算法
K-L(Kernighan-Lin)算法是一種將已知網絡劃分為已知大小的兩個社區的二分方法,它是一種貪婪算法,它的主要思想是為網絡劃分定義了一個函數增益Q,Q表示的是社區內部的邊數與社區之間的邊數之差,根據這個方法找出使增益函數Q的值成為最大值的劃分社區的方法。
1、實現策略
該算法的具體策略是,將社區結構中的結點移動到其他的社區結構中或者交換不同社區結構中的結點。從初始解開始搜索,直到從當前的解出發找不到更優的候選解,然后停止。
首先將整個網絡的節點隨機的或根據網絡的現有信息分為兩個部分,在兩個社團之間考慮所有可能的節點對,試探交換每對節點并計算交換前后的ΔQ,ΔQ=Q交換后-Q交換前,記錄ΔQ最大的交換節點對,并將這兩個節點互換,記錄此時的Q值。
規定每個節點只能交換一次,重復這個過程直至網絡中的所有節點都被交換一次為止。需要注意的是不能在Q值發生下降時就停止,因為Q值不是單調增加的,既使某一步交換會使Q值有所下降,但其后的一步交換可能會出現一個更大的Q值。在所有的節點都交換過之后,對應Q值最大的社團結構即被認為是該網絡的理想社團結構。
地址:http://eda.ee.ucla.edu/EE201A-04Spring/kl.pdf
2、代碼實現:
>>> def draw_spring(G, com): ... pos = nx.spring_layout(G) # 節點的布局為spring型 ... NodeId = list(G.nodes()) ... node_size = [G.degree(i) ** 1.2 * 90 for i in NodeId] # 節點大小 ... plt.figure(figsize=(8, 6)) # 圖片大小 ... nx.draw(G, pos, with_labels=True, node_size=node_size, node_color='w', node_shape='.') ... color_list = ['pink', 'orange', 'r', 'g', 'b', 'y', 'm', 'gray', 'black', 'c', 'brown'] ... for i in range(len(com)): ... nx.draw_networkx_nodes(G, pos, nodelist=com[i], node_color=color_list[i]) ... plt.show() ... >>> import networkx as nx >>> import matplotlib.pyplot as plt >>> G = nx.karate_club_graph() >>> com = list(kernighan_lin_bisection(G)) >>> import matplotlib.pyplot as plt >>> from networkx.algorithms.community import kernighan_lin_bisection >>> com = list(kernighan_lin_bisection(G)) >>> print('社區數量', len(com)) 社區數量 2 >>> draw_spring(G, com)效果:
三、Louvain社區發現算法
Louvain算法是一種基于模塊度的社區發現算法,其基本思想是網絡中節點嘗試遍歷所有鄰居的社區標簽,并選擇最大化模塊度增量的社區標簽,在最大化模塊度之后,每個社區看成一個新的節點,重復直到模塊度不再增大。
地址:https://arxiv.org/pdf/0803.0476.pdf
1、實現策略
具體實現上,如下圖所示,步驟如下:
1)初始時將每個頂點當作一個社區,社區個數與頂點個數相同。
2)依次將每個頂點與之相鄰頂點合并在一起,計算它們最大的模塊度增益是否大于0,如果大于0,就將該結點放入模塊度增量最大的相鄰結點所在社區。
其中,模塊度用來衡量一個社區的質量,公式第一如下。
3)迭代第二步,直至算法穩定,即所有頂點所屬社區不再變化。
4)將各個社區所有節點壓縮成為一個結點,社區內點的權重轉化為新結點環的權重,社區間權重轉化為新****結點邊的權重。
5)重復步驟1-3,直至算法穩定。
2、代碼實現:
>>> import networkx as nx >>> import matplotlib.pyplot as plt >>> G = nx.karate_club_graph() >>> com = list(kernighan_lin_bisection(G)) >>> import matplotlib.pyplot as plt >>> from networkx.algorithms.community import louvain_communities >>> com = list(louvain_communities(G)) >>> print('社區數量', len(com)) 社區數量 4 >>> draw_spring(G, com)3、效果:
四、標簽傳播社區發現算法
LPA全稱label propagation algorithm,即標簽傳遞算法,是一種圖聚類算法,常用在社交網絡中,用于發現潛在的社區,是一種基于標簽傳播的局部社區劃分。對于網絡中的每一個節點,在初始階段,Label Propagation算法對于每一個節點都會初始化一個唯一的一個標簽。
每一次迭代都會根據與自己相連的節點所屬的標簽改變自己的標簽,更改的原則是選擇與其相連的節點中所屬標簽最多的社區標簽為自己的社區標簽,這就是標簽傳播的含義,隨著社區標簽不斷傳播。最終,連接緊密的節點將有共同的標簽
1、實現策略
LPA認為每個結點的標簽應該和其大多數鄰居的標簽相同,將一個節點的鄰居節點的標簽中數量最多的標簽作為該節點自身的標簽(bagging思想)。給每個節點添加標簽(label)以代表它所屬的社區,并通過標簽的“傳播”形成同一個“社區”內部擁有同一個“標簽”。
標簽傳播算法(LPA)的做法如下:
第一步: 為所有節點指定一個唯一的標簽;
第二步: 逐輪刷新所有節點的標簽,直到達到收斂要求為止。對于每一輪刷新,節點標簽刷新的規則如下:
對于某一個節點,考察其所有鄰居節點的標簽,并進行統計,將出現個數最多的那個標簽賦給當前節點。當個數最多的標簽不唯一 時,隨機選一個。
2、代碼實現:
>>> import networkx as nx >>> import matplotlib.pyplot as plt >>> G = nx.karate_club_graph() >>> com = list(kernighan_lin_bisection(G)) >>> import matplotlib.pyplot as plt >>> from networkx.algorithms.community import label_propagation_communities >>> com = list(label_propagation_communities(G)) >>> print('社區數量', len(com)) 社區數量 3 >>> draw_spring(G, com)3、效果
五、greedy_modularity社區算法
1、實現策略
貪心模塊度社區算法,是一種用于檢測社區結構的分層聚集算法,它在具有n個頂點和m條邊的網絡上的運行時間是O(mdlogn),其中d是描述社區結構的樹狀圖的深度。
地址:https://arxiv.org/pdf/cond-mat/0408187v2.pdf
2、代碼實現:
>>> import networkx as nx >>> import matplotlib.pyplot as plt >>> G = nx.karate_club_graph() >>> com = list(kernighan_lin_bisection(G)) >>> import matplotlib.pyplot as plt >>> from networkx.algorithms.community import greedy_modularity_communities >>> com = list(greedy_modularity_communities(G)) >>> print('社區數量', len(com)) 社區數量 3 >>> draw_spring(G, com)3、效果:
參考文獻
1、https://icode9.com/content-1-1321350.html
2、https://blog.csdn.net/qq_16543881/article/details/122825957
3、https://blog.csdn.net/qq_16543881/article/details/122781642
總結
以上是生活随笔為你收集整理的【知识图谱】Louvain、LPA等5类经典社区发现算法 Python 实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7. B+树
- 下一篇: java的string访问某个元素_CS