import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
def CALC_katz_by_summation(G, alpha=None, beta = 0.2, normalized=True):
"""
- katz centrality는 각 노드에서 시작된 어떤 "정보"가 시간 t가 변함에 따라, 다른 노드에 얼마나 영향을 주는지 확인하는 방법
- 이 때 전파 강도를 alpha를 통해 조절하고, beta를 통해 lower bound를 설정함
- 즉, 각 노드별로 얼마나 다른 노드에 파급력 있게 정보를 전달하는지를 summation을 통해서도 계산할 수 있음.
- 물론, 다음 함수에서 설명할,
"""
alpha = 0.1
A = nx.to_numpy_matrix(G)
Sum_A = np.zeros(A.shape)
# k degree마다 alpha**k, A**k를 곱하여 더해줌.
for k in range(1, 100):
Sum_A += np.multiply(alpha**k, A**k)+0.2
# i: source, j: target
# 즉, j에 대해서 더해줘야, k일 때, j에 남아있는 값들을 알 수 있음.
katz_cent = Sum_A.sum(axis=0)
# normalize
if normalized==True:
norm = np.sign(sum(katz_cent)) * np.linalg.norm(katz_cent)
else:
norm = 1
katz_cent = katz_cent / norm
katz_cent_dict = {n:katz_cent[i] for i, n in enumerate(G)}
return katz_cent_dict
def CALC_katz_by_lin_eq(G):
"""
linear eq: (I - alpha*A) = b
를 풀어서, katz centrality를 계산하는 방법.
"""
A = nx.adj_matrix(G).T
n = A.shape[0]
alpha = 0.1
b = np.ones((n, 1)) * float(1)
# linear equation solve
centrality = np.linalg.solve(np.eye(n, n) - (alpha * A), b)
norm = np.sign(sum(centrality)) * np.linalg.norm(centrality)
centrality = centrality/norm
centrality = {n: centrality[i][0] for i, n in enumerate(G)}
#print(centrality)
return centrality
########################################
# Generate Graph
G = nx.random_k_out_graph(n=200, k=2, alpha=0.5, seed=0)
G = nx.DiGraph(G.copy()) # MultiDiGraph => DiGraph
katz_by_summation = CALC_katz_by_summation(G)
katz_by_lineq = CALC_katz_by_lin_eq(G)
##########################################
# katz centrality의 corrleation값을 통해 비교함.
katz_corr = np.correlate([*katz_by_summation.values()],
[*katz_by_lineq.values()])
print(f"== correlation: {katz_corr[0]: 5.3%}")
##########################################
# katz centrality를 비교하여, 순위가 다른치 체크함.
# value로 보면 값이 조금씩 다른데, 최대 최소값이 조금씩 다를 수는 있어도, 순위 자체는 큰 차이가 없음
# katz by summation
katz1 = sorted(katz_by_summation.items(), key=lambda x: x[1], reverse=True)
katz1 = map(lambda x: x[0], katz1)
# katz_by_lineq
katz2 = sorted(katz_by_lineq.items(), key=lambda x: x[1], reverse=True)
katz2 = map(lambda x: x[0], katz2)
COUNT_rank_diff = 0
for n1, n2 in zip(katz1, katz2):
if n1!=n2:
COUNT_rank_diff+=1
print(f"== COUNT_rank_diff %: {COUNT_rank_diff}")
댓글남기기