注意:本文讲解怎样使用Python计算特征向量中心性,重在说明用什么样的python函数做这样的计算,而所举的例子是极其简化的,几乎没有实际意义。实际意义应该是这样的:
那么,用在社交网络分析是那个,也是一样的道理。剩下的问题就是:用什么数据指标表示分布和迁移。这个问题确定了,才能带入到Python函数中进行计算。
好吧,言归正传,下面只讲怎样调用函数进行计算,而怎样建模,你要自己去设计。
1,本Notebook的背景介绍
这2个范例都使用了社交网络节点重要性度量的几个指标做辅助分析:点度中心度,中间中心度、接近中心度,特征向量中心度(eigenvectorcentrality)。
今天这个Notebook是使用Python进行特征向量中心度(EigenvectorCentrality)计算。
1.1,GooSeeker文本分词和情感分析软件已有的社会网络图功能
在之前的多个Notebook中,我们使用了GooSeeker文本分词和情感分析软件,进行中文文本的分词,词频统计,词云图生成,人工筛选,情感分析,社会网络图生成:
如果需要进一步的计算,比如,LDA聚类、主题分类、中心度等计算,我们会借助JupyterNotebook,利用从GooSeeker文本分析软件导出的excel做进一步处理。
1.2,为什么做成JupyterNotebook模板的形式
JupyterNotebook这类交互式数据探索和分析工具代表了一股不容忽视的潮流,借助于Python编程的强大力量,数据加工的能力和灵活性已经有相当明显的优势,尤其是程序代码和文字描述可以混合编排,数据探索和数据描述做完了,一篇研究报告也基本上成型了。
然而Python毕竟是一个全功能的编程语言,对于非编程出身的数据分析师来说,Pandas,Numpy,Matplotlib这些词让人望而生畏。本系列Notebook将设法解决这个问题,让非编程出身的数据分析师能够忽略复杂的编程过程,专注于数据处理和统计分析部分,就像使用Excel的公式一样驾驭Python。
所以,我们将尝试发布一系列JupyterNotebook,像文档模板,一些基本的程序环境设置、文件操作等固化下来,在设定的分析场景下不需要改动程序代码。而数据处理部分的代码可以根据需要截取选用。每一项功能用一个codecell存代码,不需要的处理功能可以删除。
1.3,notebook模板的存储结构
2,简要技术说明
本notebook主要实现以下几个步骤:
1.进行接近中心度计算实验
3,第三方库
decorator库版本5和network配合时有bug,需要安装4.2.2.安装步骤如下:
1.以管理员打开AnacondaPowerShellPrompt
2.执行命令:pipinstalldecorator==4.4.2
4,数据源
无。基于测试数据
5,修改历史
2021-09-03:第一版发布
7,准备程序环境
importnetworkxasnx
importmatplotlib.pyplotasplt
importpylab
importnumpyasnp
%xmodeVerbose
importwarnings
warnings.filterwarnings("ignore",category=DeprecationWarning)
8,实验一:3个节点2条边,节点0->节点1->节点2
8.1,定义图的邻接关系
#定义网络
vertices_s1=np.array([0,1])
vertices_e1=np.array([1,2])
value1=np.array([1,1])
8.2,生成一个空的有向图
G1=nx.DiGraph()
8.3,在网络中添加带权重的边
foriinrange(np.size(vertices_s1)):
G1.add_weighted_edges_from([(vertices_s1[i],vertices_e1[i],value1[i])])
8.4,画网络图
pos=nx.shell_layout(G1)
nx.draw(G1,pos,with_labels=True,node_color='white',edge_color='red',node_size=800,alpha=1)
pylab.title('BetweennessCentralityTest',fontsize=25)
pylab.show()
8.5,计算特征向量中心度(eigenvectorcentrality)并输出值
eigenvector1=nx.eigenvector_centrality(G1,max_iter=5000)#特征向量中心度中心度
print("输出特征向量中心度的计算值:")
foritemineigenvector1:
print(item,"\t",eigenvector1[item])
输出特征向量中心度的计算值:
02.978034010258459e-06
10.002441987888411935
20.999997018338697
8.6,计算点度中心性(degreecentrality)作为对比
dc=nx.degree_centrality(G1)
print("输出点度中心度的计算值:")
dc
输出结果是:
输出点度中心度的计算值:
{0:0.5,1:1.0,2:0.5}
输出结果可见:调用的degree_centrality没有区分入度和出度,所以,节点1连接数最多
8.7,输出结果解读
上面的图实际上是一条链,权重从节点0传递到1,再到2,所以,节点2的值最大。进一步参考资料如下:
2.可以结合网络结构,对比点度中心度,中间中心度、接近中心度,特征向量中心度的计算结果
9,实验二:有8个节点的情况
9.1,定义图的邻接关系
从下面的代码可以看到,其实跟上面的图有点区别,每个节点增加了自环,而且自环权重都是1。如果表示成矩阵的话,对角线上的数值就是1,看看能算出来什么结果
#自定义网络
vertices_s2=np.array([0,1,2,3,4,5,6,7,0,0,0,3,2,2,4])
vertices_e2=np.array([0,1,2,3,4,5,6,7,1,2,3,6,4,5,7])
value2=np.array([1,1,1,1,1,1,1,1,3,3,3,3,3,3,3])
9.2,生成一个空的有向图
G2=nx.DiGraph()
9.3,在网络中添加带权中的边
foriinrange(np.size(vertices_s2)):
G2.add_weighted_edges_from([(vertices_s2[i],vertices_e2[i],value2[i])])
9.4,画网络图
pos=nx.shell_layout(G2)
nx.draw(G2,pos,with_labels=True,node_color='white',edge_color='red',node_size=800,alpha=1)
9.5,计算特征向量中心度(eigenvectorcentrality)并输出值
eigenvector2=nx.eigenvector_centrality(G2,max_iter=5000)#特征向量中心度中心度
foritemineigenvector2:
print(item,"\t",eigenvector2[item])
01.3968827665765946e-08
11.054646488765327e-05
21.054646488765327e-05
31.054646488765327e-05
40.003978664355487948
50.003978664355487948
60.003978664355487948
70.9999762548961627
但是很奇怪的问题是:
1.0和3之间的权重是很大的一个数字,无论改成什么,下面的结果都没有变化
2.迭代次数取一个小一点的数字就没法算出结果,比如,1000
下面我们再看看点度中心度计算结果,做个对比。注意,下面用的函数不区分入度和出度,总的连接数多那么重要度就高
9.6,计算点度中心性(degreecentrality)作为对比
dc=nx.degree_centrality(G2)
{0:0.7142857142857142,
1:0.42857142857142855,
2:0.7142857142857142,
3:0.5714285714285714,
4:0.5714285714285714,
5:0.42857142857142855,
6:0.42857142857142855,
7:0.42857142857142855}
10,实验三:知乎主题传播的示意图
10.1,生成一个空的有向图
G3=nx.DiGraph()
10.2,为这个网络添加节点和边
G3.add_edge('userA','user11')#添加边
G3.add_edge('userA','user12')#添加边
G3.add_edge('userA','user13')#添加边
G3.add_edge('userA','user14')#添加边
G3.add_edge('userA','user15')#添加边
G3.add_edge('userA','user16')#添加边
10.3,画网络图
pos=nx.shell_layout(G3)
nx.draw(G3,pos,with_labels=True,node_color='white',edge_color='red',node_size=800,alpha=1)
10.4,计算特征向量中心度(eigenvectorcentrality)并输出值
eigenvector3=nx.eigenvector_centrality(G3,max_iter=1000)#特征向量中心度中心度
foritemineigenvector3:
print(item,"\t",eigenvector3[item])
userA0.0016800317461798174
user110.40824771432169543
user120.40824771432169543
user130.40824771432169543
user140.40824771432169543
user150.40824771432169543
user160.40824771432169543
11,总结
虽然用一些简单案例展示了networkx计算特征向量中心度,但是,从案例2的结论来看,似乎比较难解释,也许计算误差累计下来以后,对一些案例,看到的是有很大误差的结果。
看来有必要进一步调研一下networkx计算特征向量中心度的算法,根据官方的文档,该算法使用了Perron–Frobeniustheorem,那么我们在后面的notebook中将专门研究一下这个算法的计算原理,跟线性代数里面讲的特征向量计算有什么差别。