CS224W课程学习笔记(二):网络图的特征说明和指标实战

news2024/9/24 3:18:00

引言

在第二三节课中,主要研究的是四个关键网络属性以表征图形:度分布,路径长度,聚类系数和连接组件 。 这些定义主要是针对无向图的,而由于上一节中已经介绍了度分布,以及相应公式和例题,关于路径长度,简单来讲就是一个图中所需占比最短的一条或者多条路径,该路径并不唯一,讲深点,就得从过程遍历来看列举的四种算法了,每种都有每种的优劣,这里也不再详述,主要根据课程助教写的笔记,针对后两个重新复习。


C l u s t e r i n g    C o e f f i c i e n t Clustering \ \ Coefficient Clustering  Coefficient

聚类系数(针对无向图)用于衡量节点 i i i 的邻居所占比例。 对于度数为 k i k_{i} ki的节点 i i i,我们计算聚类系数为 C i = 2 e i k i ( k i − 1 ) C_{i}=\frac{2e_{i}}{k_{i}(k_{i}-1)} Ci=ki(ki1)2ei 其中 e i e_{i} ei 是节点 i i i 的相邻节点之间的边数。 注意 C i ∈ [ 0 , 1 ] C_{i}\in[0,1] Ci[0,1] 。 此外,对于度数为0或1的节点,聚类系数是不确定的。

同样,可以计算平均聚类系数为: C = 1 N ∑ i N C i C=\frac{1}{N}\sum_{i}^{N}C_{i} C=N1iNCi 平均聚类系数使我们能够看到边在网络的某些部分是否显得更加密集。 在社交网络中,平均聚类系数趋于很高,表明如我们期望的那样,朋友的朋友倾向于彼此认识。

该点还会在之后提到,这里只做简单概述

C o n n e c t i v i t y Connectivity Connectivity

图的连通性可衡量最大连通组件的大小。 最大的连通组件是可以通过路径将任意两个顶点连接在一起的图的最大的集合。

查找连接的组件:

  1. 从随机节点开始并执行广度优先搜索(BFS)
  2. 标记BFS访问的节点
  3. 如果访问了所有节点,则表明网络是连通的
  4. 否则,找到一个未访问的节点并重复BFS

课程链接与相关工具介绍

斯坦福原版视频

https://www.youtube.com/watch?v=3IS7UhNMQ3U&list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&index=4

https://www.youtube.com/watch?v=4dVwlE9jYxY&list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&index=5

https://www.youtube.com/watch?v=buzsHTa4Hgs&list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&index=6

本节课学习资料与工具

本节的助教笔记:https://snap-stanford.github.io/cs224w-notes/preliminaries/measuring-networks-random-graphs

同济子豪的笔记:https://github.com/TommyZihao/zihao_course/blob/main/CS224W/2-tradition-ml.md

NetworkX-常用图数据挖掘算法:https://networkx.org/documentation/stable/reference/algorithms/index.html

NetworkX-节点重要度算法:https://networkx.org/documentation/stable/reference/algorithms/centrality.html

NetworkX-Clustering算法:https://networkx.org/documentation/stable/reference/algorithms/clustering.html

NetworkX-最短路径算法:https://networkx.org/documentation/stable/reference/algorithms/shortest_paths.html

CSC641-Fall2015-Module-2-Centrality-Measures:https://www.jsums.edu/nmeghanathan/files/2015/08/CSC641-Fall2015-Module-2-Centrality-Measures.pdf?x61976

网络图的特征

社会网络分析(非224w,实为经济学(简单,复杂的不会,emmm))

1736年,瑞上:的著名数学家欧拉(L.Euler,1707~1783 )用图论方法解决了柯尼斯堡桥问题(Konigsberg Bridge Problem)(参见张贵新,1989:140~146)。他的解决方法是把与该桥相关的数学规念转换为由点和线构成的图形、从而给出相应的证明。

这种观念在数学和很多应用科学领域中得到多次体现。在统计学中,学者们发展出了马尔可夫随机链(Markov random chains);在物理学中,学者们利用图形来理解欧氏空间中相互联络的各个分子之间的关系,即使按照相对论,大尺度空间是弯曲的黎曼空间,也可以利用图论方法研究物理空间结构;在运筹学(operations research)中,人们利用树形图法表达物品的位置以及物资流通的渠道。

图可以有多种类型:条形图、趋势分析图等等,这些作为我们所熟悉的,可以统称为“变量图”,它表征的是变量的频次等属性。而网络社群图,主要由三要素构成:

  1. 行动者(actors): 比如人组成的网络,班级组成的网络,学校组成的网络。
  2. 联系(ties): 即线(边),代表着行动者之间的关系,比如维系人和人的社会关系如亲情、友情和爱情,班级内部交流,学校组的5G等等。
  3. 边界(boundary): 这些行动者和边需要确定一个界限,比如一个地区人口,比如政府单位人员,或者在某种限定条件下做同一件事情的人。

如果一个图符合上述三个要素,那么就是一个社交网络图,作为网络图的一种,它和上一篇中提到的整个图框架是被包含的关系,即它也有无向图和有向图,能用矩阵去表示,但是因为值域不同,所以操作还是有所限制,具体的一个过程见如下导图:

在这里插入图片描述

社网图中心性

上节相当于介绍了社会网络图的一个概念与数据准备工作,预先构造关系矩阵,本节即是介绍怎么评价一个网络图的指标,即特征的中心性,这里介绍主要的几种,见如下表格:

 度数中心性(Degree)中间(介性)中心性(betweenness)接近中心性(Closeness)
绝对点度中心度 C A D i = d ( i ) = ∑ j X i j C_{ADi}=d\left( i \right) =\sum_j{X}_{ij} CADi=d(i)=jXij C A B i = ∑ j < k b j k ( i ) = ∑ j < k g j k ( i ) / g j k C_{A B i}=\sum_{j<k} b_{j k}(i)=\sum_{j<k} g_{j k}(i) / g_{j k} CABi=j<kbjk(i)=j<kgjk(i)/gjk C A P i − 1 = ∑ j d i j C_{A P i}^{-1}=\sum_{j} d_{i j} CAPi1=jdij
相对点度中心度 C R D i = d ( i ) / ( n − 1 ) C_{RDi}^{}=d\left( i \right) /\left( n-1 \right) CRDi=d(i)/(n1) C R B i = 2 C A B i / [ ( n − 1 ) ( n − 2 ) ] C_{RBi}^{}=2C_{ABi}^{}/\left[ \left( n-1 \right) \left( n-2 \right) \right] CRBi=2CABi/[(n1)(n2)] C R P i − 1 = 2 C A P i − 1 / ( n − 1 ) C_{RPi}^{-1}=2C_{APi}^{-1}/\left( n-1 \right) CRPi1=2CAPi1/(n1)
图的中心势 C A D = ∑ i ( C A D max ⁡ − C A D i ) ( n − 1 ) ( n − 2 ) C R D = ∑ i ( C R D max ⁡ − C R D i ) n − 2 \begin{array}{l}{C_{A D}=\frac{\sum_{i}\left(C_{A D \max }-C_{A D i}\right)}{(n-1)(n-2)}} \\ {C_{R D}=\frac{\sum_{i}\left(C_{R D \max }-C_{R D i}\right)}{n-2}}\end{array} CAD=(n1)(n2)i(CADmaxCADi)CRD=n2i(CRDmaxCRDi) C B = 2 ∑ i ( C A B max ⁡ − C A B i ) / [ ( n − 1 ) 2 ( n − 2 ) ] = 2 ∑ i ( C B B max ⁡ − C R B i ) / ( n − 1 ) C_B=2\sum_i{\left( C_{AB\max}-C_{ABi} \right)}/\left[ \left( n-1 \right) ^2\left( n-2 \right) \right] =2\sum_i{\left( C_{BB\max}-C_{RBi} \right)}/\left( n-1 \right) CB=2i(CABmaxCABi)/[(n1)2(n2)]=2i(CBBmaxCRBi)/(n1) C C = ∑ i ( C R C max ⁡ ′ − C R C i ′ ) ( n − 2 ) ( n − 1 ) ( 2 n − 3 ) C_{C}=\frac{\sum_{i}\left(C_{R C \max }^{\prime}-C_{R C i}^{\prime}\right)}{(n-2)(n-1)}(2 n-3) CC=(n2)(n1)i(CRCmaxCRCi)(2n3)

以及第四种特征向量中心性,对于给定的图 G : = ( V , E ) G:=(V,E) G:=(V,E) ∣ V ∣ |V| V顶点让 A = ( a v , t ) A=(a_{v},t) A=(av,t)是邻接矩阵,即 a v , t = 1 {\displaystyle a_{v,t}=1} av,t=1 如果顶点 v {\displaystyle v} v链接到顶点 t {\displaystyle t} t吨, 和 a v , t = 0 a v , t = 0 {\displaystyle a_{v,t}=0}a_{v,t} = 0 av,t=0av,t=0,否则相对中心性得分 x v {\displaystyle x_{v}} xv 的顶点 v {\displaystyle v} v可以定义为:
x v = 1 λ ∑ t ∈ M ( v ) x t = 1 λ ∑ t ∈ V a v , t x t {\displaystyle x_{v}={\frac {1}{\lambda }}\sum _{t\in M(v)}x_{t}={\frac {1}{\lambda }}\sum _ {t\in V}a_{v,t}x_{t}} xv=λ1tM(v)xt=λ1tVav,txt

这可以用矢量符号重写为特征向量方程,即为:

A x = λ x {\displaystyle \mathbf {Ax} =\lambda \mathbf {x} } Ax=λx

这四种中心性就基本概括了一个网络图所能表示的所有指标或者说信息,它们切断了嘈杂的数据,揭示了需要注意的网络部分,但每种代表的具体含义各不相同,以下为我查找资料的时候对每个中心性做的一些解释:

  • 点的度中心性(Degree Centrality): 度中心性仅根据每个节点持有的链接数分配重要性分数,它能告诉我们,每个节点与网络中的其他节点之间有多少直接的“一跳”连接。度中心性是节点连接性的最简单度量。有时将入度(入站链接的数量)和出度(出站链接的数量)视为不同的衡量标准很有用,例如在查看交易数据或帐户活动时。

  • 点的近性中心度(Closeness Centrality): 近似中心性根据每个节点与网络中所有其他节点的“接近度”对每个节点进行评分。一个点的近性中心度较高,说明该点到网络中其他各点的距离总体来说较近,反之则较远。假如一个物流仓库网络需要选某个仓库作为核心中转站,需要它到其他仓库的距离总体来说最近,那么一种方法就是找到近性中心度最高的那个仓库。

  • 点的介性中心度(Betweenness Centrality): 介数中心性衡量一个节点位于其他节点之间最短路径上的次数。一个点的介性中心度较高,说明其他点之间的最短路径很多甚至全部都必须经过它中转,相当于显示哪些节点是网络中节点之间的“桥梁”。假如这个点消失了,那么其他点之间的交流会变得困难,甚至可能断开(因为原来的最短路径断开了)。一般用于查找影响系统周围流程的个人,但应该谨慎使用,因其可能表明某人对网络中不同的集群拥有权限,如果被hack将造成不可预估的影响。小概率可能只是他们在两个集群的外围。

  • 特征向量中心性(eigenvector centrality): 特征向量中心性基于特征值,这意味着实体的价值基于与其相连的实体的价值:后者越高,前者就越高。但与其它三个中心性不同的是,它表示的是实体的重要性,一个实体本身度数中心性高,或介数中心性高,或接近中心性高,其特征向量中心性不一定高。举个例子,如果一个实体 A 连接到许多其他实体,但这些其他实体本身是外围的并且没有进一步连接到其他实体,则实体 A 将具有高度中心性,但特征向量中心性低。因此,具有高特征向量中心性的实体与网络中的突出/流行/重要实体相关联,即使它本身不受欢迎,也可以利用其连接的流行度和影响力。相当于在人类社会网络中,具有影响力的人可以获取到特殊的待遇以及相应的权利。

总结完中心性的定义,会在最后用一个代码实战案例进行实践,感兴趣的还可以看很早之前也算是我所有博客里数据最好的 ucinet网络分析使用总结,这就是专门的一个社会网络分析工具,那么切回正题。

图模型的分类

ES模型图模型

ES随机图模型(Erdös-Renyi Random Graph Model),用于生成无向图,它有两类:

  1. G n p G_{np} Gnp: 具有 n n n 个节点的无向图,并且每条边 ( u , v ) (u,v) (u,v) 出现的概率符合概率为 p p p 的独立同步分布
  2. G n m G_{nm} Gnm: 具有n个节点的无向图,随机地均匀地选择 m m m 条边

然后课上又重新回顾了网络图的四种属性,针对该种网络。

The Clustering Coefficient of G n p G_{np} Gnp

回顾一下,聚类系数的计算公式为 C i = 2 e i k i ( k i − 1 ) C_{i}=\frac{2e_{i}}{k_{i}(k_{i}-1)} Ci=ki(ki1)2ei 其中 e i e_{i} ei 是节点 i i i 的相邻节点之间的边数。因为在 G n p G_{np} Gnp 中边出现的概率符合概率为 p p p 的独立同分布,所以图 G n p G_{np} Gnp 中期望的 e i e_{i} ei E [ e i ] = p k i ( k i − 1 ) 2 \mathbb{E}\left[e_{i}\right]=p \frac{k_{i}\left(k_{i}-1\right)}{2} E[ei]=p2ki(ki1) 这是因为 k i ( k i − 1 ) 2 \frac {k_{i}(k_{i}-1)} {2} 2ki(ki1) 是度为 k i k_{i} ki 的节点 i i i 的邻居的不同对的数量,并且每一对以概率 p p p 相连接。

因此,聚类系数的期望为: E [ C i ] = p ⋅ k i ( k i − 1 ) k i ( k i − 1 ) = p = k ˉ n − 1 ≈ k ˉ n \mathbb{E}\left[C_{i}\right]=\frac{p \cdot k_{i}\left(k_{i}-1\right)}{k_{i}\left(k_{i}-1\right)}=p=\frac{\bar{k}}{n-1} \approx \frac{\bar{k}}{n} E[Ci]=ki(ki1)pki(ki1)=p=n1kˉnkˉ k ˉ \bar{k} kˉ 表示平均度,平均度系数允许我们查看边缘是否在网络的某些部分出现得更密集。从上面公式可以得到, G n p G_{np} Gnp 的聚类系数非常小,如果我们以固定的平均度 生成 k ˉ \bar{k} kˉ 一个非常非常大的图,那么 C C C 随着规模 n n n 的增大而减小。 E [ C i ] → 0 \mathbb{E}\left[C_{i}\right] \rightarrow 0 E[Ci]0 as n → ∞ n \rightarrow \infty n

Some Network Properties of G n p G_{np} Gnp

G n p G_{np} Gnp 的度分布符合二项分布,设 P ( k ) P(k) P(k) 表示具有度为 k k k 的节点数,则 P ( k ) = ( n − 1 k ) p k ( 1 − p ) n − 1 − k P(k)=\left(\begin{array}{c} n-1 \\ k \end{array}\right) p^k(1-p)^{n-1-k} P(k)=(n1k)pk(1p)n1k 二项分布的均值和方差分别为 k ˉ = p ( n − 1 ) \bar{k}=p(n-1) kˉ=p(n1) σ 2 = p ( 1 − p ) ( n − 1 ) \sigma^{2}=p(1-p)(n-1) σ2=p(1p)(n1)

二项式分布的一个特性是,根据数字定律,随着网络规模的增加,分布变得越来越狭窄。

The Path Length of G n p G_{np} Gnp

关于这个我看事后笔记没看懂,又不想回头在翻视频了,因为当时听的时候可能就是以数据结构的理念去听的,这里大致讲一下,要讨论 G n p G_{np} Gnp 的路径长度,需要引入一个扩展系数的概念。即:
α = min ⁡ S ⊂ V  # edges leaving  S min ⁡ ( ∣ S ∣ , ∣ V \ S ∣ ) \alpha=\min _{S \subset V} \frac{\text { \# edges leaving } S}{\min (|S|,|V \backslash S|)} α=SVminmin(S,V\S) # edges leaving S

关于扩展系数的一个重要事实是,在具有 n n n 个节点且扩展系数为 α α α 的图中,对于所有的节点对,将有 O ( ( log ⁡ n ) / α ) O((\log n)/\alpha) O((logn)/α) 条路径连接他们。它描述了图的任意节点集与剩余节点之间边的数量。
在这里插入图片描述

The Connectivity of G n p G_{np} Gnp

下图显示了随机图 G n p G_{np} Gnp 的演变,我们可以看到当平均度 k ˉ = 2 E / n \bar{k}=2E/n kˉ=2E/n p = k ˉ / ( n − 1 ) p=\bar{k}/(n-1) p=kˉ/(n1) 时,出现了一个巨大的连通组件。

在这里插入图片描述

相当于从左到右,数值概率在不断增大,然后图也在发生着改变。然后下一页就是老师做的一个实验,对于10万个节点的图, k = p ( n − 1 ) k=p(n-1) k=p(n1)从0.5到3对于巨分支的节点占比情况:
在这里插入图片描述

模型对比

而通过该模型网络复习了图的四个概念以及根据该概率图特性做的一些变化后,跟之前的现实模型可以做一个对比,对比图如下:

在这里插入图片描述

可以看到:

  • 优点

    • 巨分支所占比例是接近的
    • 平均路径长度也比较接近
  • 不足

    • 度分布差异较大。 现实网络呈现幂律分布,而随机图呈现泊松分布(二项分布)
    • 聚类系数相差极大。对于这一属性,这才是应该更关注。

总结一下,随机图模型 G n p G_{np} Gnp很粗糙,对于现实网络的拟合并不好。但是,并不是学习它没有意义,它是后续随机图模型的“迭代”基础。算是地基工程!

随机Kronecker图模型

Kronecker图

随机 Kronecker 图

模型对比

在这里插入图片描述

中心性实战

这里主要复现了 苏轼的朋友圈——基于 networkx 进行社交网络分析(SNA) 中的代码与参考了其内容,非常值得推荐。

因为该文是2018年所写,采用的数据库在我查找的时候已经没有了,但所幸,我所使用的2020版本的数据库,与之前的基本一致,以下就是过程。

本次实验与参考环境用的一致,为sqlite,相比于MySQL,它少了事务以及跨主机的复杂功能,但作为优点,就是演示简单,即插即用。而因为我所使用是Linux环境,在Linux中,如果以源码方式编译python,之前一定会经过下载sqlite,即apt-get install libsqlite3-dev,所以一般是默认安装了sqlite,或者可以直接安装anaconda集成环境,就省略了python编译过程。那在确认环境无误后,导入依赖包以及数据库,代码为:

import sqlite3

import numpy as np
import pandas as pd
import networkx as nx

import matplotlib as mpl
import matplotlib.pyplot as plt
plt.style.use('seaborn')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 数据库文件
db = 'CBDB_20200528.db'

数据来源于 CBDC(China Biographical Database),即中国历代人物传记数据库

去网站上选择download,然后根据所需年份,选择数据库,这里如果用MySQL的话,需要先导入数据库,然后代码层面还需要加一个数据库类,不复杂,但作为一个小demo也有点大材小用,那sqlite就方便多了,直接查询,为:

# 查找 person_id 函数
def getPersonId(person_name):
    ''' Get person_id
    @param person_name: str
    @return person_id: str
    '''
    sql = '''
    SELECT c_personid
    FROM biog_main
    WHERE c_name_chn = '{0}'
    '''.format(person_name)

    try:
        person_id = str(pd.read_sql(sql, con=sqlite3.connect(db)).iloc[0, 0])
        return person_id
    except:
        print("No such person.")

# 查找苏轼的 person_id,注意要使用繁体中文
person_id = getPersonId('蘇軾')
person_id
"""
'3767'
"""

在这里插入图片描述

在获得目标人物(苏轼)的 person_id 后,需要通过该 id 在数据库中查找相关记录,得到苏轼与其亲友、及其亲友与其他人的书信往来关系:

sql = '''
SELECT a.c_personid person_id
    , b1.c_name_chn person_a
    , c_assoc_id assoc_id
    , b2.c_name_chn person_b
    , a.c_assoc_code assoc_code
    , c.c_assoc_desc_chn assoc_desc
FROM assoc_data a
LEFT JOIN biog_main b1 
    ON a.c_personid = b1.c_personid
LEFT JOIN biog_main b2 
    ON a.c_assoc_id = b2.c_personid
LEFT JOIN assoc_codes c 
    ON a.c_assoc_code = c.c_assoc_code
WHERE (a.c_personid = {0}
    OR a.c_personid IN (
        SELECT c_personid 
        FROM assoc_data 
        WHERE c_assoc_id = {0}
        AND c_assoc_code IN ('429', '430', '431', '432', '433', '434', '435', '436'))
    OR a.c_assoc_id IN (
        SELECT c_assoc_id
        FROM assoc_data 
        WHERE c_personid = {0}
        AND c_assoc_code IN ('429', '430', '431', '432', '433', '434', '435', '436'))) 
    AND a.c_assoc_code IN ('429', '430', '431', '432', '433', '434', '435', '436')
'''.format(person_id)

person_assoc = pd.read_sql(sql, con=sqlite3.connect(db))

在对数据库执行了查询操作后,我们将得到一个 DataFrame,其中包括了:

  • person_id:关系人A id
  • person_a: 关系人A姓名
  • assoc_id:关系人B id
  • person_b:关系人B姓名
  • assoc_code:关系代码
  • assoc_desc:关系名称

DataFrame 详细信息为:
在这里插入图片描述

关系人A或关系人B为苏轼的记录数:

person_assoc[(person_assoc['person_id'] == int(person_id)) | (person_assoc['assoc_id'] == int(person_id))].count()
"""
person_id     550
person_a      550
assoc_id      550
person_b      550
assoc_code    550
assoc_desc    550
dtype: int64
"""

DataFrame 中包含了 8 种关系(均为书信往来关系):

# 打印所有关系的名称
for i in person_assoc['assoc_desc'].unique():
    print(i)

"""
致書Y
被致書由Y
答Y書
收到Y的答書
致Y啓
收到Y的啓
答Y啓
收到Y的答啓
"""

据此信息,我们可以将dataframe转网络结构数据,上一节中使用的是nx.read_edgelist,而这里,使用nx.from_pandas_edgelist,具体为:

# 生成图
person_G = nx.from_pandas_edgelist(person_assoc, source='person_a', target='person_b', edge_attr='assoc_desc')

# 打印图信息
print(nx.info(person_G))
print('Density: {0}'.format(nx.density(person_G)))
"""
Graph with 614 nodes and 906 edges
Density: 0.004814257855051517
"""

# 补充,求总的平均度
avg_degree = sum(dict(person_G.degree()).values()) / person_G.number_of_nodes()
"""
Number of nodes: 614
Number of edges: 906
Average degree:   2.9511
"""

# networkx的api求单边平均度
nx.average_degree_connectivity(person_G)
"""
{42: 11.619047619047619,
 1: 111.63448275862069,
 8: 43.854166666666664,
 109: 5.321100917431193,
 211: 4.938388625592417,
 79: 8.012658227848101,
 4: 60.1875,
 15: 16.866666666666667,
 2: 91.11111111111111,
 141: 6.368794326241135,
 7: 41.22857142857143,
 18: 29.083333333333332,
 3: 70.26881720430107,
 41: 15.292682926829269,
 6: 40.129629629629626,
 16: 27.34375,
 13: 19.0,
 19: 28.63157894736842,
 9: 45.22222222222222,
 37: 13.91891891891892,
 5: 48.8,
 14: 33.0,
 11: 32.5,
 10: 44.95}
"""

在这里插入图片描述

这里因为参考中打印结果与代码不一致,其中节点的度、边以及总平均度没有,所以我根据输出结果反推了一下代码,顺带找到了networkx中的节点平均度,打印了一下输出。图中描述了 906 个关系,其中包含 614 个唯一个体。苏轼的社交网络中的随机个体在社交网络的其余部分平均有近 3 个联系人。由于存在大量与苏轼亲友有书信往来的但与苏轼本人无关系的记录,整个社会网络的密度较低。

基于以上数据分析,对于数据的构成我们已经有一个大致的概括,所以接下来就能直接挖掘特征,这里输出本篇一直在介绍的中心性指标:

person_betweenness = pd.Series(nx.betweenness_centrality(person_G), name='Betweenness')
person_person = pd.Series.to_frame(person_betweenness)
person_person['Closeness'] = pd.Series(nx.closeness_centrality(person_G))
person_person['PageRank'] = pd.Series(nx.pagerank_scipy(person_G))
person_person['eigenvector'] = pd.Series(nx.eigenvector_centrality(person_G))
person_person['Degree'] = pd.Series(dict(nx.degree(person_G)))
desc_betweenness = person_person.sort_values('Betweenness', ascending=False)
desc_betweenness.head(10)

相比于参考的那篇,这里多加了一个eigenvector,即特征向量中心性,其实没有多大必要,因为PageRank可以看成是该中心性的一种特殊形式,不过为了更为直观,我顺带就一起输出了:

BetweennessClosenessPageRankeigenvectorDegree
蘇軾0.5912040.6039410.1110230.548464211
歐陽修0.3178910.5335070.0702280.332594141
黃庭堅0.2577890.4755620.0635310.181748109
王安石0.1460490.4571220.0387740.18943879
畢仲游0.0866610.4344440.0221200.10656942
司馬光0.0783870.4564410.0206600.13429741
韓琦0.0542050.4301750.0169370.11545037
張耒0.0262460.4187160.0087720.08212918
米芾0.0235580.3855350.0079680.04753215
張方平0.0220550.4523990.0079340.10794018

最后,对该数据进行可视化,在绘制可视化图形前,需要提前创建一致的图形布局,这里选用了 kamada_kawai_layout 的图形布局:

#pos = nx.circular_layout(person_G)
pos = nx.kamada_kawai_layout(person_G)
#pos = nx.shell_layout(person_G)
#pos = nx.spring_layout(person_G)
#pos = nx.random_layout(person_G)

绘制图形的函数:

# 绘制函数
def draw_graph(df, top):
    ''' Draw Graph
    @param df: DataFrame
    @param top: int, numbers of top
    '''    
    nodes = df.index.values.tolist() #生成节点列表
    edges = nx.to_edgelist(person_G) #生成边列表
    # 生成无向度量图
    metric_G = nx.Graph()
    metric_G.add_nodes_from(nodes)
    metric_G.add_edges_from(edges)
    # 生成 Top n 的标签列表
    top_labels = {}
    for node in nodes[:top]:
        top_labels[node] = node
    # 生成节点尺寸列表
    node_sizes = []
    for node in nodes:
            node_sizes.append(df.loc[node]['Degree'] * 16 ** 2)
    # 设置图形尺寸
    plt.figure(1, figsize=(64, 64))
    # 绘制图形
    nx.draw(metric_G, pos=pos, node_color='#cf1322, with_labels=False)
    nx.draw_networkx_nodes(metric_G, pos=pos, nodelist=nodes[:top], node_color='#a8071a', node_size=node_sizes[:top])
    nx.draw_networkx_nodes(metric_G, pos=pos, nodelist=nodes[top:], node_color='#a3b1bf', node_size=node_sizes[top:])
    nx.draw_networkx_edges(metric_G, pos=pos, edgelist=edges, edge_color='#d9d9d9', arrows=False)
    nx.draw_networkx_labels(metric_G, pos=pos, font_size=20, font_color='#555555')
    nx.draw_networkx_labels(metric_G, pos=pos, labels=top_labels, font_size=28, font_color='#1890ff')
    # 保存图片
    plt.savefig('tmp.png')

draw_graph(desc_betweenness, 20)

上述代码为生成网络图,图中的每个节点都对应苏轼朋友圈中的一个人,而在朋友圈中与苏轼最亲近的 20 个人的节点以红底蓝字突出显示,节点大小对应程度大小:
在这里插入图片描述

参考与推荐

[1]. https://snap-stanford.github.io/cs224w-notes/preliminaries/measuring-networks-random-graphs

[2]. https://github.com/TommyZihao/zihao_course/blob/main/CS224W/2-tradition-ml.md

[3]. ucinet网络分析使用总结

[4]. 知乎社交网络分析(上):基本统计

[5]. https://en.wikipedia.org/wiki/Eigenvector_centrality

[6]. CS224W 学习笔记

[7]. Few but good
The eigenvector centrality and its meaning

[8]. 苏轼的朋友圈——基于 networkx 进行社交网络分析(SNA)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/351054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刚性电路板的特点及与柔性电路板的区别

打开市场上的任何一个电子产品&#xff0c;会发现里面都有一块或多块电路板。电路板是电子产品运行的核心&#xff0c;之前沐渥小编已经给大家介绍了柔性电路板&#xff0c;下面给大家介绍刚性电路板的基础知识。 刚性电路板俗称硬板&#xff0c;是由不容易变形的刚性基材制成的…

MASA Stack 1.0 发布会 —— 社区问题解答

MASA Stack 1.0 圆桌讨论 Q1&#xff1a; 全职开源的团队&#xff0c;你们的收入是什么&#xff1f; 1.首先感谢我们的金主朗诗德公司&#xff0c;朗诗德是一家大型的净水器研发、生产、销售的公司&#xff0c;我们的产品也在朗诗德公司进行了大量的落地验证&#xff0c;再次…

Kotlin新手教程二(Kotlin基本数据类型及基础语法)

一、基本数据类型 1.数字 由于Kotlin支持类型推断&#xff0c;所以在使用时若超出Int的范围则会被认定为其它类型&#xff1b;若需要显式指定Long型值&#xff0c;则需要在值后添加L后缀。 2.浮点数 3.比较两个数&#xff08; 和 &#xff09; Kotlin 中没有基础数据类型&a…

C语言(输出scanf()函数)

一.概念带入 scanf()把输入的字符串转换成整数&#xff0c;浮点数&#xff0c;字符或字符串。而printf()正好与其相反&#xff0c;把整数&#xff0c;浮点数&#xff0c;字符和字符串转换成显示在屏幕上的文本。所以scanf&#xff08;&#xff09;在使用上面会和printf有很多一…

实验十四、共源放大电路的频率响应

一、题目 利用 Multisim 从下列两个方面研究图1所示电路的频率响应。图1共源放大电路图1\,\,共源放大电路图1共源放大电路&#xff08;1&#xff09;为改善低频特性&#xff0c;应增大三个耦合电容中的哪一个最有效。 &#xff08;2&#xff09;场效应管的漏极静态电流对上限频…

审批流、工作流、业务流

是业务流、工作流、审批流 业务流&#xff1a;即业务流程&#xff0c;指为了完成某项业务而进行的各种工作的有序组合 工作流&#xff1a;即工作流程&#xff0c;指为了完成某项工作而进行的各种动作的有序组合 审批流&#xff1a;即审批流程&#xff0c;是对某项工作的审批活动…

记录一次服务器被攻击的经历

突然收到阿里云发过来的异常登陆的信息&#xff1a; 于是&#xff0c;急忙打开电脑查看对应的ECS服务器的记录&#xff1a; 发现服务器的cpu占用率异常飙升&#xff0c;所以可以大概断定服务器已经被非法入侵了。 通过自己的账号登陆后&#xff0c;发现sshd服务有异常的链接存…

TensorRT的命令行程序

TensorRT的命令行程序 文章目录TensorRT的命令行程序A.3.1. trtexecA.3.1.1. Benchmarking NetworkA.3.1.2. Serialized Engine GenerationA.3.1.3. trtexecA.3.1.4. 常用的命令行标志点击此处加入NVIDIA开发者计划 A.3.1. trtexec 示例目录中包含一个名为trtexec的命令行包装…

关于表的操作+1 数据库(4)

素材&#xff1a; 学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;SC (…

常见的5大软件项目风险,如何进行规避?

1、客户没有或很少参与项目 日常项目开发中&#xff0c;容易出现这样的风险&#xff1a;客户在最开始的时候提交了一份文档&#xff0c;在项目启动、计划和执行阶段&#xff0c;客户没有参与&#xff0c;只是在项目收尾时进行验收&#xff0c;客户一旦发现开发结果与预期需求相…

第42天|LeetCode121. 买卖股票的最佳时机、LeetCode122. 买卖股票的最佳时机 II

1.题目链接&#xff1a;121. 买卖股票的最佳时机 题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法…

C++类基础(十六)

类的继承——继承与特殊成员函数 ● 派生类合成的…… – 缺省构造函数会隐式调用基类的缺省构造函数 – 拷贝构造函数将隐式调用基类的拷贝构造函数 – 赋值函数将隐式调用基类的赋值函数 struct Base {Base(){std::cout << "Base()\n";}Base(const Base&…

重生之我是赏金猎人-SRC漏洞挖掘(五)-轻松GET某src soap注入

0x01 挖掘 在对某SRC测试时&#xff0c;本人根据其证书信息收集到了部分深度子域&#xff0c;并找到了其对应的业务IP段 写了个shell脚本ffuf批量fuzz某src c段资产目录 发现了xxSRC c段的一个提供了webservice的服务器 http://180.x.x.x/webservice/ 获取到接口 http://1…

全国计算机等级考试报名照片要求以及证件照制作教程

马上就全国计算机等级考试就要开始了&#xff0c;相信现在很多同学都在网上进行报名呢&#xff0c;报名的时候肯定需要用到个人证件照片&#xff0c;所以问题来了&#xff0c;我们怎么自己制作证件照片呢&#xff1f;计算机等级考试报名时对证件照都有哪些要求呢&#xff1f;该…

06 antdesign react Anchor 不同页面之间实现锚点

react Anchor 不同页面之间实现锚点一、定义二、使用步骤三、开发流程(一)、组件(二)、页面布局(三)、点击事件(四)、总结说明一、react单页面应用&#xff0c;当前页面的锚点二、react单页面应用&#xff0c;不同页面的锚点思路&#xff1a;锚点只能在当前页面使用&#xff0c…

central cache设计及实现

你好&#xff0c;我是安然无虞。 central cache 设计及实现 central cache 也是一个哈希桶结构, 而且它的哈希桶的映射关系跟 thread cache 是一样的, 不同的是 central cache 每个哈希桶位置上挂的是 SpanList 双向链表结构, 而且每个哈希桶下面的 span 中的大块内存被按映射…

大数据之数据中台

目录数据仓库传统数据仓库无法支撑互联网时代的商业智能数据埋点数据仓库 数据仓库是在企业管理和决策中面向主题的、集成的、与时间相关的、不可修改的数据集合。 在电商场景中&#xff0c;有一个数据库专门存放订单的数据&#xff0c;另外一个数据库存放会员相关的数据。构建…

订单服务:订单流程

订单流程 订单流程是指从订单产生到完成整个流转的过程&#xff0c;从而行程了一套标准流程规则。而不同的产品类型或业务类型在系统中的流程会千差万别&#xff0c;比如上面提到的线上实物订单和虚拟订单的流程&#xff0c;线上实物订单与 O2O 订单等&#xff0c;所以需要根据…

[Datawhale][CS224W]图机器学习(三)

目录一、简介与准备二、教程2.1 下载安装2.2 创建图2.2.1 常用图创建&#xff08;自定义图创建&#xff09;1.创建图对象2.添加图节点3.创建连接2.2.2 经典图结构1.全连接无向图2.全连接有向图3.环状图4.梯状图5.线性串珠图6.星状图7.轮辐图8.二项树2.2.3 栅格图1.二维矩形栅格…

如何修改 类名::静态变量?

好久没更新了&#xff0c;其中经历了备战省赛&#xff0c;重装电脑&#xff0c;换服务器&#xff0c;重新搭建博客等一系列事&#xff0c;受到许多技术大牛的指点&#xff0c;而且新人太厉害了&#xff0c;卷卷卷&#xff01; Geek Challenge 2021有一道BabyPOP&#xff0c;这…