30. 图游走算法 DeepWalk:原理与实现
图游走算法 DeepWalk:原理与实现
在复杂网络分析中,图游走算法如DeepWalk已成为学习图的低维表示的关键工具。DeepWalk通过模拟随机游走的方式捕捉图中的社区结构,进而生成节点的向量表示。这些向量表示不仅包含了图的结构信息,还能有效应用于各种图学习任务,如节点分类、链路预测和推荐系统等。DeepWalk算法的核心在于将随机游走生成的节点序列视为自然语言处理中的句子,并利用Word2Vec的Skip-Gram模型学习节点的低维嵌入。本文将详细介绍DeepWalk算法的原理、实现细节,并提供相应的代码示例。
DeepWalk 算法原理
DeepWalk 算法的核心思想是将图的结构信息转换为序列数据,然后应用自然语言处理技术中的方法,特别是 Word2Vec 算法,来学习图中每个节点的向量表示。这种方法允许我们捕捉和利用节点之间的局部和全局连接模式。
算法步骤详解
-
随机游走:随机游走在图中用于生成节点序列,类似于在文本中生成句子。此步骤的目的是以每个节点为起点,按照一定规则进行随机游走,以探索和捕捉图的局部结构特征。具体步骤包括:
- 起始节点选择:从图中随机选择一个节点作为起始点。
- 游走规则:从当前节点开始,随机选择一个邻接的节点作为下一个节点。这个选择通常与节点的度数(即与之相连的边的数量)成正比,这意味着度数较高的节点更可能被遍历到。
- 序列生成:重复上述过程,直到达到预定的序列长度。通常,这个过程会对每个节点重复多次,以生成足够的序列覆盖整个图。
-
学习表示:生成的序列被视为自然语言处理中的句子,其中的节点对应于单词。DeepWalk 使用 Word2Vec 算法来学习这些“单词”(即节点)的向量表示。Skip-Gram 和 CBOW(Continuous Bag of Words)是 Word2Vec 算法中的两种模型,它们用于从大量文本数据中学习词汇的向量表示。这两种模型虽然在目标函数的形式上类似,但在处理上下文和目标词的方式上存在差异。在 DeepWalk 算法中,这些模型被应用于图数据,其中图中的节点类似于词汇,节点的序列类似于句子。
- Skip-Gram 模型:Skip-Gram 模型的目的是根据目标节点(词)预测其周围的上下文节点(词)。对于每个训练样本,Skip-Gram 模型都尝试学习输入节点的嵌入,使得模型能够预测该节点在其随机游走序列中的上下文节点。 对于目标节点uuu 和其上下文节点 ccc,Skip-Gram 模型的目标是最大化上下文节点的条件概率的对数似然:
其中VVV是节点集合,NS(u)N_S(u) NS(u)是节点 uu u的上下文节点集。条件概率 P(c∣u)P(c | u)P(c∣u) 通常通过 softmax 函数定义:
这里 vc\mathbf{v}_cvc 和 vu\mathbf{v}_u vu 分别是上下文节点和目标节点的向量表示。该模型尤其适用于处理较大的图,因为它更关注每个节点与其直接上下文的关系。
- CBOW 模型:CBOW 模型的目的是根据节点的上下文来预测目标节点。它采用目标节点的上下文节点作为输入,通过这些上下文节点来预测目标节点。
这两种模型都通过迭代优化过程调整节点向量,以便使具有相似上下文的节点在向量空间中彼此接近,从而达到良好的聚类效果。
CBOW 模型的目标是最大化目标节点的条件概率的对数似然,给定其上下文节点:
其中NS(u) N_S(u)NS(u) 是节点uuu 的上下文节点集。条件概率 P(u∣NS(u))P(u | N_S(u)) P(u∣NS(u)) 也通常通过 softmax 函数定义:
这里 v‾NS(u)\overline{\mathbf{v}}_{N_S(u)}vNS(u) 是上下文节点向量的平均值。CBOW 模型特别适用于小图或节点度数较低的图,因为它侧重于从整个上下文中预测节点。
Python 实现
下面是使用 Python 实现 DeepWalk 的基本示例。我们将使用 networkx
创建图并使用 gensim
实现 Word2Vec。
安装必要库
首先确保安装了必要的库:
pip install networkx gensim matplotlib
代码实现
让我们分步骤实现 DeepWalk 算法的 Python 示例。我们将使用 networkx
来构建图,并利用 gensim
的 Word2Vec 来学习节点的嵌入。
步骤 1: 安装必要的库
确保安装了 networkx
和 gensim
库,这可以通过以下命令来完成:
pip install networkx gensim
步骤 2: 创建图
我们将创建一个简单的图,用于演示 DeepWalk 的实现。
import networkx as nx
# 创建一个随机图
def create_graph():
G = nx.fast_gnp_random_graph(100, 0.05) # 100个节点,生成边的概率为0.05
return G
步骤 3: 生成随机游走
我们将实现一个函数来生成随机游走序列,这些序列将作为 Word2Vec 模型的输入。
import random
def random_walk(G, start_node, walk_length):
walk = [start_node]
while len(walk) < walk_length:
cur = walk[-1]
cur_neighbors = list(G.neighbors(cur))
if not cur_neighbors:
break
next_node = random.choice(cur_neighbors)
walk.append(next_node)
return walk
def generate_walks(G, num_walks, walk_length):
walks = []
for _ in range(num_walks):
nodes = list(G.nodes())
random.shuffle(nodes)
for node in nodes:
walks.append(random_walk(G, node, walk_length))
return walks
步骤 4: 使用 Word2Vec 训练节点嵌入
利用 gensim
的 Word2Vec 模型来训练得到的随机游走序列。
from gensim.models import Word2Vec
def train_word2vec(walks):
model = Word2Vec(
walks, # 输入序列
vector_size=64, # 向量大小
window=5, # 窗口大小
min_count=0, # 忽略出现次数少于此值的节点
sg=1, # 使用skip-gram模型
workers=4, # 线程数
epochs=10 # 训练的迭代轮数
)
return model
步骤 5: 结合所有步骤
将所有步骤整合到一起,从创建图开始,然后生成随机游走,最后训练 Word2Vec 模型。
def main():
G = create_graph()
walks = generate_walks(G, num_walks=10, walk_length=20)
model = train_word2vec(walks)
# 获取某个节点的向量
node_id = 1
vector = model.wv[str(node_id)]
print(f"Vector representation for node {node_id}: {vector}")
if __name__ == "__main__":
main()
以上是使用 Python 实现 DeepWalk 的一个完整示例,包括图的生成、随机游走的模拟以及利用 Word2Vec 学习图节点嵌入的过程。这些步骤结合起来,可以有效地学习图中节点的特征表示,用于各种图分析任务。
结论
DeepWalk算法通过将随机游走与Word2Vec算法相结合,实现了对图结构中节点低维表示的学习。这种方法不仅能够捕捉图的结构信息,还能够利用Word2Vec模型的强大能力进行高效的嵌入学习。通过本文的介绍和代码示例,读者可以深入理解DeepWalk算法的原理和实现细节,并在实际应用中灵活运用
转载自:https://juejin.cn/post/7367182716997419058