1 概述

LINE是2015年微软发表的一篇论文,其全称为: Large-scale Information Network Embedding。论文下载地址:https://arxiv.org/pdf/1503.03578.pdf

LINE是一种基于graph产生embedding的方法,它可以适用于任何类型的graph,如无向图、有向图、加权图等,同时作者基于边采样进行了目标函数的优化,使算法既能捕获到局部的网络结构,也能捕获到全局的网络结构。

2 算法原理

2.1 新的相似度定义

该算法同时优化了节点的相似度计算方法,提出了一二阶相似度。

1、一阶相似度

一阶相似度用来描述的是两个顶点之间有一条边直接相连的情况,如果两个 u、vu、vuv 之间存在直连变,则其一阶相似度可以用权重wuvw_{uv}wuv来表示,如果不存在直连边,则一阶相似度为0。

上图中,顶点6、7之间是直接相连的,且权重比较大(边比较粗),则认为顶点6、7是相似的,且一阶相似度较高,顶点5、6之间并没有直接相连,则两者的一阶相似度为0。

2、二阶相似度

二阶相似度描述的是两个顶点之间没有直接相连,但是他们拥有相同的邻居。比如顶点 u、vu、vuv 直接不存在直接相连,但是 顶点 uuu 存在其自己的一阶连接点,uuu 和 对应的一阶连接点 的一阶相似度可以形式化定义为:p(u)=(wu,1,...,wu,∣V∣)p(u) = (w_{u,1}, ..., w_{u, |V|})p(u)=(wu,1,...,wu,V) ,同理可以得到顶点 vvv 和对应的一阶连接点的一阶相似度定义:p(v)=(wv,1,...,wv,∣V∣)p(v) = (w_{v,1}, ..., w_{v, |V|})p(v)=(wv,1,...,wv,V) ,顶点 u、vu、vuv 之间的相似度即为 p(u)、p(v)p(u)、p(v)p(u)p(v) 之间的相似度。

上图中,顶点 5、6之间并没有直接相连,但是他们各自的一阶连接点是相同的,说明他们也是相似的。二阶相似度就是用来描述这种关系的。

2.2 优化目标

1、一阶相似度

对于每一条无向边 (i,j)(i,j)(i,j) ,定义顶点 vi,vjv_i, v_jvi,vj之间的联合概率为:
p1(vi,vj)=11+exp(−ui⃗⋅uj⃗)p_1(v_i,v_j) = \frac{1} {1+exp(- \vec{u_i} \cdot \vec{u_j})} p1(vi,vj)=1+exp(ui

uj

)1
其中 ui⃗∈Rd\vec{u_i} \in R^dui

Rd
为顶点 viv_ivi 的低维向量表示(可以看作一个内积模型,计算两个item之间的匹配程度)。

同时定义经验分为:
p^1(i,j)=wi,jW\hat{p}_1(i,j) = \frac{w_{i,j}}{W} p^1(i,j)=Wwi,j
其中 W=∑i,j∈Ewi,jW = \sum_{i,j \in E} w_{i,j}W=i,jEwi,j

为了计算一阶相似度,优化的目标函数为:
O1=d(p^1(⋅,⋅),p1(⋅,⋅))O_1 = d(\hat{p}_1(\cdot , \cdot), p_1(\cdot , \cdot)) O1=d(p^1(,),p1(,))
其中 d(⋅,⋅)d(\cdot , \cdot)d(,) 是两个分布的距离,常用的衡量两个概率分布差异的指标为 KL 散度,使用 KL 散度并忽略常用项后有:
O1=−∑(i,j)∈Ewi,jlogp1(vi,vj)O_1 = - \sum_{(i,j) \in E} w_{i,j} log \, p_1 (v_i, v_j) O1=(i,j)Ewi,jlogp1(vi,vj)
一阶相似度只能用于无向图中。

2、二阶相似度

和一阶相似度不同的是,二阶相似度既可以用于无向图,也可以用于有向图。二阶相似度计算的假设前提是:两个顶点共享其各自的一阶连接顶点,在这种情况下,顶点被看作是一种特定的「上下文」信息,因此每一个顶点都扮演了两个角色,即拥有两个embedding向量,一个是顶点本身的表示向量,一个是该点作为其他顶点的上下文顶点时的表示向量。

对于有向边 (i,j)(i,j)(i,j),定义给定顶点 viv_ivi 的条件下,产生上下文(邻居)顶点 vjv_jvj 的概率为:
p2(vj∣vi)=exp(uj⃗T⋅ui⃗)∑k=1∣V∣exp(uk⃗T⋅ui⃗)p_2(v_j|v_i) = \frac {exp(\vec{u_j}^T \cdot \vec{u_i})}{ \sum_{k=1}^{|V|} exp(\vec{u_k}^T \cdot \vec{u_i})} p2(vjvi)=k=1Vexp(uk

Tui

)exp(uj

T
ui

)

其中 ∣V∣|V|V 为上下文顶点的个数。

二阶相似度定义的优化的目标函数为:
O2=∑i∈Vλid(p^2(⋅∣vi),p2(⋅∣vi))O_2 = \sum_{i \in V} \lambda_i d(\hat{p}_2(\cdot|v_i), p_2(\cdot|v_i)) O2=iVλid(p^2(vi),p2(vi))
其中 λi\lambda_iλi 为控制节点重要性的因子,可以通过顶点的度数或者 PageRank等方法估计得到。

同样定义经验分为:
p2^(vj∣vi)=wijdi\hat{p_2}(v_j | v_i) = \frac{w_{ij}}{d_i} p2^(vjvi)=diwij
其中,wijw_{ij}wij 是边 (i,j)(i,j)(i,j) 的边权,did_idi 是顶点 viv_ivi 的出度,对于带权图,di=∑k∈N(I)Wikd_i = \sum_{k \in N(I)} W_{ik}di=kN(I)Wik

使用KL散度计算两个概率的差异,化简后有:
O2=−∑(i,j)∈Ewi,jlogp2(vj∣vi)O_2 = -\sum_{(i,j) \in E} w_{i,j} \, log \, p_2(v_j | v_i) O2=(i,j)Ewi,jlogp2(vjvi)

2.3 优化技巧

1、Negative Sampling

二阶相似度计算中,在计算条件概率 p2(⋅∣vi)p_2(\cdot|v_i)p2(vi) 时,需要遍历所有的顶点,效率非常低下,论文中采用了负采样的技术,优化后,目标函数为:
logσ(uj⃗T⋅ui⃗)+∑i=1KEvn∼Pn(v)[−logσ(un⃗T⋅ui⃗)]log \, \sigma (\vec{u_j}^T \cdot \vec{u_i}) + \sum_{i=1}^{K} E_{v_n} \sim P_n(v)[-log \, \sigma(\vec{u_n}^T \cdot \vec{u_i}) ] logσ(uj

Tui

)+
i=1KEvnPn(v)[logσ(un

T
ui

)]

其中 KKK 为负采样的个数。

论文中定义 pn(v)p_n(v)pn(v) 正比于 dv3/4d_v ^{3/4}dv3/4dvd_vdv 是顶点 vvv 的出度(采样的个数为:出度的 3/4 幂)。

同时论文中使用 ASGD(Asynchronous Stochastic Gradient)算法进行优化。

2、Edge Sampling

在定义的一、二阶目标函数时,log之前还有一个权重系数 wi,jw_{i,j}wi,j ,在使用梯度下降方法优化参数时, wi,jw_{i,j}wi,j 会直接乘在梯度上。如果图中的边权方差很大,则很难选择一个合适的学习率。若使用较大的学习率那么对于较大的边权可能会引起梯度爆炸,较小的学习率对于较小的边权则会导致梯度过小。

对于上述问题,如果所有边权相同,那么选择一个合适的学习率会变得容易。这里采用了将带权边拆分为等权边的一种方法,假如一个权重为 www 的边,则拆分后为 www 个权重为1的边。这样可以解决学习率选择的问题,但是由于边数的增长,存储的需求也会增加。

另一种方法则是从原始的带权边中进行采样,每条边被采样的概率正比于原始图中边的权重,这样既解决了学习率的问题,又没有带来过多的存储开销。

这里的采样算法使用的是Alias算法,Alias是一种 O(1)O(1)O(1) 时间复杂度的离散事件抽样算法。具体内容可以参考:时间复杂度O(1)的离散采样算法—— Alias method/别名采样方法

2.4 其他讨论点

1、低度顶点的嵌入表示

由于低度顶点邻居数目极少,原网络中提供的信息有限,尤其在基于二阶相似度的LINE算法中是非常依赖于顶点的邻居数目的,那么如何确定低度顶点的向量表示呢?

一种直观的方法:添加更高阶的邻居(如邻居的邻居)来作为该低度结点的直接邻居。 与新添邻居边的权重如下:
wij=∑k∈N(i)wikwkjdkw_{ij} = \sum_{k \in N(i)} w_{ik} \frac{w_{kj}} {d_k} wij=kN(i)wikdkwkj
dkd_kdk 是结点 kkk 的出边的权重总和(实际上,可以只添加与低度顶点 iii 有边的,且边权最大的顶点 jjj 的邻居作为顶点i的二阶邻居)

2、如何找到网络中新添加顶点的向量表示

如果已知新添加的顶点i与现有顶点的联系(即存在边),则可得到其经验分布:p^1(⋅,vi)\hat{p}_1(\cdot, v_i)p^1(,vi)p^2(⋅∣vi)\hat{p}_2(\cdot | v_i)p^2(vi)

之后通过最小化一、二阶相似度的目标函数可得到新加顶点i的向量表示:
$$

  • \sum_{j \in N(i)} w_{ji} , log , p_1(v_j, v_i)
    或者:或者:
  • \sum_{j \in N(i)} w_{ji} , log , p_1(v_j | v_i)
    $$
    如果未能观察到新添顶点与其他现有顶点的联系,我们只能求助其他信息,比如顶点的文本信息,留待以后研究。

3 实验

算法在以下的数据集上进行了测试

对比了算法:

  • Graph factorization (GF)
  • DeepWalk
  • LINE-SGD
  • LINE
  • LINE(1st+2nd)

使用的评估指标为:

  • Micro-F1
  • Macro-F1

在维基百科上的相关算法表现如下(更多看的是在语义、句法、覆盖率、运行时间上的对比分析):

在维基百科上进行的分类对比实验结果如下,可以看出LINE(1st+2nd)是要比其他算法效果明显的

在Flickr网络数据上进行的多目标分类LINE(1st+2nd)的效果也不错

将产出的embedding降维到2度,并进行可视化,可以看出,LINE的聚类效果更加明显。

4 代码实现

论文中给出了C 代码实现的地址

https://github.com/tangjianpku/LINE

「浅梦」也实现了很多的graph embedding算法,链接为:https://github.com/shenweichen/GraphEmbedding。当然我也看到有人基于tf实现了LINE算法,算是扩展了眼界吧,其主要代码如下,完整链接为:https://github.com/snowkylin/line。

import tensorflow as tf
import numpy as np
import argparse
from model import LINEModel
from utils import DBLPDataLoader
import pickle
import timedef main():parser = argparse.ArgumentParser()parser.add_argument('--embedding_dim', default=128)parser.add_argument('--batch_size', default=128)parser.add_argument('--K', default=5)parser.add_argument('--proximity', default='second-order', help='first-order or second-order')parser.add_argument('--learning_rate', default=0.025)parser.add_argument('--mode', default='train')parser.add_argument('--num_batches', default=300000)parser.add_argument('--total_graph', default=True)parser.add_argument('--graph_file', default='data/co-authorship_graph.pkl')args = parser.parse_args()if args.mode == 'train':train(args)elif args.mode == 'test':test(args)def train(args):data_loader = DBLPDataLoader(graph_file=args.graph_file)suffix = args.proximityargs.num_of_nodes = data_loader.num_of_nodesmodel = LINEModel(args)with tf.Session() as sess:print(args)print('batches\tloss\tsampling time\ttraining_time\tdatetime')tf.global_variables_initializer().run()initial_embedding = sess.run(model.embedding)learning_rate = args.learning_ratesampling_time, training_time = 0, 0for b in range(args.num_batches):t1 = time.time()u_i, u_j, label = data_loader.fetch_batch(batch_size=args.batch_size, K=args.K)feed_dict = {model.u_i: u_i, model.u_j: u_j, model.label: label, model.learning_rate: learning_rate}t2 = time.time()sampling_time += t2 - t1if b % 100 != 0:sess.run(model.train_op, feed_dict=feed_dict)training_time += time.time() - t2if learning_rate > args.learning_rate * 0.0001:learning_rate = args.learning_rate * (1 - b / args.num_batches)else:learning_rate = args.learning_rate * 0.0001else:loss = sess.run(model.loss, feed_dict=feed_dict)print('%d\t%f\t%0.2f\t%0.2f\t%s' % (b, loss, sampling_time, training_time,time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))sampling_time, training_time = 0, 0if b % 1000 == 0 or b == (args.num_batches - 1):embedding = sess.run(model.embedding)normalized_embedding = embedding / np.linalg.norm(embedding, axis=1, keepdims=True)pickle.dump(data_loader.embedding_mapping(normalized_embedding),open('data/embedding_%s.pkl' % suffix, 'wb'))def test(args):passif __name__ == '__main__':main()

5 应用

LINE是与基于Graph构建的item embedding,在拿到item的embedding之后,我们可以进行的工作包括:

  • 作为特征在粗排模型、精排模型进行使用
  • 用来进行embedding的检索召回
  • 分类
  • 聚类

有一点需要注意的是,LINE算法可以应用到有向图、无向图、带权图中,相比DeepWalk等graph算法更加的灵活,但还是要看自己的需求而定,选用合适的算法做合适的事。


【技术服务】详情点击查看: https://mp.weixin.qq.com/s/PtX9ukKRBmazAWARprGIAg


扫一扫关注「搜索与推荐Wiki」!号主「专注于搜索和推荐系统,以系列分享为主,持续打造精品内容!

论文|LINE算法原理、代码实战和应用相关推荐

  1. DeepLearning | 图卷积神经网络(GCN)解析(论文、算法、代码)

    本篇博客主要讲述三种图卷积网络(Graph Convolutional Network, GCN)的算法原理及python实现,全文阅读时间约10分钟. 博主关于图神经网络的文章 DeepLearni ...

  2. 【机器学习】总结了九种机器学习集成分类算法(原理+代码)

    大家好,我是云朵君! 导读: 本文是分类分析(基于Python实现五大常用分类算法(原理+代码))第二部分,继续沿用第一部分的数据.会总结性介绍集成分类算法原理及应用,模型调参数将不在本次讨论范围内. ...

  3. 总结了九种机器学习集成分类算法(原理+代码)

    公众号后台回复"图书",了解更多号主新书内容作者:云朵君来源: 数据STUDIO 导读: 本文是分类分析(基于Python实现五大常用分类算法(原理+代码))第二部分,继续沿用第一 ...

  4. 六、PageRank算法与代码实战【CS224W】(Datawhale组队学习)

    开源内容:https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频:https://space.bilibili.com ...

  5. 孤立森林异常检测算法原理和实战(附代码)

    孤立森林(isolation Forest)算法,2008年由刘飞.周志华等提出,算法不借助类似距离.密度等指标去描述样本与其他样本的差异,而是直接去刻画所谓的疏离程度(isolation),因此该算 ...

  6. 原理+代码实战 | 双目视觉中的极线校正

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:计算机视觉life 为什么要做极线校正? 三维重建是通过 ...

  7. 机器学习-聚类之K均值(K-means)算法原理及实战

    K-means算法 前言 机器学习方法主要分为监督学习和非监督学习两种.监督学习方法是在样本标签类别已知的情况下进行的,可以统计出各类样本的概率分布.特征空间分布区域等描述量,然后利用这些参数进行分类 ...

  8. 机器学习-降维之奇异值分解SVD算法原理及实战

    奇异值分解 简介 PCA是通过特征值分解来进行特征提取的,但它要求矩阵必须是方阵,但在实际应用场景中,经常遇到的矩阵都不是方阵,如N个学生,每个学生有M门课程,其中N!=M, 这就组成了一个M*N的非 ...

  9. 机器学习-降维之主成分分析PCA算法原理及实战

    主成分分析 前言 近年来,随着互联网和信息行业的发展,数据已经渗透到各行各业,成为重要的生产因素如数据记录和属性规模的急剧增长.社会已经进入大数据时代,数据越多越好似乎已经成为公理.然而,数据量并不是 ...

最新文章

  1. 4G EPS 的接口类型
  2. 排序算法--冒泡排序的首尾改进
  3. 【MM模块】Batch 批次管理1
  4. 如何阅读《深入理解计算机系统》?(文末送书)
  5. 织梦 css里的图片标签,织梦{dede:field.body /}中用CSS的expression参数控制图片大小
  6. 深入浅出深度学习(三)线性代数基础
  7. linux卸载minicoda2,MiniConda2下载 MiniConda python 2.7 v4.3.30.2 Linux 64位 官方免费版(附安装步骤) 下载-脚本之家...
  8. 使用git上传代码到github远程仓库
  9. 【机器学习】Bagging和Boosting的区别(面试准备)
  10. 鲲鹏性能优化十板斧(四)——磁盘IO子系统性能调优
  11. 全新骁龙855 Plus加持!ROG游戏手机2下周发布:无惧逆风挑战
  12. Windows 2000活动目录详解之基础篇
  13. Gartner:2015年全球MSS市场分析
  14. 关于部署OOS时出现的证书问题解决
  15. stream筛选出集合中对象属性重复值
  16. 快递查询APP隐私条款
  17. 十大最赚钱增值业务排行榜
  18. 小米生活早报早间新闻入口/凤凰FM头条速递入口
  19. 笔记本电脑如何选购并安装内存条
  20. QSL Server SQL语句实例

热门文章

  1. css源码笔记(四)【爱创课堂专业前端培训】
  2. Chrome 53 Beta一些有意思的改动
  3. 用python做一个简单的猜拳游戏
  4. 数据结构笔记(C语言版)
  5. 资产管理之RFID资产管理系统解决方案-RFID资产智能盘点-新导智能
  6. R语言实战之基本统计分析
  7. 微信屏蔽网页跳转到app store的解决方案
  8. dell10代cpu装linux,戴尔10代cpu装win7系统及bios设置|戴尔十代cpu台式机装win7
  9. Python字符串切片总结
  10. stm32+k210视觉小车——来拒去留+多位串口通信