DeepWalk 是一种用于网络表示学习(Network Representation Learning)的经典算法,它通过随机游走生成句子,再借助 Skip-Gram 模型进行学习,从而将图中节点嵌入到低维空间中。本文将详细介绍 DeepWalk 的核心算法、涉及的矩阵计算,以及示例代码。
DeepWalk算法简介
DeepWalk 是一种无监督学习方法,核心思想是将图中的节点通过随机游走生成类似句子的结构,并利用自然语言处理中的 Skip-Gram 模型学习节点的表示向量。
算法流程
- 随机游走 (Random Walk): 在图中执行随机游走生成节点序列,类似于句子的结构。
- 构建共现窗口: 对于生成的节点序列,设置一个窗口大小,提取共现关系。
- Skip-Gram 模型训练: 利用 Skip-Gram 训练节点的嵌入向量。
- 节点向量生成: 输出所有节点的低维嵌入向量。
算法公式
DeepWalk 的目标是最大化条件概率:
max Φ ∏ v ∈ V ∏ u ∈ N ( v ) P ( u ∣ v ; Φ ) \max_\Phi \prod_{v\in V}\prod_{u\in N(v)} P(u|v;\Phi) Φmaxv∈V∏u∈N(v)∏P(u∣v;Φ)
其中:
- ( V ) 为图中所有节点集合,
- ( N(v) ) 为节点 ( v ) 的邻居节点集合,
- ( \Phi ) 表示节点嵌入向量的参数。
Skip-Gram 模型用以近似条件概率:
P ( u ∣ v ; Φ ) = exp ( Φ ( u ) ⋅ Φ ( v ) ) ∑ w ∈ V exp ( Φ ( w ) ⋅ Φ ( v ) ) P(u|v;\Phi) = \frac{\exp(\Phi(u)\cdot\Phi(v))}{\sum_{w\in V}\exp(\Phi(w)\cdot\Phi(v))} P(u∣v;Φ)=∑w∈Vexp(Φ(w)⋅Φ(v))exp(Φ(u)⋅Φ(v))
为了解决计算复杂度问题,通常使用 负采样 (Negative Sampling) 技术。
矩阵表示
在实现中,DeepWalk 需要以下关键矩阵:
- 转移概率矩阵 ( A ): 表示随机游走过程中从一个节点跳到另一个节点的概率。
- 嵌入矩阵 ( \Phi ): 用于存储节点的低维嵌入向量。
转移概率矩阵 ( A ) 的定义为:
A i j = { 1 deg ( v i ) , 若 ( v i , v j ) 存在边 ; 0 , 否则 . A_{ij} = \begin{cases} \frac{1}{\deg(v_i)}, & \text{若 } (v_i, v_j) \text{ 存在边}; \\ 0, & \text{否则}. \end{cases} Aij={deg(vi)1,0,若 (vi,vj) 存在边;否则.
代码实现
以下是一个基于 Python 的 DeepWalk 算法实现:
import random
import numpy as np
from gensim.models import Word2Vec
from collections import defaultdict
class DeepWalk:
def __init__(self, graph, walk_length, num_walks, embedding_dim, window_size):
self.graph = graph
self.walk_length = walk_length
self.num_walks = num_walks
self.embedding_dim = embedding_dim
self.window_size = window_size
self.sentences = []
def random_walk(self, start_node):
walk = [start_node]
for _ in range(self.walk_length - 1):
neighbors = self.graph[walk[-1]]
if neighbors:
walk.append(random.choice(neighbors))
else:
break
return walk
def generate_walks(self):
nodes = list(self.graph.keys())
for _ in range(self.num_walks):
random.shuffle(nodes)
for node in nodes:
walk = self.random_walk(node)
self.sentences.append(walk)
def train(self):
self.generate_walks()
model = Word2Vec(
sentences=self.sentences,
vector_size=self.embedding_dim,
window=self.window_size,
min_count=0,
sg=1,
workers=4
)
return model.wv
# 示例图结构
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
deepwalk = DeepWalk(graph, walk_length=10, num_walks=100, embedding_dim=64, window_size=5)
node_embeddings = deepwalk.train()
# 输出节点向量
for node in graph.keys():
print(f"Node {node}: {node_embeddings[node]}")
Gamma函数与数学公式
在算法优化中,有时需要用到 Gamma 函数来处理连续概率分布。Gamma 函数的定义为:
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt Γ(z)=∫0∞tz−1e−tdt
当 ( z ) 为正整数时,Gamma 函数可以表示为阶乘形式:
Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb{N} Γ(n)=(n−1)!∀n∈N
这在连续分布的推导中十分有用,例如计算节点的连续嵌入分布时。
总结
DeepWalk 算法将图结构与自然语言处理相结合,通过随机游走和 Skip-Gram 模型学习节点的低维嵌入。本文介绍了其核心流程、矩阵表示,以及 Python 实现代码,最后还展示了 Gamma 函数的相关公式。希望能帮助大家更好地理解和实现 DeepWalk 算法。
全局关系总结
随机游走(步骤 1是整个过程的起点,其目的是将图结构信息转化为序列信息。
共现窗口步骤通过分析序列提取节点的邻接关系,为嵌入向量的训练提供监督信号。
Skip-Gram 模型训练(步骤 3使用从随机游走中提取的上下文信息优化节点嵌入。
节点嵌入(步骤 4是最终目标,表示图中每个节点的低维向量,能在保留图结构信息的同时便于下游任务使用。