快捷导航

Jupyter Notebook使用Python计算特征向量中心度(Eigenvector Centrality)

2021-9-7 10:50| 发布者: Fuller| 查看: 3326| 评论: 0

摘要: 今天这个Notebook是使用Python进行特征向量中心度(Eigenvector Centrality)计算。上周分享的2个范例都使用了社交网络节点重要性度量的几个指标做辅助分析:点度中心度,中间中心度、接近中心度,特征向量中心度(eige ...

注意:本文讲解怎样使用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

Jupyter Notebook使用Python计算特征向量中心度(Eigenvector Centrality).zip


鲜花

握手

雷人

路过

鸡蛋

最新评论

GMT+8, 2023-2-2 08:50