参考:
详解Graph Embedding经典方法:算法原理、代码实现与应用样例
Graph Embedding 图表示学习的原理及应用

代码参考:
https://github.com/shenweichen/GraphEmbedding

本篇简单测试一下该库


文章目录

  • 1 Graph Embedding 几种常见方法
    • 1.1 DeepWalk
    • 1.2 LINE
    • 1.3 nodo2vec
    • 1.4 SDNE
    • 1.5 Struc2Vec
  • 2 实验代码

1 Graph Embedding 几种常见方法

Model Paper Note
DeepWalk [KDD 2014]DeepWalk: Online Learning of Social Representations 【Graph Embedding】DeepWalk:算法原理,实现和应用
LINE [WWW 2015]LINE: Large-scale Information Network Embedding 【Graph Embedding】LINE:算法原理,实现和应用
Node2Vec [KDD 2016]node2vec: Scalable Feature Learning for Networks 【Graph Embedding】Node2Vec:算法原理,实现和应用
SDNE [KDD 2016]Structural Deep Network Embedding 【Graph Embedding】SDNE:算法原理,实现和应用
Struc2Vec [KDD 2017]struc2vec: Learning Node Representations from Structural Identity 【Graph Embedding】Struc2Vec:算法原理,实现和应用

Graph Embedding 技术将图中的节点以低维稠密向量的形式进行表达,要求在原始图中相似 ( 不同的方法对相似的定义不同 ) 的节点其在低维表达空间也接近。得到的表达向量可以用来进行下游任务,如节点分类,链接预测,可视化或重构原始图等。

1.1 DeepWalk

DeepWalk 的思想类似 word2vec,使用图中节点与节点的共现关系来学习节点的向量表示。那么关键的问题就是如何来描述节点与节点的共现关系,DeepWalk 给出的方法是使用随机游走 (RandomWalk) 的方式在图中进行节点采样。

分类任务结果

micro-F1 : 0.6674
macro-F1 : 0.5768

1.2 LINE

之前介绍过DeepWalk,DeepWalk使用DFS随机游走在图中进行节点采样,使用word2vec在采样的序列学习图中节点的向量表示。

LINE也是一种基于邻域相似假设的方法,只不过与DeepWalk使用DFS构造邻域不同的是,LINE可以看作是一种使用BFS构造邻域的算法。此外,LINE还可以应用在带权图中(DeepWalk仅能用于无权图)。

分类任务结果

micro-F1: 0.6403
macro-F1:0.5286

结果有一定随机性,可以多运行几次,或者稍微调整epoch个数。

1.3 nodo2vec

前面介绍过基于DFS邻域的DeepWalk和基于BFS邻域的LINE。

node2vec是一种综合考虑DFS邻域和BFS邻域的graph embedding方法。简单来说,可以看作是deepwalk的一种扩展,是结合了DFS和BFS随机游走的deepwalk。
分类任务

micro-F1: 0.6757 macro-F1: 0.5917

这个结果相比于DeepWalk和LINE是有提升的。

1.4 SDNE

SDNE(Structural Deep Network Embedding )是和node2vec并列的工作,均发表在2016年的KDD会议中。可以看作是基于LINE的扩展,同时也是第一个将深度学习应用于网络表示学习中的方法。
SDNE使用一个自动编码器结构来同时优化1阶和2阶相似度(LINE是分别优化的),学习得到的向量表示能够保留局部和全局结构,并且对稀疏网络具有鲁棒性。

分类任务

micro-F1: 0.6341 macro-F1: 0.4962

这里还有一个SDNE在业界的应用的介绍:
阿里凑单算法首次公开!基于Graph Embedding的打包购商品挖掘系统解析

1.5 Struc2Vec

前面介绍过DeepWalk,LINE,Node2Vec,SDNE几个graph embedding方法。这些方法都是基于近邻相似的假设的。其中DeepWalk,Node2Vec通过随机游走在图中采样顶点序列来构造顶点的近邻集合。LINE显式的构造邻接点对和顶点的距离为1的近邻集合。SDNE使用邻接矩阵描述顶点的近邻结构。
事实上,在一些场景中,两个不是近邻的顶点也可能拥有很高的相似性,对于这类相似性,上述方法是无法捕捉到的。Struc2Vec就是针对这类场景提出的。Struc2Vec的论文发表在2017年的KDD会议中。

分类

Struc2Vec结果 micro-F1: 0.7143, macro-F1: 0.7357
Node2Vec结果 micro-F1: 0.3571, macro-F1: 0.3445

差距还是蛮大的,说明Struc2Vec确实能够更好的捕获空间结构性。


2 实验代码

import pandas as pd
import copy
from collections import Counter
from tqdm import tqdm
import sys
import random
sys.path.append('GraphEmbedding')
#from GraphEmbedding.examples.struc2vec_flight import *
import time
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from sklearn.manifold import TSNE
import pandas as pd
from collections import Counterdata_list = [set(['A','B']),set(['D','C']),set(['E','A']),set(['E','D']),set(['A','D']),set(['B','D'])]item_id = set()
data_list_3 = {}
total_freq = len(data_list)for dl in tqdm(data_list):# for d in dl:item_id.add(str(d).replace(' ',''))# dl = copy.deepcopy(tuple(str(d).replace(' ','') for d in dl))if dl not in data_list_3.keys():data_list_3[dl] = 0data_list_3[dl] += 1data_label = {str(ii).replace(' ',''):str(n) for n,ii in enumerate(item_id)} # 节点:节点编号
data_list_3 = {k:v for k,v in data_list_3.items()}   # [A,B]出现频率# 数据导出 - 节点-节点
edgelist_file = open('GraphEmbedding/test/data.edgelist','w+',encoding = 'utf-8') for k,v in tqdm(data_list_3.items()):k = [str(_k) for _k in k]text = ' '.join([data_label[_k] for _k in k]+[str(v)]) + '\n'# text = ' '.join(list(k)) + '\n'edgelist_file.write(text)edgelist_file.close()# 数据导出 - 节点-解释
edgelist_label = open('GraphEmbedding/test/data.label','w+',encoding = 'utf-8') for k,v in tqdm(data_label.items()):text = ' '.join([k,v]) + '\n'# text = ' '.join(list(k)) + '\n'edgelist_label.write(text)edgelist_label.close()#----
def bit_product_sum(x, y):return sum([item[0] * item[1] for item in zip(x, y)])def cosine_similarity(x, y, norm=False):""" 计算两个向量x和y的余弦相似度 """assert len(x) == len(y), "len(x) != len(y)"zero_list = [0] * len(x)if x == zero_list or y == zero_list:return float(1) if x == y else float(0)# method 1res = np.array([[x[i] * y[i], x[i] * x[i], y[i] * y[i]] for i in range(len(x))])cos = sum(res[:, 0]) / (np.sqrt(sum(res[:, 1])) * np.sqrt(sum(res[:, 2])))# method 2# cos = bit_product_sum(x, y) / (np.sqrt(bit_product_sum(x, x)) * np.sqrt(bit_product_sum(y, y)))# method 3# dot_product, square_sum_x, square_sum_y = 0, 0, 0# for i in range(len(x)):#     dot_product += x[i] * y[i]#     square_sum_x += x[i] * x[i]#     square_sum_y += y[i] * y[i]# cos = dot_product / (np.sqrt(square_sum_x) * np.sqrt(square_sum_y))return 0.5 * cos + 0.5 if norm else cos  # 归一化到[0, 1]区间内def plot_embeddings(emb_list,color_random = []):#X, Y = read_node_label('../data/wiki/wiki_labels.txt')X = emb_listif len(color_random) == 0:color_random = [random.sample(range(20), 1)[0] for _ in range(len(embeddings))]model = TSNE(n_components=2)node_pos = model.fit_transform(emb_list)color_idx = {}for i in range(len(X)):color_idx.setdefault(color_random[i], [])color_idx[color_random[i]].append(i)for c, idx in color_idx.items():plt.scatter(node_pos[idx, 0], node_pos[idx, 1], label=c)plt.legend()plt.show()G = nx.read_edgelist('GraphEmbedding/test/data.edgelist', create_using=nx.DiGraph(), nodetype=None,data=[('weight', int)])
# struc2vec -> 最有规律
from ge import Struc2Vec
s2v_model = Struc2Vec(G, 10, 80, workers=4, verbose=40, )
s2v_model.train()
embeddings = s2v_model.get_embeddings()# from ge import SDNE
# sdne_model = SDNE(G, hidden_size=[1024, 512],)
# sdne_model.train(batch_size=20000, epochs=50, verbose=2)
# embeddings = sdne_model.get_embeddings()# node2vec -> 有一小簇有规律
from ge import Node2Vec
n2v_model = Node2Vec(G, walk_length=10, num_walks=80,p=0.25, q=4, workers=1, use_rejection_sampling=0)
n2v_model.train(window_size = 5, iter = 3)
embeddings=n2v_model.get_embeddings()# DeepWalk -> 最散
from ge import DeepWalk
dw_model = DeepWalk(G, walk_length=10, num_walks=80, workers=1)
dw_model.train(window_size=5, iter=3)
embeddings = dw_model.get_embeddings()# 画图
emb_list = np.array(list(embeddings.values()))
#evaluate_embeddings(embeddings)
plot_embeddings(emb_list)# id中文名
label = pd.read_table('GraphEmbedding/test/data.label',header = None)
id_to_label = {l.split(' ')[1]:l.split(' ')[0]  for l in label[0]}
label_to_id = {l.split(' ')[0]:l.split(' ')[1]  for l in label[0]}# 求相似产品
simi = n2v_model.w2v_model.wv.most_similar(label_to_id['D'],topn = 20)
simi
n2v_model.sentences

开源代码已经把各个调用写的非常简单了,所以简单处理数据就可以直接测试,需要包括:

  • data.edgelist 边信息
  • data.label 节点信息

后续还可以通过TSNE把向量可视化出来,在函数plot_embeddings之中

因为借助的是gensim,所以可以使用任何词向量的功能,包括近似词查询等

在自己的实践里,貌似struc2vec从可视化TSNE效果来看,最好,分的最清楚。

简单实践GraphEmbedding图嵌入的几种方法相关推荐

  1. Android实现截屏和截长图功能的几种方法

    一般情况下各种型号的手机都会有自带的截屏功能,也会有诸如"开关机键+音量键"的截屏快捷键,只要手机是亮屏状态,都会将手机屏幕的可视区域(包含状态栏)全部截取下来. 如果开发中想要调 ...

  2. Android 实现截屏和截长图功能的几种方法

    欢迎大家关注我的公众号:**牛角尖尖上起舞** 一般情况下各种型号的手机都会有自带的截屏功能,也会有诸如"开关机键+音量键"的截屏快捷键,只要手机是亮屏状态,都会将手机屏幕的可视区 ...

  3. php随机缩略图,实现随机缩略图的简单思路和phpcms随机缩略图两种方法

    一种实现随机缩略图的简单思路:设置一个随机缩略图图片池(比如thumb文件夹),里面放若干张从"1.jpg"开始顺序命名的预置图片,判断无缩略图时,使用php的mt_rand(1, ...

  4. python简单绘图步骤_python画图的两种方法

    python如何画图?这里给大家介绍两款python绘图的库:turtle和Matplotlib. 1 安装turtle Python2安装命令:pip install turtule Python3 ...

  5. 【前端必学】PS切图详细教程3种方法(图层切图,切片,切图神器cutterman)

    PSD图像格式是Photoshop的专用格式,里面可以存放图层.通道.遮置等多种设计稿,对我们前端人员来说,最大的优点,我们可以直接从上面复制文字,获得图片,还可以测量大小和距离, 我们开发需要的是一 ...

  6. 【图嵌入】Graph Embedding 方法之 LINE 原理解读

    LINE 出自论LINE: Large-scale Information Network Embedding,与 DeepWalk 相比,比较明显的区别在于: DeepWalk 使用的深度优先搜索策 ...

  7. springboot学习(一)IDEA简单使用以及数据源配置的三种方法

    Springboot的简单使用 1 运行环境 2 maven的配置如下 3 如何使用springboot 4.配置数据源 4.1基本的配置方法 4.2springboot对数据源配置的优化(第一种) ...

  8. 图嵌入综述 (arxiv 1709.07604) 译文 4.1 ~ 4.2

    原文:A Comprehensive Survey of Graph Embedding: Problems, Techniques and Applications (arxiv 1709.0760 ...

  9. 图嵌入综述 (arxiv 1709.07604) 译文第三章

    原文:A Comprehensive Survey of Graph Embedding: Problems, Techniques and Applications (arxiv 1709.0760 ...

最新文章

  1. 矿Spring入门Demo
  2. CRMEB删除公众号首页logo动画
  3. 周五尾盘上涨,配合周末消息,周一套人的经典实例
  4. php中preg_match用户名正则实例
  5. java maven module_java – Maven JDK9模块:无法解析module-info
  6. php的工作模式CGI,FastCGI,PHP-CGI与PHP-FPM(转)
  7. Photon服务器引擎入门
  8. Python使用OpenCV+pillow提取AVI视频中关键帧图像
  9. CocoaPods 简易教程 Alamofire请求数据 Swift
  10. 如何选择VC界面库产品
  11. SQLServer 2008 r2 安装图解
  12. Maxscale读写分离,多实例
  13. 什么是UV贴图和展开?游戏建模纯干货,UV的详细解释,不懂得赶紧看过来!
  14. 台湾科技挣扎,人祸大于天灾?
  15. scikit-learn笔记
  16. 回收站里的文件都清空了应该怎么恢复?
  17. 人工智能主要是学什么的?
  18. VS2019 / 2017 / 2013 产品密钥 – 所有版本
  19. Java最小因式分解_Javascript-625-最小因式分解——腾讯面试题库
  20. SVN冲突解决方案总结

热门文章

  1. Storm计算结果是怎样存放的
  2. C++ 类的前向声明
  3. 对面象对象概念的理解、解释
  4. 负载均衡原理与实践详解 第五篇 负载均衡时数据包流程详解
  5. COOKIE和Session的原理及异同
  6. 「极点日历」小程序插件
  7. 安利一个React同构渲染脚手架 —— razzle
  8. BGP多出口多宿主实验
  9. VMware中让虚拟机支持虚拟化
  10. Netflix推出Hollow,处理内存数据集的Java库