NetworkX: harmonic centrality
centrality - harmonic centrality.
- harmonic centrality는 다른 모든 노드들인 v들로부터, 해당 노드인 u까지 향하는 “최단 거리의 길이(shortest path length)의 역수”를 모두 더한 값을 말합니다. 즉, 계산하려는 노드로 들어오는 거리를 고려하죠
- 이렇게 쓰고 보면, 마치 closeness centrality와 유사해보이지만, 다음과 같이 달라요.
- closeness centrality: (최단거리들의 길이 합)의 역수
- hormonic centrality: (최단거리의 역수)의 합
- 이라는 차이가 있죠. 이렇게 쓰고 나면, 도대체
Why harmonic centrality matter?
- 이렇게 쓰고 나면, “이렇게 바꾼다고 뭐가 그렇게 달라지냐?”, 라는 생각이 들지만, 다릅니다.
- 논문 Axioms for Centrality에 작성된 내용을 보면, “다양한 중심성 지표를 대상으로 실험을 해보 결과
harmonic centrality가 가장 탁월했다”라고 말하기도 하죠. 그리고 그 외로도 아래의 다양한 아티클들에서,harmonic centrality의 우수성을 이야기하고 있습니다.
Compute harmonic centrality and compare with others.
- a-comparison-of-harmonic-centrality-and-pagerank에서 다음을 주장했습니다.
- 작은 network에서 harmonic centrality가 pagerank보다 속도가 빠르다: 이건 그렇기는 한데, 작은 네트워크이므로 시간 상 이점이 별로 없다고 봅니다. 네트워크가 커지면, harmonic centrality가 pagerank보다 현저하게 느려집니다.
- 지표들로 historgram을 구성했을 때, 그 값들이 multi-modal이다: scale-free network에서, 지표들로 histogram을 만들어보면, pagerank의 경우는 거의 한쪽으로 쏠려 있는데(skeweed), harmonic centrality의 경우는 multi-modal의 형태가 나타납니다. 이는, 그래프의 노드들에 대한 특정한 특성을 말한다고 할 수 있고, 이를 이용해서 그래프를 분석해낼 수도 있겠죠. 혹은, harmonic centrality가 그래프에 대한 뚜렷한 특정을 보여주는 예라고 말할 수 있습니다.
- 자세한 내용은 다음 코드에서 확인하시면 좋습니다.
import networkx as nx
import numpy as np
import time
def np_normalize_dict(input_dict):
"""
input_dict: {node_name: centrality_float}에서
value를 normalize하여 리턴.
"""
vs = np.array(list(input_dict.values()))
vs /= np.linalg.norm(vs)
return {k: v for k, v in zip(input_dict.keys(), vs)}
def custom_harmonic_centrality(G):
"""
node `u`의 harmonic centrality는
다른 모든 node `v`로 향하는 모든 shortest path length의 역수를 더한다.
"""
r_dict = {n:0 for n in G}
for n1 in G:
for n2 in G:
if n1!=n2:
n2_n1_l = nx.shortest_path_length(G, n2, n1)
#print(n1, n2, n1_n2_l)
r_dict[n1]+=1/n2_n1_l
return r_dict
########################
# Graph generation
N = 10 # node size
p = 0.5
G = nx.fast_gnp_random_graph(N, p, seed=0)
print("=="*20)
print("== custom harmonic centrality")
custom_harmonic_cent = custom_harmonic_centrality(G)
print("== nx - harmonic centrality")
nx_harmonic_cent = nx.harmonic_centrality(G)
# 만약, nx.harmonic_centrality와 다르다면 아래 코드에서 오류가 발생해야 함.
for n in G:
# To ignore underflow rounding.
round_c__h_cent = round(custom_harmonic_cent[n], 8)
round_nx_h_cent = round(nx_harmonic_cent[n], 8)
assert round_c__h_cent == round_nx_h_cent
print("=="*20)
#############################################
# Comparison with pagerank
# Graph generation
N = 100 # node size
p = 0.3
G = nx.fast_gnp_random_graph(N, p, seed=0)
G = nx.scale_free_graph(N)
G = nx.Graph(G)
print(f"nx.is_connected(G): {nx.is_connected(G)}")
print("==")
print("== computation time")
harmonic_time = time.time()
harmonic_cent = nx.harmonic_centrality(G)
harmonic_time = time.time() - harmonic_time
#harmonic_cent = np_normalize_dict(harmonic_cent) # normalize
print(f"harmonic computation time: {harmonic_time:10.6f}")
pagerank_time = time.time()
pagerank_cent = nx.pagerank(G)
pagerank_time = time.time() - pagerank_time
#pagerank_cent = np_normalize_dict(pagerank_cent) # normalize
print(f"pagerank computation time: {pagerank_time:10.6f}")
print(f"harmonic is {pagerank_time/harmonic_time:.2f} times faster than pagerank ")
print("==")
# value distribution
print("== histogram ")
harmonic_cent_v = list(harmonic_cent.values())
pagerank_cent_v = list(pagerank_cent.values())
# np histogram
bins=30
harmonic_bin, h_edge_bin = np.histogram(harmonic_cent_v, bins=bins)
pagerank_bin, p_edge_bin = np.histogram(pagerank_cent_v, bins=bins)
print("== harmonic, pagerank histogram")
MARKER = "="
for h, p in zip(harmonic_bin, pagerank_bin):
# left is harmonic
# right is pagerank
left = f"{MARKER*h:>50s}"
right = f"{MARKER*p:<50s}"
row = left + "|" + right
print(row)
print("=="*20)
- 그림으로 만들어서 처리하면 좋은데, 귀찮아서 그냥 아스키 아트로 히스토그램을 만들어서 넣었습니다후후후후.
========================================
== custom harmonic centrality
== nx - harmonic centrality
========================================
nx.is_connected(G): True
==
== computation time
harmonic computation time: 0.052979
pagerank computation time: 0.036304
harmonic is 0.69 times faster than pagerank
==
== histogram
== harmonic, pagerank histogram
==|===================================================================================
=|=========
===|===
======|=
==|
=============|
|
============|=
|=
=|
===============================|
===================|
=====|
=|=
|
|
=|
=|
|
|
|
=|
|
|
|
|
|
|
|
=|=
========================================
wrap-up
- centrality를 분석할 때, 사실 골치아픈 것중 하나가, scale-free network에서 대부분의 centrality가 쏠려 있다는 것이죠. 이렇게 할 경우에는 노드간의 차이가 크지 않아서, 해석에 어려움을 겪습니다.
- 반대로 harmonic centrlaity의 경우는 그 차이가 뚜렷하게 나타나므로 이를 비교하여 유의미한 분석을 할 수 있지 않을까 싶습니다.
reference
GitHub에서 이 글의 마크다운 원본 보기 & 수정 제안src/content/posts/2020-02-05-nx_alg_harmonic_centrality