forked from qinyuenlp/CommunityDetection
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevaluation.py
75 lines (69 loc) · 2.22 KB
/
evaluation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# -*- coding:utf-8 -*-
import math
import numpy as np
import networkx as nx
def NMI(com, real_com):
"""
Compute the Normalized Mutual Information(NMI)
Parameters
--------
com, real_com : list or numpy.array
number of community of nodes
"""
if len(com) != len(real_com):
return ValueError('len(A) should be equal to len(B)')
com = np.array(com)
real_com = np.array(real_com)
total = len(com)
com_ids = set(com)
real_com_ids = set(real_com)
#Mutual information
MI = 0
eps = 1.4e-45
for id_com in com_ids:
for id_real in real_com_ids:
idAOccur = np.where(com == id_com)
idBOccur = np.where(real_com == id_real)
idABOccur = np.intersect1d(idAOccur, idBOccur)
px = 1.0*len(idAOccur[0])/total
py = 1.0*len(idBOccur[0])/total
pxy = 1.0*len(idABOccur)/total
MI = MI + pxy*math.log(pxy/(px*py) + eps,2)
# Normalized Mutual information
Hx = 0
for idA in com_ids:
idAOccurCount = 1.0*len(np.where(com == idA)[0])
Hx = Hx - (idAOccurCount/total)*math.log(idAOccurCount/total + eps, 2)
Hy = 0
for idB in real_com_ids:
idBOccurCount = 1.0*len(np.where(real_com == idB)[0])
Hy = Hy - (idBOccurCount/total) * math.log(idBOccurCount/total + eps, 2)
MIhat = 2.0*MI/(Hx + Hy)
return MIhat
def modularity(G, community):
"""
Compute modularity of communities of network
Parameters
--------
G : networkx.Graph
an undirected graph
community : dict
the communities result of community detection algorithms
"""
V = [node for node in G.nodes()]
m = G.size(weight='weight') # if weighted
n = G.number_of_nodes()
A = nx.to_numpy_array(G)
Q = 0
for i in range(n):
node_i = V[i]
com_i = community[node_i]
degree_i = G.degree(node_i)
for j in range(n):
node_j = V[j]
com_j = community[node_j]
if com_i != com_j:
continue
degree_j = G.degree(node_j)
Q += A[i][j] - degree_i * degree_j/(2 * m)
return Q/(2 * m)