Skip to content

Commit d835c55

Browse files
author
CindeeM
committed
RF: move modularity into WeightedPartition class
1 parent 43107f9 commit d835c55

File tree

2 files changed

+82
-81
lines changed

2 files changed

+82
-81
lines changed

brainx/tests/test_weighted_modularity.py

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ def test_init(self):
5151
comm = [set([node]) for node in self.graph.nodes()]
5252
self.assertEqual(part.communities, comm)
5353

54-
def test_community_degree(self):
54+
def test_communities_degree(self):
5555
## if no community, method will raise error
5656
part = wm.WeightedPartition(self.graph)
5757
part = wm.WeightedPartition(self.graph, self.communities)
58-
cdegree = part.community_degree()
58+
cdegree = part.communities_degree()
5959
self.assertEqual(round(cdegree[0]), 1462.0)
6060

6161

@@ -90,29 +90,28 @@ def test_get_node_community(self):
9090
self.assertEqual(part.get_node_community(0), 0)
9191

9292

93-
def test_modularity():
94-
graph, comm = get_test_data()
95-
part = wm.WeightedPartition(graph, comm)
96-
npt.assert_almost_equal(wm.modularity(part), 0.0555463)
97-
93+
def test_modularity(self):
94+
part = wm.WeightedPartition(self.graph, self.communities)
95+
npt.assert_almost_equal(part.modularity(), 0.0555463)
96+
97+
98+
def test_total_links(self):
99+
part = wm.WeightedPartition(self.graph) # one comm per node
100+
## summ of all links in or out of communities
101+
## since one per scommunity, just weighted degree of each node
102+
tot_per_comm = part.total_links()
103+
degw = self.graph.degree(weight='weight').values()
104+
self.assertEqual(tot_per_comm, degw)
105+
## This isnt true of we have communities with multiple nodes
106+
part_2comm = wm.WeightedPartition(self.graph, self.communities)
107+
self.assertEqual(part_2comm == degw, False)
108+
109+
def test_internal_links(self):
110+
part = wm.WeightedPartition(self.graph) # one comm per node
111+
weights = part.internal_links()
112+
## this inlcudes self links so
113+
self.assertEqual(weights[0], 1.0)
98114

99-
def test_total_links():
100-
graph, communities = get_test_data()
101-
part = wm.WeightedPartition(graph) # one comm per node
102-
## summ of all links in or out of communities
103-
## since one per scommunity, just weighted degree of each node
104-
tot_per_comm = wm.total_links(part)
105-
degw = graph.degree(weight='weight').values()
106-
npt.assert_equal(tot_per_comm, degw)
107-
## This isnt true of we have communities with multiple nodes
108-
part_2comm = wm.WeightedPartition(graph, communities)
109-
npt.assert_equal(part_2comm == degw, False)
110-
111-
def test_internal_links():
112-
graph, communities = get_test_data()
113-
part = wm.WeightedPartition(graph) # one comm per node
114-
weights = wm.internal_links(part)
115-
## this inlcudes seld links so
116115

117116

118117
def test_dnodecom():

brainx/weighted_modularity.py

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ def _init_communities_from_nodes(self):
5353
return [set([node]) for node in self.graph.nodes()]
5454

5555

56-
def community_degree(self):
56+
def communities_degree(self):
5757
""" calculates the joint degree of a community"""
58-
community_degrees = []
58+
communities_degrees = []
5959
for com in self.communities:
6060
tmp = np.sum([self.graph.degree(weight='weight')[x] for x in com])
61-
community_degrees.append(tmp)
62-
return community_degrees
61+
communities_degrees.append(tmp)
62+
return communities_degrees
6363

6464
def get_node_community(self, node):
6565
"""returns the node's community"""
@@ -91,65 +91,67 @@ def _allnodes_in_communities(self, communities):
9191
return len(self.graph.nodes()) == \
9292
len([item for com in communities for item in com])
9393

94+
def total_links(self):
95+
""" sum of all links inside or outside community
96+
no nodes are missing"""
97+
comm = self.communities
98+
weights = [0] * len(comm)
99+
all_degree_weights = self.graph.degree(weight='weight')
100+
for node, weight in all_degree_weights.items():
101+
node_comm = self.get_node_community(node)
102+
weights[node_comm] += weight
103+
return weights
104+
105+
def internal_links(self):
106+
""" sum of weighted links strictly inside each community
107+
includes self loops"""
108+
comm = self.communities
109+
weights = [0] * len(comm)
110+
comm = self.communities
111+
for val, nodeset in enumerate(comm):
112+
for node in nodeset:
113+
nodes_within = set([x for x in self.graph[node].keys() \
114+
if x in nodeset])
115+
if len(nodes_within) < 1:
116+
continue
117+
if node in nodes_within:
118+
weights[val] += self.graph[node][node]['weight']
119+
nodes_within.remove(node)
120+
weights[val] += np.sum(self.graph[node][x]['weight']/ 2. \
121+
for x in nodes_within)
122+
return weights
123+
124+
125+
def modularity(self):
126+
"""Calculates the proportion of within community edges compared to
127+
between community edges for all nodes in graph with given partition
94128
95-
def modularity(partition):
96-
"""Calculates the proportion of within community edges compared to
97-
between community edges for all nodes in graph with given partition
129+
Parameters
130+
----------
131+
partition : weighted graph partition object
98132
99-
Parameters
100-
----------
101-
partition : weighted graph partition object
133+
Returns
134+
-------
135+
modularity : float
136+
value reflecting the relation of within community connection
137+
to across community connections
102138
103-
Returns
104-
-------
105-
modularity : float
106-
value reflecting the relation of within community connection
107-
to across community connections
108139
140+
References
141+
----------
142+
.. [1] M. Newman, "Fast algorithm for detecting community structure
143+
in networks", Physical Review E vol. 69(6), 2004.
144+
145+
"""
146+
if self.graph.is_directed():
147+
raise TypeError('only valid on non directed graphs')
148+
149+
m2 = self.total_edge_weight
150+
internal_connect = np.array(self.internal_links())
151+
total = np.array(self.total_links())
152+
return np.sum(internal_connect/m2 - (total/(2*m2))**2)
109153

110-
References
111-
----------
112-
.. [1] M. Newman, "Fast algorithm for detecting community structure
113-
in networks", Physical Review E vol. 69(6), 2004.
114154

115-
"""
116-
if partition.graph.is_directed():
117-
raise TypeError('only valid on non directed graphs')
118-
119-
m2 = partition.total_edge_weight
120-
internal_connect = np.array(internal_links(partition))
121-
total = np.array(total_links(partition))
122-
return np.sum(internal_connect/m2 - (total/(2*m2))**2)
123-
124-
def total_links(part):
125-
""" sum of all links inside or outside community
126-
no nodes are missing"""
127-
comm = part.communities
128-
weights = [0] * len(comm)
129-
all_degree_weights = part.graph.degree(weight='weight')
130-
for node, weight in all_degree_weights.items():
131-
node_comm = part.get_node_community(node)
132-
weights[node_comm] += weight
133-
return weights
134-
135-
def internal_links(part):
136-
""" sum of weighted links strictly inside each community
137-
includes self loops"""
138-
comm = part.communities
139-
weights = [0] * len(comm)
140-
comm = part.communities
141-
for val, nodeset in enumerate(comm):
142-
for node in nodeset:
143-
nodes_within = set([x for x in part.graph[node].keys() \
144-
if x in nodeset])
145-
if len(nodes_within) < 1:
146-
continue
147-
if node in nodes_within:
148-
weights[val] += part.graph[node][node]['weight']
149-
nodes_within.remove(node)
150-
weights[val] += np.sum(part.graph[node][x]['weight']/ 2. \
151-
for x in nodes_within)
152-
return weights
153155

154156

155157
def meta_graph(partition):

0 commit comments

Comments
 (0)