1
+ #Author: Maxwell Bertolero
2
+
3
+ import numpy as np
4
+ from random import choice
5
+ import networkx as nx
6
+
7
+ def within_module_degree (graph , partition , weighted = False ):
8
+ '''
9
+ Computes the within-module degree for each node (Guimera et al. 2005)
10
+
11
+ ------
12
+ Inputs
13
+ ------
14
+ graph = Networkx Graph, unweighted, undirected.
15
+ partition = dictionary from modularity partition of graph using Louvain method
16
+
17
+ ------
18
+ Output
19
+ ------
20
+ Dictionary of the within-module degree of each node.
21
+
22
+ '''
23
+ new_part = {}
24
+ for m ,n in zip (partition .values (),partition .keys ()):
25
+ try :
26
+ new_part [m ].append (n )
27
+ except KeyError :
28
+ new_part [m ] = [n ]
29
+ partition = new_part
30
+ wd_dict = {}
31
+
32
+ #loop through each module, look at nodes in modules
33
+ for m in partition .keys ():
34
+ mod_list = partition [m ]
35
+ mod_wd_dict = {}
36
+ #get within module degree of each node
37
+ for source in mod_list :
38
+ count = 0
39
+ for target in mod_list :
40
+ if (source ,target ) in graph .edges () or (target ,source ) in graph .edges ():
41
+ if weighted == True :
42
+ count += graph .get_edge_data (source ,target )['weight' ]
43
+ count += graph .get_edge_data (target ,source )['weight' ] # i assume this will only get one weighted edge.
44
+ else :
45
+ count += 1
46
+ mod_wd_dict [source ] = count
47
+ # z-score
48
+ all_mod_wd = mod_wd_dict .values ()
49
+ avg_mod_wd = float (sum (all_mod_wd ) / len (all_mod_wd ))
50
+ std = np .std (all_mod_wd )
51
+ #add to dictionary
52
+ for source in mod_list :
53
+ wd_dict [source ] = (mod_wd_dict [source ] - avg_mod_wd ) / std
54
+ return wd_dict
55
+
56
+
57
+ def participation_coefficient (graph , partition ):
58
+ '''
59
+ Computes the participation coefficient for each node (Guimera et al. 2005).
60
+
61
+ ------
62
+ Inputs
63
+ ------
64
+ graph = Networkx graph
65
+ partition = modularity partition of graph
66
+
67
+ ------
68
+ Output
69
+ ------
70
+ Dictionary of the participation coefficient for each node.
71
+
72
+ '''
73
+ #this is because the dictionary output of Louvain is "backwards"
74
+ new_part = {}
75
+ for m ,n in zip (partition .values (),partition .keys ()):
76
+ try :
77
+ new_part [m ].append (n )
78
+ except KeyError :
79
+ new_part [m ] = [n ]
80
+ partition = new_part
81
+ pc_dict = {}
82
+ all_nodes = set (graph .nodes ())
83
+ # loop through modules
84
+ if weighted == False :
85
+ for m in partition .keys ():
86
+ #set of nodes in modules
87
+ mod_list = set (partition [m ])
88
+ #set of nodes outside that module
89
+ between_mod_list = list (set .difference (all_nodes , mod_list ))
90
+ for source in mod_list :
91
+ #degree of node
92
+ degree = float (nx .degree (G = graph , nbunch = source ))
93
+ count = 0
94
+ # between module degree
95
+ for target in between_mod_list :
96
+ if (source ,target ) in graph .edges () or (source ,target ) in graph .edges ():
97
+ count += 1
98
+ bm_degree = float (count )
99
+ if bm_degree == 0.0 :
100
+ pc = 0.0
101
+ else :
102
+ pc = 1 - ((float (bm_degree ) / float (degree ))** 2 )
103
+ pc_dict [source ] = pc
104
+ return pc_dict
105
+ #this is because the dictionary output of Louvain is "backwards"
106
+ if weighted == True :
107
+ for m in partition .keys ():
108
+ #set of nodes in modules
109
+ mod_list = set (partition [m ])
110
+ #set of nodes outside that module
111
+ between_mod_list = list (set .difference (all_nodes , mod_list ))
112
+ for source in mod_list :
113
+ #degree of node
114
+ degree = 0
115
+ edges = G .edges ([source ],data = True )
116
+ for edge in edges :
117
+ degree += graph .get_edge_data (edge [0 ],edge [1 ])['weight' ]
118
+ count = 0
119
+ # between module degree
120
+ for target in between_mod_list :
121
+ if (source ,target ) in graph .edges () or (source ,target ) in graph .edges ():
122
+ count += graph .get_edge_data (source ,target )['weight' ]
123
+ count += graph .get_edge_data (target ,source )['weight' ] # i assume this will only get one weighted edge.
124
+ bm_degree = float (count )
125
+ if bm_degree == 0.0 :
126
+ pc = 0.0
127
+ else :
128
+ pc = 1 - ((float (bm_degree ) / float (degree ))** 2 )
129
+ pc_dict [source ] = pc
130
+ return pc_dict
0 commit comments