全对SimRank相似度计算的并行方法
在处理大规模图数据时,全对SimRank相似度计算是一个具有挑战性的问题。由于大规模图数据节点众多,其邻接矩阵元素规模可达万亿级别,现有的计算方法难以有效处理。为了解决这一问题,本文提出了一种基于分治思想的算法,利用图中的密集块信息,有效降低了计算复杂度。
1. 基础概念与问题提出
在图论中,使用 $G = (V, E)$ 表示有向图,其中 $V$ 是顶点集,$E \subseteq V \times V$ 是边集。两个顶点 $u$ 和 $v$ 之间的相似度定义如下:
[
s(u, v) =
\begin{cases}
1, & u = v \
\frac{c}{\vert I(u) \vert \vert I(v) \vert} \sum_{u’ \in I(u), v’ \in I(v)} s(u’, v’), & u \neq v
\end{cases}
]
这里 $c$ 是衰减系数,用于增加邻域结构对最终相似度的权重,$I(u) = {v : (v, u) \in E}$ 表示连接到 $u$ 的顶点集。基于此定义,提出了基于矩阵乘法的迭代算法。设 $S_k$ 是第 $k$ 次迭代的相似度矩阵,$S_0$ 是初始矩阵,当 $u = v$ 时,$S_{0_{uv}} = 1$,否则 $S_{0_{uv}} = 0$,可通过以下公式得到 $S_{k + 1}$:
[
S_{k + 1_{uv}} =
\begin{cases}
1, & u = v \
\frac{c}{\vert I(u) \vert \vert I(v) \vert} \sum_{u’ \in I(u), v’ \in I(v)} S_{k + 1_{u’v’}}, & u \neq v
\end{cases}
]
该计算的时间复杂度为 $O(n^2)$,空间复杂度为 $O(kn^2d^2)$。为降低全对SimRank相似度计算的复杂度,提出了基于图划分的算法。对于超大规模图,图划分面临两个主要挑战:
- 算法需要有出色的可扩展性,能够充分利用划分过程的计算并行性,并通过堆叠计算节点获得更大的处理能力。
- 划分结果需要更好地保留原始图的语义,因为现实生活中的图不是随机生成的,其拓扑结构往往蕴含着语义层面的信息。
2. 图划分与相似度计算
2.1 基于模块化的图划分
采用的分布式图划分算法受多级划分思想的启发,主要有三个步骤:
1.
图规模缩减
:通过收缩操作逐步减小原始图的规模。每次收缩时,先对图进行简单划分,然后将划分结果的每个分区视为一个新顶点,分区之间的边作为新边,形成规模更小的图。
2.
小图划分
:经过多次收缩迭代,当图的规模小到可接受的阈值时,使用传统的高质量单节点算法(如KL或FM)直接对小图进行划分,得到初步结果。
3.
结果投影
:将这些划分结果投影回原始图,得到最终划分。
收缩过程借鉴了社区检测的思想。社区是网络中的密集群组,社区内顶点之间的连接相对紧密,而社区之间的连接相对稀疏。与社区检测不同的是,图划分通常会设定划分的块数。通过模块化最大化的思想,更好地保留了原始图中的密集子结构和语义信息。
2.2 块相似度计算
假设图中的每个块是一个顶点,图的划分形成一个收缩图。首先定义收缩图中边的权重:
- 对于图 $G$ 的划分 $P = (C_1, C_2, \ldots, C_n)$,设 $L(C_i)$ 表示分区 $C_i$ 中的所有边数,$L(C_i, C_j)$ 表示连接块 $C_i$ 和块 $C_j$ 的边数。对于收缩图 $G’$ 中的顶点 $v_i$ 和 $v_j$,边 $(v_i, v_j)$ 的权重定义为:
[
w(v_i, v_j) = \frac{L(C_i, C_j)}{L(C_i)}
]
- 顶点 $v_i$ 到自身的权重为:
[
w(v_i, v_i) = 1 - \sum_{v_j \in O(v_i)} w(v_i, v_j)
]
收缩图 $G’$ 是一个加权有向图,边 $(v_i, v_j)$ 的权重可大致理解为随机游走者从点 $v_i$ “逃逸” 到点 $v_j$ 的概率。基于这些定义,将原始图 $G$ 划分中块 $C_i$ 和 $C_j$ 之间的相似度定义为收缩图 $G’$ 中顶点 $v_i$ 和 $v_j$ 之间的相似度。为了将边权重引入SimRank模型,提出了SimRank++算法,其计算相似度的公式如下:
[
s_{k + 1}(u, v) = c \cdot evidence(u, v) \sum_{u’ \in I(u), v’ \in I(v)} s_k(u’, v’)W(u’, u)W(v’, v)
]
其中:
[
evidence(u, v) = \sum_{i = 1}^{\vert I(u) \cap I(v) \vert} 2^{-i}
]
[
W(u’, u) = w(u’, u) \cdot \exp(-Var({w(u’, u) \vert u \in O(u’)}))
]
如果写成矩阵形式,设 $V$ 是证据矩阵,满足 $V(i, j) = evidence(i, j)$,则整个加权有向图的SimRank相似度计算过程如算法1所示:
Algorithm 1. Weighted All-pair SimRank:wapSimRank
1: procedure WeightedSimRank(G′, u, c, k)
2: N ←|V |;
3: S ←identity matrix IN;
4: for i = 1 to k do
5: T ←c · W T · S · W;
6: S ←T + IN −D(diag(T));
▷D is the diagonal matrix.
7: end for
8: S ←element-wise multiplication of V and S;
9: return S.
10: end procedure
2.3 全局顶点对相似度估计
对于不同块中的顶点对 $(u, v)$,其相似度计算公式为:
[
s(u, v) = s(C_i, u) \cdot s_{block}(C_i, C_j) \cdot s(C_j, v)
]
其中 $s(C_i, u)$ 可视为顶点 $u$ 与其所在块中心点的相似度,近似表示为:
[
s(C_i, u) = \frac{1}{\vert C_i \vert} \sum_{q \in C_i} s(u, q)
]
算法的主要步骤如下:
1. 按照之前的方法对原始图 $G$ 进行划分,得到多个块 $P = (C_1, C_2, \ldots, C_n)$。
2. 将每个块收缩为一个顶点,得到加权有向图 $G’$,在 $G’$ 上运行SimRank++算法,得到块之间的相似度。
3. 直接在每个块 $C_i$ 上运行串行全对SimRank算法,得到块内顶点对的相似度。
4. 使用上述公式计算不同块中顶点的相似度。
5. 最终返回全局相似度。
3. 实验环境与数据集
- 实验环境 :集群由六个计算节点组成,每个节点处理器为12核Intel Xeon E - 2650,频率为2.1 GHz,内存64 GB,硬盘1 TB。节点通过千兆以太网连接,操作系统为Ubuntu 16.04,Spark运行版本为1.6.2,底层分布式文件系统HDFS版本为2.6.0。所有节点配置为从节点,其中一个额外配置为主节点。在Spark中运行时,为每个执行器分配10 GB内存。
-
数据集
:使用了四个真实数据集,分别是eu - 2005、ljournal - 2008、arabic - 2005和wiki - topcats。具体信息如下表所示:
| 数据集 | 顶点数 | 边数 | 平均顶点度 | 大小 |
| ---- | ---- | ---- | ---- | ---- |
| eu - 2005 | 862,664 | 19,235,140 | 22.29 | 256.4 MB |
| ljournal - 2008 | 5,363,260 | 79,023,142 | 14.73 | 1.2 GB |
| arabic - 2005 | 22,744,080 | 639,999,458 | 28.14 | 10.9 GB |
wiki - topcats是一个有向图,记录了维基百科中各种网页超链接之间的引用关系,选取了四个最大的类别得到该图,其详细信息如下:
| 类别 | 顶点数 |
| ---- | ---- |
| C1 | 34,722 |
| C2 | 22,700 |
| C3 | 15,303 |
| C4 | 11,662 |
边数信息如下表:
| | C1 | C2 | C3 | C4 |
| ---- | ---- | ---- | ---- | ---- |
| C1 | 9,653 | 14,321 | 15,678 | 18,323 |
| C2 | 9,804 | 82,767 | 32,130 | 135,480 |
| C3 | 13,098 | 21,104 | 51,092 | 11,523 |
| C4 | 15,431 | 28,873 | 9,522 | 73,564 |
每个图数据最初是普通文本格式,每行代表图的一条边。在开始实验前,所有数据集都预先加载到分布式文件系统HDFS上。
4. 实验结果分析
4.1 有效性
严格来说,提出的相似度计算方法是一种计算近似SimRank相似度的算法。对于同一块内的顶点对,结果与严格的SimRank相似度差异不大;对于不同块中的顶点对,数值上存在差异,但在wiki - topcats上的实验结果表明,数值差异不超过 ±5%。为了测试算法在实际应用中的语义有效性,使用基于顶点相似度的经典k - 中心点图聚类算法PAM对wiki - topcats进行聚类作为标准结果。分别运行SimRank算法和本文算法,以正确分类的顶点数与总顶点数的比值作为准确率。结果显示,SimRank的准确率为0.6218,本文算法的准确率为0.6221,准确率大致相同或略高。这可能是因为图划分预处理过程在一定程度上提取了原始图中的密集子图,消除了噪声。
4.2 计算效率
将本文的partitionSimRank算法与基于稀疏矩阵计算的matrixSimRank方法和基于数据传输优化的DeltaSimRank算法进行计算效率比较。三种算法均基于Spark编写为分布式程序,运行环境和相关参数设置完全相同。partitionSimRank预处理过程中设置的划分块数为300,图的划分时间计入算法的总时间成本。三种算法的运行时间如下表所示:
| 算法 | eu - 2005 | ljournal - 2008 | arabic - 2005 |
| ---- | ---- | ---- | ---- |
| matrixSimRank | 1278.20 | 6523.14 | - |
| DeltaSimRank | 51.95 | 402.03 | 2045.50 |
| partitionSimRank | 16.38 | 32.38 | 126.32 |
可以看出,DeltaSimRank相比matrixSimRank在计算效率上有数十倍的提升,因为DeltaSimRank大大减少了迭代过程中产生的中间数据量。而partitionSimRank相比DeltaSimRank在计算效率上也有几倍甚至十倍的提升,这是因为算法中最耗时的块内相似度计算的运行时间与之前的全局全对计算相比减少了 $(n/m)^2$ 倍。
4.3 可扩展性
实验还研究了算法的可扩展性:
-
数据可扩展性
:当集群计算节点数量固定时,算法的运行时间随输入图的大小而变化。在块数 $\alpha = 300$,SimRank计算迭代次数 $k = 6$ 且其他参数固定的情况下,输入图大小从256 MB增加到10.9 GB,运行时间大致与输入大小呈线性变化,表明多级划分模型具有良好的数据可扩展性。
-
节点可扩展性
:当输入图规模固定时,研究算法效率随集群中计算节点数量的变化。以最大的图arabic - 2005为输入,所有参数固定,计算节点数量从2增加到6。实验结果表明,对于不同大小的输入图,算法的运行时间几乎随集群计算节点的增加而线性减少,表明算法在分布式环境中具有良好的节点可扩展性。
综上所述,提出的基于分治思想的算法在大规模图数据的全对SimRank相似度计算中,在有效性和计算效率方面都表现出色,并且具有良好的可扩展性。
全对SimRank相似度计算的并行方法
5. 总结与展望
在大规模图数据处理中,全对SimRank相似度计算是一个极具挑战性的问题。由于大规模图数据节点众多,其邻接矩阵元素规模庞大,传统计算方法难以有效应对。本文提出的基于分治思想的算法,通过图划分技术,将大规模图数据分解为多个子图进行处理,有效降低了计算复杂度。
从实验结果来看,该算法在有效性和计算效率方面都表现出色。在有效性方面,对于同一块内的顶点对,计算结果与严格的SimRank相似度差异不大;对于不同块中的顶点对,数值差异也在可接受范围内(不超过 ±5%)。通过实际应用中的聚类实验,算法的准确率与传统SimRank算法大致相同或略高,这得益于图划分预处理过程对原始图中密集子图的提取和噪声的消除。
在计算效率方面,与基于稀疏矩阵计算的matrixSimRank方法和基于数据传输优化的DeltaSimRank算法相比,partitionSimRank算法具有显著的优势。DeltaSimRank算法通过增量计算减少了迭代过程中的中间数据量,相比matrixSimRank有数十倍的计算效率提升;而partitionSimRank算法进一步优化,通过减少块内相似度计算的时间,相比DeltaSimRank有几倍甚至十倍的计算效率提升。
此外,算法还具有良好的可扩展性。无论是数据可扩展性还是节点可扩展性,都表现出了线性的变化趋势。在数据可扩展性方面,随着输入图大小的增加,运行时间大致与输入大小呈线性变化;在节点可扩展性方面,随着集群计算节点数量的增加,运行时间几乎呈线性减少。
未来,我们可以进一步优化算法,提高其在更大规模图数据上的性能。例如,可以探索更高效的图划分算法,以更好地保留原始图的语义信息,同时减少划分时间。还可以研究如何进一步优化块内相似度计算和块间相似度计算的方法,提高计算效率。另外,将算法应用于更多的实际场景,如社交网络分析、知识图谱构建等,验证其在不同领域的有效性和实用性。
6. 算法流程总结
为了更清晰地展示算法的执行过程,以下是算法的主要步骤总结:
1.
图划分
:
- 通过收缩操作逐步减小原始图的规模,每次收缩先进行简单划分,将划分结果的每个分区视为新顶点,形成更小的图。
- 当图的规模小到可接受的阈值时,使用传统的高质量单节点算法(如KL或FM)对小图进行划分,得到初步结果。
- 将划分结果投影回原始图,得到最终划分,得到多个块 $P = (C_1, C_2, \ldots, C_n)$。
2.
块相似度计算
:
- 定义收缩图中边的权重,将每个块收缩为一个顶点,得到加权有向图 $G’$。
- 在 $G’$ 上运行SimRank++算法,计算块之间的相似度。
3.
块内相似度计算
:直接在每个块 $C_i$ 上运行串行全对SimRank算法,得到块内顶点对的相似度。
4.
全局顶点对相似度估计
:对于不同块中的顶点对 $(u, v)$,使用公式 $s(u, v) = s(C_i, u) \cdot s_{block}(C_i, C_j) \cdot s(C_j, v)$ 计算其相似度,其中 $s(C_i, u)$ 近似表示为 $s(C_i, u) = \frac{1}{\vert C_i \vert} \sum_{q \in C_i} s(u, q)$。
5.
返回结果
:最终返回全局相似度。
下面是算法流程的mermaid流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(图划分):::process
B --> C(块相似度计算):::process
C --> D(块内相似度计算):::process
D --> E(全局顶点对相似度估计):::process
E --> F([返回全局相似度]):::startend
7. 关键技术点分析
- 图划分技术 :图划分是算法的核心步骤之一,其目的是将大规模图数据分解为多个子图,以便并行处理。本文采用的分布式图划分算法受多级划分思想的启发,结合了社区检测的思想,通过模块化最大化的方法,更好地保留了原始图中的密集子结构和语义信息。在实际操作中,首先通过收缩操作逐步减小图的规模,然后使用传统的高质量单节点算法对小图进行划分,最后将划分结果投影回原始图。
- SimRank++算法 :为了将边权重引入SimRank模型,本文采用了SimRank++算法。该算法通过定义边的权重和证据矩阵,将边的信息纳入到相似度计算中,提高了相似度计算的准确性。在实际计算中,通过矩阵运算实现了SimRank相似度的迭代计算。
- 分治思想 :算法基于分治思想,将大规模图数据的全对SimRank相似度计算问题分解为块内相似度计算和块间相似度计算两个子问题。通过分别计算块内和块间的相似度,最后合并得到全局相似度,有效降低了计算复杂度。
8. 实际应用建议
如果您想在实际项目中应用该算法,可以按照以下步骤进行操作:
1.
数据准备
:将图数据转换为普通文本格式,每行代表图的一条边。将数据预先加载到分布式文件系统HDFS上,确保数据可以被集群中的计算节点访问。
2.
环境配置
:搭建Spark集群环境,确保节点之间可以通过千兆以太网连接。配置节点的处理器、内存和硬盘等硬件资源,为每个执行器分配足够的内存(如本文中的10 GB)。
3.
算法实现
:根据本文提供的算法步骤和代码,实现partitionSimRank算法。可以参考以下伪代码:
// 图划分
P = partitionGraph(G)
// 块收缩为顶点,得到加权有向图
G' = collapseBlocks(P)
// 计算块之间的相似度
blockSimilarities = SimRank++(G')
// 计算块内顶点对的相似度
intraBlockSimilarities = {}
for each block Ci in P:
intraBlockSimilarities[Ci] = serialSimRank(Ci)
// 计算全局顶点对相似度
globalSimilarities = {}
for each vertex pair (u, v) in G:
if u and v in the same block:
globalSimilarities[(u, v)] = intraBlockSimilarities[block(u)][(u, v)]
else:
Ci = block(u)
Cj = block(v)
sCi_u = averageSimilarity(u, Ci)
sCj_v = averageSimilarity(v, Cj)
sblock_Ci_Cj = blockSimilarities[(Ci, Cj)]
globalSimilarities[(u, v)] = sCi_u * sblock_Ci_Cj * sCj_v
return globalSimilarities
- 参数调整 :根据实际情况调整算法的参数,如划分块数、SimRank计算的迭代次数等。可以通过实验来确定最优的参数设置,以提高算法的性能。
- 结果评估 :使用实际数据对算法进行测试,评估算法的有效性和计算效率。可以使用聚类算法等方法验证算法在语义层面的有效性,比较不同算法的运行时间来评估计算效率。
通过以上步骤,您可以在实际项目中应用该算法,解决大规模图数据的全对SimRank相似度计算问题。
超级会员免费看

被折叠的 条评论
为什么被折叠?



