@@ -16,10 +16,10 @@ def __init__(self, graph, community=None):
16
16
""" initialize partition of graph, with optional community
17
17
18
18
Parameters
19
- ==========
19
+ ----------
20
20
graph : networkx graph
21
21
22
- community : list of sets
22
+ community : list of sets, optional
23
23
a list of sets with nodes in each set
24
24
if community is None, will initialize with
25
25
one community per node
@@ -65,10 +65,9 @@ def get_node_community(self, node):
65
65
"""returns the node's community"""
66
66
try :
67
67
return [val for val ,x in enumerate (self .community ) if node in x ][0 ]
68
- except :
68
+ except IndexError :
69
69
if not node in self .graph .nodes ():
70
- raise ValueError ('node {0} not in graph for this ' \
71
- 'partition' .format (node ))
70
+ raise ValueError ('node:{0} is not in the graph' .format (node ))
72
71
else :
73
72
raise StandardError ('cannot find community for node ' \
74
73
'{0}' .format (node ))
@@ -94,26 +93,33 @@ def _allnodes_in_community(self, community):
94
93
95
94
96
95
def modularity (partition ):
97
- """Modularity of a graph with given partition
98
- using Newman 2004 Physical Review paper
96
+ """Calculates the proportion of within community edges compared to
97
+ between community edges for all nodes in graph with given partition
99
98
100
99
Parameters
101
- ==========
100
+ ----------
102
101
partition : weighted graph partition object
103
102
104
103
Returns
105
- =======
104
+ -------
106
105
modularity : float
107
106
value reflecting the relation of within community connection
108
107
to across community connections
108
+
109
+
110
+ References
111
+ ----------
112
+ .. [1] M. Newman, "Fast algorithm for detecting community structure
113
+ in networks", Physical Review E vol. 69(6), 2004.
114
+
109
115
"""
110
116
if partition .graph .is_directed ():
111
117
raise TypeError ('only valid on non directed graphs' )
112
118
113
119
m2 = partition .total_edge_weight
114
120
internal_connect = np .array (internal_links (partition ))
115
121
total = np .array (total_links (partition ))
116
- return np .sum (internal_connect / m2 - (total / (2 * m2 ))** 2 )
122
+ return np .sum (internal_connect / m2 - (total / (2 * m2 ))** 2 )
117
123
118
124
def total_links (part ):
119
125
""" sum of all links inside or outside community
@@ -123,7 +129,7 @@ def total_links(part):
123
129
all_degree_weights = part .graph .degree (weight = 'weight' )
124
130
for node , weight in all_degree_weights .items ():
125
131
node_comm = part .get_node_community (node )
126
- weights [node_comm ]+= weight
132
+ weights [node_comm ] += weight
127
133
return weights
128
134
129
135
def internal_links (part ):
@@ -139,7 +145,7 @@ def internal_links(part):
139
145
if len (nodes_within ) < 1 :
140
146
continue
141
147
if node in nodes_within :
142
- weights [val ]+= part .graph [node ][node ]['weight' ]
148
+ weights [val ] += part .graph [node ][node ]['weight' ]
143
149
nodes_within .remove (node )
144
150
weights [val ] += np .sum (part .graph [node ][x ]['weight' ]/ 2. \
145
151
for x in nodes_within )
@@ -154,7 +160,7 @@ def meta_graph(partition):
154
160
metagraph = nx .Graph ()
155
161
# new nodes are communities
156
162
newnodes = [val for val ,_ in enumerate (partition .community )]
157
- mapping = {val : nodes for val , nodes in enumerate (partition .community )}
163
+ mapping = {val :nodes for val ,nodes in enumerate (partition .community )}
158
164
metagraph .add_nodes_from (newnodes , weight = 0.0 )
159
165
160
166
for node1 , node2 , data in partition .graph .edges_iter (data = True ):
@@ -212,13 +218,21 @@ def dnodecom(node, part):
212
218
if neighbor == node :
213
219
continue
214
220
tmpcomm = part .get_node_community (neighbor )
215
- comm_weights [tmpcomm ] += data .get ('weight' ,1 )
221
+ comm_weights [tmpcomm ] += data .get ('weight' , 1 )
216
222
return comm_weights
217
223
218
224
219
225
220
- def gen_dendogram (graph , community = None , min = 0.0000001 ):
221
- """generate dendogram based on muti-levels of partitioning"""
226
+ def gen_dendogram (graph , community = None , minthr = 0.0000001 ):
227
+ """generate dendogram based on muti-levels of partitioning
228
+
229
+ Parameters
230
+ ----------
231
+ graph : networkx undirected graph
232
+ community : list of sets, optional
233
+ minthr : float
234
+ min stoping threshold for difference in old and new modularity
235
+ """
222
236
223
237
if type (graph ) != nx .Graph :
224
238
raise TypeError ("Bad graph type, use only non directed graph" )
@@ -244,7 +258,7 @@ def gen_dendogram(graph, community=None, min=0.0000001):
244
258
partition = Partition (current_graph )
245
259
newpart = _one_level (partition )
246
260
new_mod = modularity (newpart )
247
- if new_mod - mod < min :
261
+ if new_mod - mod < minthr :
248
262
break
249
263
250
264
dendogram .append (newpart )
@@ -324,11 +338,18 @@ def _combine(prev, next):
324
338
community partition
325
339
326
340
Parameters
327
- ==========
341
+ ----------
328
342
prev : list of sets
329
343
community partition
330
344
next : list of sets
331
345
next level community partition
346
+
347
+ Examples
348
+ --------
349
+ >>> prev = [set([0,1,2]), set([3,4])]
350
+ >>> next = [set([0,1])]
351
+ >>> result = _combine(prev, next)
352
+ [set([0, 1, 2, 3, 4])]
332
353
"""
333
354
expected_len = np .max ([x for sublist in next for x in sublist ])
334
355
if not len (prev ) == expected_len + 1 :
0 commit comments