✓ 文件回写 ✓ 属性回写 ✓ 直接返回 ✓ 流式返回 ✕ 统计值
概述
特征向量中心性(Eigenvector Centrality)度量网络中节点的影响力或重要性。在图中,节点是互相影响的;具体地,一个节点通过入边接收来自邻居节点的影响力。因此,节点的特征向量中心性分值不仅取决于有多少条入边,还取决于入边邻居有多重要。来自高分值节点的连接比来自低分值节点的连接对节点分值的贡献更大。在疾病传播场景中,特征向量中心性分值高的节点距离传染源近的可能性更大,需要格外防范。
著名的 PageRank 是特征向量中心性的一个变种。
特征向量中心性的取值范围是 0 到 1,节点的分值越大,影响力越大。
基本概念
特征向量中心性
节点的分值可通过递归的方式计算。以下图为例,邻接矩阵 A 反映每个节点的入边。将所有节点的分值初始化为 1,并用向量 s(0) 表示。
在每轮影响力传递中,更新每个节点的分值为其入边邻居的分值和。经过一轮,s(1) = As(0) 以及经过 L2 范数归一化处理后的结果如下所示:
经过 k 轮迭代后,s(k) = As(k-1) = Aks(0)。随着 k 的增长,s(k) 逐渐达到稳态。在本例中,s(k) 在大约 20 轮后不再改变。
事实上,向量 s(k) 朝着矩阵 A 对应于绝对值最大的特征值的特征向量的方向收敛。因此,s(k) 各元素的值称为各点的特征向量中心性分值。
特征值和特征向量
给定 n x n 维矩阵 A、常数 λ 以及 n 维非 0 向量 x,如果满足 Ax = λx,那么称 λ 为 A 的特征值(Eigenvalue), x 为 A 对应于特征值 λ 的特征向量(Eigenvector)。
上面的矩阵 A 有 4 个特征值 λ1、λ2、λ3 和 λ4,分别对应特征向量 x1、x2、x3 和 x4。其中,x1 是对应于主特征值 λ1 的特征向量,λ1 是主特征值因为其绝对值最大。
根据 Perron-Forbenius 定理,如果矩阵 A 有特征值 |λ1| > |λ2| ≥ |λ3| ≥ ... ≥ |λn|,当 k → ∞,s(k) = Aks(0) 的方向朝着 x1 的方向收敛,s(0) 可以是任意非 0 向量。
幂迭代
为了保证精度的同时也提高计算效率,本算法采用幂迭代法计算矩阵 A 的主特征向量(x1):
- s(1) = As(0)
- s(2) = As(1) = A2s(0)
- ...
- s(k) = As(k-1) = Aks(0)
算法在所有节点的变化值小于规定的收敛偏差(tolerance)时停止,若迭代轮数达到限制,算法也会结束。
特殊说明
- 本算法使用邻接矩阵加上单位矩阵后的矩阵(即 A = A + I)来进行计算以保证收敛。
- 没有入边的节点的特征向量中心性分值趋近于 0。
- 自环边算作一条入边,其权重值只计算一次(权重图)。
语法
- 命令:
algo(eigenvector_centrality)
- 参数:
名称 |
类型 |
规范 |
默认 |
可选 |
描述 |
---|---|---|---|---|---|
max_loop_num | int | ≥1 | 20 |
是 | 最大迭代轮数;运行至规定的最大轮数后,即使没达到收敛要求,算法也会停止 |
tolerance | float | (0,1) | 0.001 |
是 | 收敛偏差;某轮迭代后,如果所有点的分值变化值小于收敛偏差,算法结束 |
edge_schema_property | @<schema>?.<property> |
数值类型,需 LTE | / | 是 | 用作边权重的属性,权重值为所有指定属性值的和 |
limit | int | ≥-1 | -1 |
是 | 返回的结果条数,-1 返回所有结果 |
order | string | asc , desc |
/ | 是 | 按中心性分值大小对结果进行排序 |
示例
示例是一个网页引用关系图,边属性 @link.value 的值可用作权重:
文件回写
配置项 | 回写内容 |
---|---|
filename | _id ,rank |
algo(eigenvector_centrality).params({
max_loop_num: 15,
tolerance: 0.01
}).write({
file: {
filename: 'rank'
}
})
结果:文件 rank
web7,4.63007e-06
web6,0.0198426
web5,0.255212
web3,0.459901
web4,0.255214
web2,0.573512
web1,0.573511
属性回写
配置项 | 回写内容 | 回写至 | 数据类型 |
---|---|---|---|
property | rank |
点属性 | float |
algo(eigenvector_centrality).params({
edge_weight_property: 'value'
}).write({
db: {
property: 'ec'
}
})
结果:每个节点的中心性分值回写至名为 ec 的点属性下
直接返回
别名序号 | 类型 | 描述 | 列名 |
---|---|---|---|
0 | []perNode | 点及其中心性 | _uuid , rank |
algo(eigenvector_centrality).params({
max_loop_num: 20,
tolerance: 0.01,
edge_weight_property: '@link.value',
order: 'desc'
}) as ec
return ec
结果:ec
_uuid | rank |
---|---|
1 | 0.73133802 |
6 | 0.48346400 |
2 | 0.43551901 |
3 | 0.17412201 |
4 | 0.098612003 |
5 | 0.041088000 |
7 | 0.0000000 |
流式返回
别名序号 | 类型 | 描述 | 列名 |
---|---|---|---|
0 | []perNode | 点及其中心性 | _uuid , rank |
示例:计算所有点的特征向量中心性,统计分值大于 0.4 和小于等于 0.4 的节点数量
algo(eigenvector_centrality).params({
edge_weight_property: '@link.value'
}).stream() as ec
with case
when ec.rank > 0.4 then 'attention'
when ec.rank <= 0.4 then 'normal'
END as r
group by r
return table(r, count(r))
结果:table(r, count(r))
r | count(r) |
---|---|
attention | 3 |
normal | 4 |