最近做了一些社会网络分析的工作,在这里写一个简单的总结。
一. 工具
1. Python 3.7
2. NetworkX 2.3
这是一个专门用于复杂网络分析的包,执行pip install networkx即可安装。
二、网络基本性质
1. 节点数
网络中包含的节点个数。
2. 连接数
网络中包含的边的个数。
3. 密度
网络中包含的边的个数占网络中所有可能的边的个数的比例。
4. 聚集系数
也称为局部聚集系数,是网络中每个节点的聚集系数的平均值。节点的聚集系数为,将该节点的所有邻居两两组合,则共有种组合,组合中的两个节点为邻居的组合数占所有组合数的比例即为该节点的聚集系数。
5. 传递性
也称为全局聚集系数,即网络中的三角形结构占所有可能的三角形结构的比例。
6. 互惠性
互惠性是有向图的性质,即在有向图中,双向连接的边占所有边的比例。
三、中心性分析
中心性分析包括两方面,分别是节点的中心度和整体网络的中心势。
1. 节点中心度
节点中心度包括三种,分别为度数中心度、接近中心度和中介中心度。
(1)度数中心度(degree centrality)
度数中心度是与某节点直接相连的其他节点的个数,如果一个点与许多点直接相连,那么该点具有较高的度数中心度。在有向图中,度数中心度分为出度中心度和入度中心度。由于这种测量仅关注与某一个节点直接相连的点数,忽略间接相连的点数,因此被视为局部中心度。
(2)接近中心度(closeness centrality)
接近中心度是某个节点与图中所有其他点的最短距离之和的倒数,一个点越是与其他点接近,该点在传递信息方面就越不依赖其他节点,则该点就具有较高的接近中心度。在有向图中,接近中心度分为出接近中心度和入接近中心度。
(3)中介中心度(betweenness centrality)
中介中心度测量了某个节点在多大程度上能够成为“中间人”,即在多大程度上控制他人。如果一个节点处于多个节点之间,则可以认为该节点起到重要的“中介”作用,处于该位置的人可以控制信息的传递而影响群体。
(4)绝对中心度和相对中心度
上面描述的三种中心度的计算方法都是绝对中心度,绝对中心度有一个缺陷是,对于不同结构和规模的网络中的节点,其中心度无法直接进行比较,因此提出了相对中心度。相对中心度可以理解为是对绝对中心度进行了标准化。相对中心度的计算公式如下:
度数中心度:
是节点的邻居数量,是网络中的所有节点的集合,是网络中节点的个数。接近中心度:
是所有从节点出发可达的节点集合,为节点和节点之间的最短距离。中介中心度:
是节点与节点之间最短路径的条数,是节点与节点之间经过节点的最短路径的条数。
2. 网络中心势
整体网络的中心势与节点的中心度相对应,也有三种,分别为度数中心势、接近中心势和中介中心势。
(1)度数中心势(degree centralization)
(2)接近中心势(closeness centralization)
(3)中介中心势(betweenness centralization)
四、利用NetworkX来进行社会网络分析
1. 构建网络
在networkx中定义了许多种网络,例如无向图、有向图、二分图、多层网络等等,这里我们使用有向图来做分析。
import networkx as nx
G = nx.DiGraph() #初始化一个有向图
G.add_edge('A', 'B') #添加边
G.add_edge('A', 'D')
G.add_edge('B', 'C')
G.add_edge('B', 'D')
G.add_edge('D', 'E')
G.add_edge('E', 'D')
在这里我们初始化了一个有5个节点、6条边的有向图,注意,在给有向图添加边的时候,节点的顺序非常重要,第一个节点代表起点,第二个节点代表终点。
2. 网络基本性质
在network中可以直接计算网络的基本性质。
num_nodes = nx.number_of_nodes(G) #节点书
num_edges = nx.number_of_edges(G) #连接数
density = nx.density(G) #密度
clusterint_coefficient = nx.average_clustering(G) #平均聚集系数/局部聚集系数
transitivity = nx.transitivity(G) #传递性/全局聚集系数
reciprocity = nx.reciprocity(G) #互惠性
print('节点个数: ', num_nodes)
print('连接数: ', num_edges)
print('密度: ', density)
print('局部聚集系数: ', clusterint_coefficient)
print('全局聚集系数: ', transitivity)
print('互惠性: ', reciprocity)
输出为:
节点个数: 5
连接数: 6
密度: 0.3
局部聚集系数: 0.15333333333333332
全局聚集系数: 0.25
互惠性: 0.3333333333333333
3. 中心度计算
在networkx中计算出来的中心度均为相对中心度。
out_degree = nx.out_degree_centrality(G) #出度中心度
in_degree = nx.in_degree_centrality(G) #入度中心度
out_closeness = nx.closeness_centrality(G.reverse()) #出接近中心度
in_closeness = nx.closeness_centrality(G) #入接近中心度
betweenness = nx.betweenness_centrality(G) #中介中心度
print('出度中心度: ', out_degree)
print('入度中心度: ', in_degree)
print('出接近中心度: ', out_closeness)
print('入接近中心度: ', in_closeness)
print('中介中心度: ', betweenness)
输出为:
出度中心度: {'A': 0.5, 'B': 0.5, 'D': 0.25, 'C': 0.0, 'E': 0.25}
入度中心度: {'A': 0.0, 'B': 0.25, 'D': 0.75, 'C': 0.25, 'E': 0.25}
出接近中心度: {'A': 0.6666666666666666, 'B': 0.5625, 'D': 0.25, 'C': 0.0, 'E': 0.25}
入接近中心度: {'A': 0.0, 'B': 0.25, 'D': 0.75, 'C': 0.3333333333333333, 'E': 0.44999999999999996}
中介中心度: {'A': 0.0, 'B': 0.08333333333333333, 'D': 0.16666666666666666, 'C': 0.0, 'E': 0.0}
4. 中心势计算
在networkx中没有似乎没有直接计算中心势的方法,这里我们可以根据公式自己计算。
max_ = 0
s = 0
for out in out_degree.keys():
if(out_degree[out] > max_): max_ = out_degree[out]
s = s + out_degree[out]
print('出度中心势:', (num_nodes * max_ - s) / (num_nodes - 2))
max_ = 0
s = 0
for in_ in in_degree.keys():
if(in_degree[in_] > max_): max_ = in_degree[in_]
s = s + in_degree[in_]
print('入度中心势:', (num_nodes * max_ - s) / (num_nodes - 2))
max_ = 0
s = 0
for b in out_closeness.keys():
if(out_closeness[b] > max_): max_ = out_closeness[b]
s = s + out_closeness[b]
print('出接近中心势:', (num_nodes * max_ - s) / (num_nodes- 1) / (num_nodes - 2) * (2 * num_nodes - 3))
max_ = 0
s = 0
for b in in_closeness.keys():
if(in_closeness[b] > max_): max_ = in_closeness[b]
s = s + in_closeness[b]
print('入接近中心势:', (num_nodes * max_ - s) / (num_nodes- 1) / (num_nodes - 2) * (2 * num_nodes - 3))
max_ = 0
s = 0
for b in betweenness.keys():
if(betweenness[b] > max_): max_ = betweenness[b]
s = s + betweenness[b]
print('中介中心势:', (num_nodes * max_ - s) / (num_nodes - 1))
输出为:
出度中心势: 0.3333333333333333
入度中心势: 0.75
出接近中心势: 0.9357638888888888
入接近中心势: 1.1472222222222221
中介中心势: 0.14583333333333331
5. 绘制
import matplotlib.pyplot as plt
nx.draw(G)
plt.show()
输出为:
当然,这个是最简单的画图方法了,networkx中还有更复杂的方法,可以根据自己的需要来进行个性化的处理。
以后有时间再写一下networkx画图~