注意:本文讲解怎样使用Python计算特征向量中心性,重在说明用什么样的python函数做这样的计算,而所举的例子是极其简化的,几乎没有实际意义。实际意义应该是这样的: 特征向量是描述动态系统变迁的,应用场景基本上是这样的:比如,一个社交网络,网络节点和相互连接的边能够描述一种“流动”,经过一定时间的变迁,将流动到一种稳定状态,就像一个稳定的生态系统,这个稳定状态就是用特征向量描述的。 Otto Bretscher写的Linear Algebra with Applications的2.1节Example 9讲了一个很好的例子,用互联网网页的访客分布为例,讲解了能够达到的均衡分布状态,就是特征向量。也就是说,面对一个互联网,不管一开始访客是怎样分布的,经过一定时间以后,分布状态会稳定下来。可见,稳定下来的这个特征向量就描述了这个动态系统的迁移特性。 那么,用在社交网络分析是那个,也是一样的道理。剩下的问题就是:用什么数据指标表示分布和迁移。这个问题确定了,才能带入到Python函数中进行计算。 好吧,言归正传,下面只讲怎样调用函数进行计算,而怎样建模,你要自己去设计。 1,本Notebook的背景介绍 本周我们分享了几篇借助社会网络分析方法进行研究的论文案例: 1. 网络社交平台中社群标签生成研究 该研究范文以 “豆瓣小组”为例进行实证研究,通过对网络社群的深入分析,发现社群特征可根据社群话题及用户兴趣予以表征。首先,利用主题提取BTM模型对网络社群话题进行主题模型训练,从而得到网络社群话题预标签; 其次,根据社群成员兴趣标签网络中不同类型的重要节点指标,利用TOPSIS多指标综合评价方法挖掘成员整体兴趣,从而得到网络社群成员兴趣预标签。 2. 突发公共事件网络新闻文本集信息关联及可视化 该研究范文以某事故网络新闻文本集为例,对突发公共事件网络新闻文本集信息关联及可视化进行了研究。本文首先界定了信息元的概念,对其关联规则进行了分析,然后以某事故为例进行了实证研究。研究结果表明,排名前30节点的节点度、特征向量中心性、中介中心性变化趋势基本一致,这些信息是某事故公众的关注焦点;随着时间的演变,公众对该突发事件的关注度与关注点也在发生变化。 这2个范例都使用了社交网络节点重要性度量的几个指标做辅助分析:点度中心度,中间中心度、接近中心度,特征向量中心度(eigenvector centrality)。 我们之前发布过在Jupyter Notebook中使用Python计算点度中心度,中间中心度、接近中心度的文章: 1. 怎样利用集搜客的共词矩阵表计算点度中心性(Degree centrality) 2. 如何使用Jupyter Notebook计算中介中心度(betweenness centrality) 3. 怎样使用Jupyter Notebook计算接近中心度 今天这个Notebook是使用Python进行特征向量中心度(Eigenvector Centrality)计算。 1.1,GooSeeker文本分词和情感分析软件已有的社会网络图功能 在之前的多个Notebook中,我们使用了GooSeeker文本分词和情感分析软件,进行中文文本的分词,词频统计,词云图生成,人工筛选,情感分析,社会网络图生成: 如果需要进一步的计算,比如,LDA聚类、主题分类、中心度等计算,我们会借助Jupyter Notebook,利用从GooSeeker文本分析软件导出的excel做进一步处理。 1.2,为什么做成Jupyter Notebook模板的形式 GooSeeker每年都要支持各个大学的毕业生采集数据完成他们的毕业设计。GooSeeker有一套微博数据采集工具,专门面向不希望编写网络爬虫程序的研究者设计的。 例如,可以先从微博关键词搜索入口,把搜到的涉及“xx城市空气”的微博话题采集下来,然后把这些话题的微博博文采集下来。微博博文内容呈现方式很丰富,文字、图片、视频都有。这些内容都可以采集下来,分别进行分析。例如,将视频采集下来以后抽取关键帧图片,利用图片分析方法进行分析。 针对重点的微博内容,可以深入采集转发和评论,转发者和评论者,可分析和描述传播的特征和转发者和评论者的传播者特征。还可以根据博主的粉丝数计算传播的量化特征。 GooSeeker推出多个微博数据采集工具,匹配高校师生从不同角度、不同传播路径、不同内容呈现采集数据的需求。同样也适用于公共领域和民间舆论场分析,市场和商业环境分析等。 数据采集下来之后,需要趁手的工具来做数据处理和数据分析,GooSeeker提供了文本分词和情感分析软件, 同时也推出了系列Jupyter Notebook,借助于python的大量第三方库,为数据分析大量强大的工具。 Jupyter Notebook这类交互式数据探索和分析工具代表了一股不容忽视的潮流,借助于Python编程的强大力量,数据加工的能力和灵活性已经有相当明显的优势,尤其是程序代码和文字描述可以混合编排,数据探索和数据描述做完了,一篇研究报告也基本上成型了。 然而Python毕竟是一个全功能的编程语言,对于非编程出身的数据分析师来说,Pandas,Numpy,Matplotlib这些词让人望而生畏。本系列Notebook将设法解决这个问题,让非编程出身的数据分析师能够忽略复杂的编程过程,专注于数据处理和统计分析部分,就像使用Excel的公式一样驾驭Python。 所以,我们将尝试发布一系列Jupyter Notebook,像文档模板,一些基本的程序环境设置、文件操作等固化下来,在设定的分析场景下不需要改动程序代码。而数据处理部分的代码可以根据需要截取选用。每一项功能用一个code cell存代码,不需要的处理功能可以删除。 1.3,notebook模板的存储结构 本notebook项目目录都预先规划好了,具体参看Jupyter Notebook项目目录规划参考。如果要做多个分析项目,可以把整个模板目录专门拷贝一份给每个分析项目。 2,简要技术说明 本notebook主要实现以下几个步骤: 1. 进行接近中心度计算实验 3,第三方库 decorator库版本5和network配合时有bug,需要安装4.2.2. 安装步骤如下: 1. 以管理员打开Anaconda PowerShell Prompt 2. 执行命令:pip install decorator==4.4.2 4,数据源 无。基于测试数据 5,修改历史 2021-09-03:第一版发布 6,版权说明 本notebook是GooSeeker大数据分析团队开发的,本notebook中的代码可自由共享使用,包括转发、复制、修改、用于其他项目中。 7,准备程序环境 导入必要的Python程序包。可以参看networkx计算中心度的官方文档 import networkx as nx import matplotlib.pyplot as plt import pylab import numpy as np %xmode Verbose import warnings 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,在网络中添加带权重的边 for i in range(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,计算特征向量中心度(eigenvector centrality)并输出值 eigenvector1 = nx.eigenvector_centrality(G1, max_iter=5000) #特征向量中心度中心度 print("输出特征向量中心度的计算值:") for item in eigenvector1: print(item,"\t",eigenvector1[item]) 输出特征向量中心度的计算值: 0 2.978034010258459e-06 1 0.002441987888411935 2 0.999997018338697 8.6,计算点度中心性(degree centrality)作为对比 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的值最大。进一步参考资料如下: 1. 可以参考文章中心性的度量---度中心性,间接中心性,紧密中心性,特征向量中的解释 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,在网络中添加带权中的边 for i in range(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 ) pylab.title('BetweennessCentralityTest',fontsize=25) pylab.show() 9.5,计算特征向量中心度(eigenvector centrality)并输出值 eigenvector2 = nx.eigenvector_centrality(G2, max_iter=5000) #特征向量中心度中心度 print("输出特征向量中心度的计算值:") for item in eigenvector2: print(item,"\t",eigenvector2[item]) 输出特征向量中心度的计算值: 0 1.3968827665765946e-08 1 1.054646488765327e-05 2 1.054646488765327e-05 3 1.054646488765327e-05 4 0.003978664355487948 5 0.003978664355487948 6 0.003978664355487948 7 0.9999762548961627 但是很奇怪的问题是: 1. 0和3之间的权重是很大的一个数字,无论改成什么,下面的结果都没有变化 2. 迭代次数取一个小一点的数字就没法算出结果,比如,1000 下面我们再看看点度中心度计算结果,做个对比。注意,下面用的函数不区分入度和出度,总的连接数多那么重要度就高 9.6,计算点度中心性(degree centrality)作为对比 dc = nx.degree_centrality(G2) print("输出点度中心度的计算值:") dc 输出点度中心度的计算值: {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 ) pylab.title('BetweennessCentralityTest',fontsize=25) pylab.show() 10.4,计算特征向量中心度(eigenvector centrality)并输出值 eigenvector3 = nx.eigenvector_centrality(G3, max_iter=1000) #特征向量中心度中心度 print("输出特征向量中心度的计算值:") for item in eigenvector3: print(item,"\t",eigenvector3[item]) 输出特征向量中心度的计算值: userA 0.0016800317461798174 user11 0.40824771432169543 user12 0.40824771432169543 user13 0.40824771432169543 user14 0.40824771432169543 user15 0.40824771432169543 user16 0.40824771432169543 11,总结 虽然用一些简单案例展示了networkx计算特征向量中心度,但是,从案例2的结论来看,似乎比较难解释,也许计算误差累计下来以后,对一些案例,看到的是有很大误差的结果。 看来有必要进一步调研一下networkx计算特征向量中心度的算法,根据官方的文档,该算法使用了Perron–Frobenius theorem,那么我们在后面的notebook中将专门研究一下这个算法的计算原理,跟线性代数里面讲的特征向量计算有什么差别。 12,下载本Notebook 下载notebook源代码请点击进入:使用python计算特征向量中心度 |