(Facebook 네트워크 DataSet : snap.stanford.edu 의 Facebook 수집 정보)
[Option 1] Modularity Maximization
- Accuracy 수식
Ego-Network (circle num) |
NMI |
Accuracy | Balaced_Accuracy |
0 (24) |
0.315198369925 |
0.708784596871 | 0.504977375469 |
107 (9) |
0.40327795919 |
0.606028183716 | 0.569606621639 |
348 (14) |
0.439735454474 |
0.176045321946 | 0.486369035413 |
414 (7) |
0.672568174712 |
0.78936146336 | 0.715865535473 |
686 (14) |
0.34900620265 | 0.379027658968 | 0.504352021915 |
698 (13) |
0.892580698441 |
0.869803921569 | 0.712850224836 |
1684 (17) |
0.446600063726 |
0.796311011582 | 0.556930216647 |
1912 (46) |
0.587107636673 |
0.802668113234 | 0.553714011307 |
3437 (32) |
0.759151157085 |
0.654209621993 | 0.525378237688 |
3980 (17) |
0.566945313748 | 0.786576168929 | 0.521568166818 |
실행과정 유의사항
snap의 Facebook 데이터에서의 Ground-Truth 데이터 값과 비교하기 위하여 나누려 하는 커뮤니티의 수를 입력 해야 하는데 Ground-Truth 의 커뮤니티 수에 맞게 입력해야 합니다. 위의 표에 맞도록 입력해야 합니다. - Example ( 오른쪽 괄호 안의 값 ) 0.edges 파일에 대한 커뮤니티 도출시 입력 Community 수의 값 : 24 107.edges 파일에 대한 커뮤니티 도출시 입력 Community 수의 값 : 9 실행 과정에서 NMI 값에 대한 함수 , Accuracy 값에 대한 함수의 입력 Parameter는 커뮤니티 도출이 된 데이터가 2차원 형태의 List 데이터를 요구합니다. K-means 함수 실행 후의 [1,1,1,0,0,0,1,2,2,] 값 X 노드의 값을 가지고 있는 List [ [ 1,2,3,4], [5,6,7,8], [10,12] ] O |
설정 변경 사항
Edges 의 데이터에서의 커뮤니티 분할 결과의 노드들이 Ground-Truth 에서 읽어 드린 데이터의 노드들과 값이 다릅니다. 양 측에 서로 존재하지 않는 노드들이 존재하여 전체 노드의 수 N 값이 달라지게 되어 이를 맞도록 수정하기 위하여 양 측 데이터에서 한 쪽에만 존재하는 노드들을 제외하였습니다. 즉, 양 쪽 데이터 모두에 존재하느 노드들만 남겨놓고 실행하였습니다. |
소스 코드
# -*- coding: utf-8 -*- import dircache import os.path import networkx as net import networkx.algorithms as algo import matplotlib.pyplot as plt import numpy as np import numpy.linalg as la import Pycluster from scipy import * #circles num #0 = 24, 107 = 9, 348 = 14, 414 = 7, 686 = 14, 698 = 13, 1684 = 17, 1912 = 46, 3437 = 32, 3980 = 17 def my_NMI(circle1, circle2): #NMI 값을 반환하는 함수 result_value = 0
cc_temp = [] for i in circle1: for j in i: if not j in cc_temp: cc_temp.append(j) n = len(cc_temp)
circle1_num = [] for i in circle1: circle1_num.append(len(i))
circle2_num = [] for i in circle2: circle2_num.append(len(i))
#print circle1_num #print circle2_num #print n
circle1_h = my_h(circle1_num, n) circle2_h = my_h(circle2_num, n) denominator = np.sqrt( (circle1_h * circle2_h) )
numerator = 0 for i in range(0, len(circle1)): for j in range(0, len(circle2)): x = same_data_num(circle1[i], circle2[j] ) x = float(x)/n #print "same data %f" % x if not x == 0: #print "not 0" numerator += x * np.log10( x / ((float(circle1_num[i])/n)*(float(circle2_num[j])/n)) )
result_value = numerator / denominator
return result_value def same_data_num(circle1, circle2): #NMI 계산에 필요한 함수(양쪽 써클에 동일하게 존재하는 노드의 수) result_value = 0 for i in circle1: for j in circle2: if i == j: result_value += 1
return result_value
def my_h(circle_num, n): #NMI 계산에 필요한 함수 result_value = 0 for i in circle_num: if not i == 0: x = float(i) / n result_value += x * np.log10(x)
#print result_value return result_value def my_accuracy(circle1, circle2): # Accuracy 값을 반환하는 함수 result_value = 0
all_list = [] for i in circle1: for j in i: all_list.append(j) pair_list = [] for i in range(0, len(all_list)): for j in range(i, len(all_list)): if all_list[i] != all_list[j]: pair_list.append( [ all_list[i], all_list[j] ] )
a_value = 0 d_value = 0
for pair in pair_list: c1 = 0 c2 = 0 for x in circle1: if pair[0] in x and pair[1] in x: c1 = 1 for x in circle2: if pair[0] in x and pair[1] in x: c2 = 1 if c1 == 1 and c2 == 1: a_value += 1 if c1 == 0 and c2 == 0: d_value += 1 n = len(all_list) result_value = float(a_value + d_value) / ( n*(n-1)/2)
return result_value list = dircache.listdir('.') g = net.Graph() for item in list: filename, extension = os.path.splitext(item) if extension in '.edges': # edges 파일에 데이터를 읽어들여 egoNetwork Graph 생성 print 'add information to g(Graph) from ' + item f = file(item) pre ='' after='' isAdd = 0 allF = f.read() for x in allF: if x == ' ': isAdd = 1 elif x == '\n': isAdd = 0 g.add_edge(int(pre), int(after)) g.add_edge(int(filename), int(pre)) g.add_edge(int(filename), int(after)) pre='' after='' else: if isAdd == 0: pre += x else: after += x #Modularity Maximization 에 기반한 커뮤니티 도출 시작 print "%s community number : " % filename dimen = input() g_nodes_num = g.number_of_nodes() g_edges_num = g.number_of_edges() A = [] for i in g: temp = [] for j in g: if g.has_edge(i, j): temp.append(1) else: temp.append(0) A.append(temp)
B = [] k = 0 l = 0
for i in g: temp = [] for j in g: temp.append( (A[k][l] - ( (g.degree(i)*g.degree(j)) / float(2*g_edges_num) ) ) ) l += 1 B.append(temp) k += 1 l = 0
B_mat = np.mat(B) w, v = la.eig(B_mat) V = [[0.0 for i in range(1,3)] for k in range(1, g_nodes_num+1)] V = np.mat(V) # top two eigenvector V[:,0] += v[:,0] V[:,1] += v[:,1] #only use first dimensional value
labels = Pycluster.kcluster(V, dimen)
#labels
# W = np.diag((w[0], w[1])) eigenvalue is not used
circle = [] k = 0 for i in range(0, dimen): k = 0 temp = [] for j in g: if labels[0][k] == i: temp.append(j) k += 1 circle.append(temp)
k = 0 f = open('%s.mmCircles' % filename, 'w') for x in circle: f.write("circle%d\t" % k ) for y in x: f.write("".join(str(y))) f.write("\t") f.write('\n') k += 1 f.close()
#modularity 이용 커뮤티니 나눈뒤 circle에 나뉜 값을 저장 with open("%s.circles" % filename) as readF: readData = readF.read() readData = readData.split('\n') readData.remove('') readString = [row.split('\t')[1:] for row in readData] gt_circle = [] for i in readString: temp = [] for j in i: temp.append(int(j)) gt_circle.append(temp)
#circle 안에는 나뉘어진 커뮤니티 정보 #gt_circle 안에는 읽어들인 Ground-Truth 커뮤니티 정보 #gt circle 에는 있는데 circle에 없는 경우 gt_circle 에서 지우기 remove_list = [] for list_gt in gt_circle: for value_gt in list_gt: sameValue = 1 for list_cc in circle: for value_cc in list_cc: if value_gt == value_cc: sameValue = 0 if sameValue == 1: #print value_gt remove_list.append(value_gt)
for i in remove_list: for h in range(0, len(circle)): try: gt_circle[h].remove(i) except ValueError: pass
#circle 에는 있는데 gt_circle에 없는 경우 circle 에서 지우기
remove_list = [] for list_gt in circle: for value_gt in list_gt: sameValue = 1 for list_cc in gt_circle: for value_cc in list_cc: if value_gt == value_cc: sameValue = 0 if sameValue == 1: #print value_gt remove_list.append(value_gt)
for i in remove_list: for h in range(0, len(circle)): try: circle[h].remove(i) except ValueError: pass
#양쪽에 없는 값들 지우기 끝 print "%s's NMI : " % filename print my_NMI(circle, gt_circle) print "%s's Accuracy : " % filename print my_accuracy(circle, gt_circle)
g = net.Graph() |
'Python' 카테고리의 다른 글
Python numpy 데이터피팅, 함수의 해 graph (0) | 2013.07.16 |
---|---|
사회관계망 네트워크의 상호성 및 팔로어 수/친구 수 분포 분석 (0) | 2013.04.29 |
python 파일명 및 파일 확장자 확인하기 (0) | 2013.04.04 |
python 디렉토리(폴더) 안애 파일 목록 불러오기 (0) | 2013.04.04 |
python 스트링 값 비교 ( string compare) (0) | 2013.04.04 |