networkx基本操作请参考:[呆萌的图模型学习——图基本信息 & Networkx基本操作(二)](呆萌的图模型学习——图基本信息 & Networkx基本操作(二))
node2vec github 地址:https://github.com/eliorc/node2vec
算法思路
xxx to vec
是一段时期的产物,传说当年首先出了一个word2vec
模型,
word2vec:把一句话先分词,然后在一句话中以词为基本单位,通过随机游走的方式在词与相邻的词之间跳来跳去,生成多个等长的序列,用这样的一堆序列,使用skipgram来训练模型,最后每个词都有embedding,相似的embedding同时还代表有相似的语义
之后,大家发现这种神奇的操作,然后那这个思路套在不同的场景下,套在图模型下就有了node2vec
node2vec:在图上使用随机游走(等概率到相邻节点),在节点间跳来跳去,生成多个等长的序列,最后用skipgram训练模型,每个节点就有了embedding
示例代码
import networkx as nx
import os
def generate_network():
"""构建图的操作"""
# 构建一个图,包括三个群落,分别包裹5,12,13个节点
gen_network: nx.Graph = nx.generators.community.random_partition_graph([5, 12, 13], .25, .1, seed=0)
return gen_network
def node_2_vec(graph: nx.Graph = None):
"""根据图,计算node2vec与边的embedding"""
from node2vec import Node2Vec
from node2vec.edges import HadamardEmbedder
from gensim.models import Word2Vec
from gensim.models import KeyedVectors
node2vec_model_save_path = "node2vec_model"
node2vec_edge_save_path = "edge_model"
node_kv = None
edges_kv = None
# 根据图模型创建node2vec,并导出Word2vec向量
if os.path.exists(node2vec_model_save_path):
node_kv = Word2Vec.load(node2vec_model_save_path)
else:
node2vec_model = Node2Vec(graph, workers=1, dimensions=16) # 训练node2vec
node_kv = node2vec_model.fit(window=10, min_count=1, batch_words=4)
node_kv.save(node2vec_model_save_path) # 保存模型
# word2vec_model.wv["节点名"]
# 根据node2vec计算edge2vec
if os.path.exists(node2vec_edge_save_path):
edges_kv = KeyedVectors.load(node2vec_edge_save_path)
else:
edges_embs = HadamardEmbedder(keyed_vectors=node_kv.wv) # 根据node2vec训练边的vec
edges_kv = edges_embs.as_keyed_vectors()
edges_kv.save(node2vec_edge_save_path)
return node_kv, edges_kv
if __name__ == '__main__':
generate_graph = generate_network()
node_vec, edge_vec = node_2_vec(graph=generate_graph)
print("节点的embedding", node_vec.wv[1])
print('边的embedding', edge_vec['(\'23\', \'27\')'])