日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python社区发现—Louvain—networkx和community

發布時間:2023/12/10 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python社区发现—Louvain—networkx和community 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

社區

如果一張圖是對一片區域的描述的話,將這張圖劃分為很多個子圖。當子圖之內滿足關聯性盡可能大,而子圖之間關聯性盡可能低時,這樣的子圖可以稱之為一個社區。

社區發現算法

社區發現算法有很多,例如LPA,HANP,SLPA以及Louvain,不同的算法劃分社區的效果不盡相同。Louvain算法是基于模塊度的社區發現算法,該算法在效率和效果上都表現較好,并且能夠發現層次性的社區結構,其優化目標是最大化整個社區網絡的模塊度。

模塊度

模塊度是評估一個社區網絡劃分好壞的度量方法,它的物理含義是社區內節點的連邊數與隨機情況下的邊數只差,它的取值范圍是 [?1/2,1)。可以簡單地理解為社區內部邊的權重減去所有與社區節點相連的邊的權重和,對無向圖更好理解,即社區內部邊的度數減去社區內節點的總度數。



Louvain算法

算法流程:
1、初始時將每個頂點當作一個社區,社區個數與頂點個數相同。
2、依次將每個頂點與之相鄰頂點合并在一起,計算它們的模塊度增益是否大于0,如果大于0,就將該結點放入該相鄰結點所在社區。
3、迭代第二步,直至算法穩定,即所有頂點所屬社區不再變化。
4、將各個社區所有節點壓縮成為一個結點,社區內點的權重轉化為新結點環的權重,社區間權重轉化為新結點邊的權重。
5、重復步驟1-3,直至算法穩定。

# coding=utf-8 import collections import randomdef load_graph(path):G = collections.defaultdict(dict)with open(path) as text:for line in text:vertices = line.strip().split()v_i = int(vertices[0])v_j = int(vertices[1])w = float(vertices[2])G[v_i][v_j] = wG[v_j][v_i] = wreturn Gclass Vertex():def __init__(self, vid, cid, nodes, k_in=0):self._vid = vidself._cid = cidself._nodes = nodesself._kin = k_in # 結點內部的邊的權重class Louvain():def __init__(self, G):self._G = Gself._m = 0 # 邊數量self._cid_vertices = {} # 需維護的關于社區的信息(社區編號,其中包含的結點編號的集合)self._vid_vertex = {} # 需維護的關于結點的信息(結點編號,相應的Vertex實例)for vid in self._G.keys():self._cid_vertices[vid] = set([vid])self._vid_vertex[vid] = Vertex(vid, vid, set([vid]))self._m += sum([1 for neighbor in self._G[vid].keys() if neighbor > vid])def first_stage(self):mod_inc = False # 用于判斷算法是否可終止visit_sequence = self._G.keys()random.shuffle(list(visit_sequence))while True:can_stop = True # 第一階段是否可終止for v_vid in visit_sequence:v_cid = self._vid_vertex[v_vid]._cidk_v = sum(self._G[v_vid].values()) + self._vid_vertex[v_vid]._kincid_Q = {}for w_vid in self._G[v_vid].keys():w_cid = self._vid_vertex[w_vid]._cidif w_cid in cid_Q:continueelse:tot = sum([sum(self._G[k].values()) + self._vid_vertex[k]._kin for k in self._cid_vertices[w_cid]])if w_cid == v_cid:tot -= k_vk_v_in = sum([v for k, v in self._G[v_vid].items() if k in self._cid_vertices[w_cid]])delta_Q = k_v_in - k_v * tot / self._m # 由于只需要知道delta_Q的正負,所以少乘了1/(2*self._m)cid_Q[w_cid] = delta_Qcid, max_delta_Q = sorted(cid_Q.items(), key=lambda item: item[1], reverse=True)[0]if max_delta_Q > 0.0 and cid != v_cid:self._vid_vertex[v_vid]._cid = cidself._cid_vertices[cid].add(v_vid)self._cid_vertices[v_cid].remove(v_vid)can_stop = Falsemod_inc = Trueif can_stop:breakreturn mod_incdef second_stage(self):cid_vertices = {}vid_vertex = {}for cid, vertices in self._cid_vertices.items():if len(vertices) == 0:continuenew_vertex = Vertex(cid, cid, set())for vid in vertices:new_vertex._nodes.update(self._vid_vertex[vid]._nodes)new_vertex._kin += self._vid_vertex[vid]._kinfor k, v in self._G[vid].items():if k in vertices:new_vertex._kin += v / 2.0cid_vertices[cid] = set([cid])vid_vertex[cid] = new_vertexG = collections.defaultdict(dict)for cid1, vertices1 in self._cid_vertices.items():if len(vertices1) == 0:continuefor cid2, vertices2 in self._cid_vertices.items():if cid2 <= cid1 or len(vertices2) == 0:continueedge_weight = 0.0for vid in vertices1:for k, v in self._G[vid].items():if k in vertices2:edge_weight += vif edge_weight != 0:G[cid1][cid2] = edge_weightG[cid2][cid1] = edge_weightself._cid_vertices = cid_verticesself._vid_vertex = vid_vertexself._G = Gdef get_communities(self):communities = []for vertices in self._cid_vertices.values():if len(vertices) != 0:c = set()for vid in vertices:c.update(self._vid_vertex[vid]._nodes)communities.append(c)return communitiesdef execute(self):iter_time = 1while True:iter_time += 1mod_inc = self.first_stage()if mod_inc:self.second_stage()else:breakreturn self.get_communities()if __name__ == '__main__':G = load_graph('s.txt')algorithm = Louvain(G)communities = algorithm.execute()# 按照社區大小從大到小排序輸出communities = sorted(communities, key=lambda b: -len(b)) # 按社區大小排序count = 0for communitie in communities:count += 1print("社區", count, " ", communitie)

networkx和community社區劃分和可視化

安裝

使用community安裝python-louvain即可
pip install python-louvain
pip install networkx

使用

最佳劃分

community.best_partition(graph, partition=None, weight='weight', resolution=1.0)

Compute the partition of the graph nodes which maximises the modularity (or try…) using the Louvain heuristics.
This is the partition of highest modularity, i.e. the highest partition of the dendrogram generated by the Louvain algorithm.

import community import networkx as nx import matplotlib.pyplot as plt#better with karate_graph() as defined in networkx example. #erdos renyi don't have true community structure G = nx.erdos_renyi_graph(30, 0.05)#first compute the best partition partition = community.best_partition(G)#drawing size = float(len(set(partition.values()))) pos = nx.spring_layout(G) count = 0. for com in set(partition.values()) :count = count + 1.list_nodes = [nodes for nodes in partition.keys()if partition[nodes] == com]nx.draw_networkx_nodes(G, pos, list_nodes, node_size = 20,node_color = str(count / size))nx.draw_networkx_edges(G,pos, alpha=0.5) plt.show()

總結

以上是生活随笔為你收集整理的Python社区发现—Louvain—networkx和community的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。