分享

基于GNN的社交推荐算法设计与应用

 520jefferson 2021-12-20
嘿,记得给“机器学习与推荐算法”添加星标

分享嘉宾:易玲玲/孙仕杰 腾讯

出品平台:DataFunTalk

导读:在微信平台,大部分数据都是以图结构的形式存在的。比如社交网络天然是一个图结构数据,其次,用户行为数据也可以被构建成为行为图谱。相应地,在微信平台上的大多数机器学习任务都是可以使用图算法进行建模的。比如用户兴趣标签的预测是图上的节点分类问题,推荐物品相当于是图的链路预测问题。今天主要分享我们在微信平台上图神经网络的落地应用,围绕推荐算法设计和系统落地两个方面,分以下三大部分:
  • 图表征算法技术演进

  • GNN算法在社交推荐中的应用

  • GNN实时训练和在线推理

01

图表征算法技术演进

图数据建模的关键在于图表征。学术界已经有比较多较为成熟的图表征算法,在微信上图表征算法也有三个阶段的发展:

1. 人工提取特征(15年前) 

图片

微信团队在图特征的表达上经历过几次技术迭代。在15年之前,我们采用的是人工提取特征,即我们会去理解图数据的物理结构。例如我们利用节点特征,使用节点中心性算法、节点度数、kcore、closeness等网络科学中常见指标衡量节点的社交拓扑特征;又如利用图中边的特征信息,计算共同邻居以及好友亲密度,甚至使用社团划分算法来描述群体特征。微信实际应用中,好友推荐、同事推荐会使用计算共同邻居的传统算法来实现。

人工提取特征的优点在于逻辑非常简单,解释性非常强,但是缺点在于由于需要人工定义特征,导致特征提取费时费力,而且它提取的信息相对有限。

2. 自动学习特征(15年-18年)

图片

在15年之后我们尝试了使用无监督的Network Embedding技术来提取图表征。我们使用Deepwalk这类算法使得图在Embedding空间上表达出对应的拓扑特征。这一类算法在业务上的应用手段是先通过Network Embedding把图的拓扑特征抽取出来,那么在下游任务中可以使用抽取的拓扑特征和节点本身的一些诸如兴趣这类的属性特征结合起来进行使用,进行第二阶段的建模。

相比人工构造图特征,Network Embedding完成了自动提取特征,效率更高,然而,这种两阶段的建模,第一阶段Network Embedding抽取出来的图表征,在某些下游任务上效果并不显著。因为Network Embedding的训练loss和下游任务的loss可能不对齐,这里存在的的gap使得特征在下游任务中的预测能力不佳。此外,微信的数据形态非常丰富,而Network Embedding无法做到图拓扑特征和节点属性特征的融合,但这又对我们的业务十分重要。

3. 端对端学习特征(18年-)

图片

在18年之后,微信团队将图表征技术升级至GNN。相较于Network Embedding的两阶段模型(无监督表达学习抽取图拓扑特征+拼接节点属性特征应用至下游应用模型),GNN是一个端对端的模型,它可以通过优化下游任务的损失函数自动融合图拓扑结构与节点属性特征。

4. GNN算法框架

图片

自18年开始,我们团队就开始GNN算法的应用落地,下面介绍一下GNN的算法框架。GNN算法的第一步是构图,我们可以根据具体的业务场景设计对应的图,比如它可以通过一些业务规则来去除噪声。完成构图之后,GNN使用聚合操作来将融合邻居节点特征,之后对聚合特征使用线性或者非线性变换,再与节点自身属性进行融合。简要来说,聚合相当于把节点邻居的特征抽取出来,进而在后一步与自身特征融合,最终使用融合后的表达进行下游预测任务。最后我们需要根据实际业务设计对应的损失函数。

这几步操作整体上构成了GNN模型的框架,其中最关键的是第二步的聚合和第三步的融合操作。不同聚合/融合的方式就形成了不同的图神经网络算法。比如GAT,它是使用attention机制进行邻居节点特征抽取,相当于去学习重要性较高的邻居并将其赋予较高的权重。又比如GraphSage,它除了可以使用Min、Max、Sum等操作以外,还提供了基于LSTM的聚合函数。对应地,我们也可以在第三步选择不同的节点特征融合方式。

02

GNN算法在社交推荐中的应用

1. 广告定向系统

下面重点讲一下近两年来GNN算法在微信业务上的应用,更多基础内容可以阅读《社会化推荐浅谈》。

图片

第一个应用是广告定向系统,对应着图上节点的分类问题。广告主会先给我们一批种子用户,我们需要从微信中找到与种子用户相似的用户进行朋友圈的广告投放。业内其他公司也会有相似的广告定向系统,他们的解决方案通常是将问题转化为一个二分类问题,即根据种子用户构建一个二分类模型(或者使用Pu Learning技术),去筛选出目标人群。但是朋友圈广告和其他平台有很不一样的特点。由于朋友圈是一个社交环境,大家在逛朋友圈的时候也会发现,如果有其他好友对广告有了点赞或者评论的话,可能会增加你对广告的点击概率,所以针对朋友圈广告的定向问题,我们将其转化为基于社交网络的图问题。

图片

以上图的例子,红色的点是广告主给我们的种子用户,种子用户的社交网络如上,那么我们的图任务就是去预测灰色的节点是否对广告感兴趣。在18年之前,我们会使用Network Embedding的方法提取拓扑结构,再加上用户节点本身的兴趣特征,建立一个GDBT的分类模型在线上使用。而现在我们建立了基于GNN的工程框架,可以直接使用GNN模型进行建模,将之前的二阶段框架整体替换做了升级。

GNN在广告定向上也有一些优化点,我们首先上线的是GAT模型,第二阶段的优化是在GAT的模型基础上追加特征交叉crossnet以增强用户广告兴趣特征的学习,另外我们针对种子用户少的广告进行了专项优化。

图片

我们第一版上线的GNN模型是GAT。GAT的聚合函数使用了注意力机制。这里按照之前展示的GNN框架来描述GAT模型的运行流程。首先针对构图操作,我们从种子用户的好友拉取关系链,形成一个用来建模GNN的底图。我们会进行采样操作,一方面是广告主有基础属性的要求,另外对好友关系链也利用业务的先验知识进行采样。第二步,GAT会使用基于attention的聚合操作抽取相似度更近的节点特征,再使用特征拼接的方法将自身特征与邻居特征进行进一步聚合。最后,我们采用半监督学习的方式,使用种子用户作为正样本。

图片

GNN的核心操作其实就是直接将邻居节点的兴趣特征与自身节点特征融合。但是,在广告推荐领域,用户对广告是否感兴趣更多是基于自身的兴趣,所以对用户兴趣标签的提炼尤为重要。所以,我们在GNN的基础之上引入了推荐领域常用的特征学习思路,即加入一个cross网络来提取用户自身的特征。通过Cross网络输出的交叉特征与GAT输出的特征进行拼接,我们相当于构造了Cross网络和GNN的双塔模型。这种建模方式进一步强调了用户兴趣特征的学习,从而提高用户对广告是否感兴趣的预测能力。

图片

另外,我们对小众的广告主进行了专项优化,对一些小众广告主他们提供的种子用户数量非常少。这就导致了CrossGAT会很容易出现过拟合问题。针对过拟合问题,我们融合了传统的网络科学里面最朴素的标签传播的思路进行了数据增强,即利用GNN消息传递机制来传播标签信息。具体到模型设计,我们在CrossGAT的基础之上追加了标签修正模型。如上图所示,P step相当于使用CrossGAT预测出节点对广告是否感兴趣,之后加入GraphSage模型进行标签修正,而GraphSage-mean可以看做是一个简单投票机制,即当好友的预测值与节点自身的预测值相近时,我们会将这个节点作为高置信度的样本追加到训练集中成为下一次迭代的正样本,从而形成了迭代循环,解决种子用户较少的问题。

图片

小结一下广告looklike业务中GNN算法的应用,在18年以前还是使用Network Embedding+XGB的模型。之后我们升级至GAT后,广告点击率和互动率都有一定程度的提升。然后,我们在GAT的基础之上增强了模型的交叉特征能力,对模型性能提升效果显著。随后,我们在面对种子用户较少的场景下引入传统的网络科学的迭代思路优化GNN框架,并利用标签传播补充正样本来解决这一问题。在种子用户较少的情况下,DualGNN的点击率和互动率的提升相当可观。

2. 社交召回-新业务冷启动问题

图片

去年,微信加入了直播这一新业务。在业务初期,很多用户没有直播行为,但是他们拥有非常丰富的社交数据以及文章阅读/短视频观看等兴趣类数据。在冷启动召回问题上,业界如抖音使用了大量头条的数据,相当于使用DNN做兴趣迁移,比如头条中用户的一个兴趣其实是可以用来预测用户在抖音的兴趣。对于微信来说,我们一方面想要有效利用平台数据,另一方面想要更加合理地针对数据进行建模。

图片

DNN算法的优势在于表达用户和商品之间的非线性关系,但是它忽略了用户、物品、属性的关联关系,所以我们尝试使用GNN框架对用户兴趣进行迁移。当然,我们的召回系统也会去使用DNN的算法,所以我们的工作是基于DNN召回的基础上追加GNN的召回,实现多路召回。

图片

我们还是根据GNN框架来介绍模型工作原理。第一步仍然是构图部分,由于直播推荐场景下节点包括用户,直播间、短视频、公众号文章的item等,我们的原始图是一张异构图。图的边可以是用户之间的好友关系,用户和直播间的观看关系,用户与短视频的观看关系,还有文章的阅读关系等。

GNN的召回还是遵循双塔结构,在用户塔我们会生成用户侧的metapath,例如比如item-user-user相当于把好友喜欢的物品推荐给我,属于社交关系的协同。又比如使用其他短视频行为或者文章阅读行为,相当于如果一个用户与其他用户在公众号上有比较多的共同阅读的话,两个用户之间的embedding也会非常接近,即embedding向量的内积较大。物品塔这一侧我们也会根据item-user-item的协同关系以及一些tag之间的协同关系建立metapath。

图片

图片

在用户塔这一侧,针对每个用户的单路metapath我们会使用单路注意力机制进行特征聚合,而针对最后多路metapath卷积信息的聚合,我们使用了pooling操作来生成最终的用户embedding。物品塔这一侧也使用了相同的机制。构建损失函数时,我们首先包含了推荐损失,即预测用户和物品直接是否有边的二分类损失,并采用时长进行加权。更进一步,我们借鉴了DNN序列召回的思路设计了加入了重构损失。例如item与item之间有共同观看用户,那么我们希望重构的图中两个item之间形成一条边。对于user和user之间,如果他们有共同观看的item,那么重构图中也应存在一条边。追加重构损失的目的是为了提升embedding的质量。此外,我们借鉴了多目标模型的思想,为每个损失函数赋予一个可学习的权重,并利用贝叶斯方法进行自动学习。

图片

总结一下,针对新业务新用户冷启动的双塔召回模型有以下几个要点。

  • 在构图时,我们可以在图中任意追加不同“域”的行为,使得模型有比较好的扩展性。我们可以在图中随时加入不同种类的协同关系,并为新的协同关系设计新的metapath即可。

  • 在推荐损失的基础上,我们追加了重构损失来提高embedding的质量。

  • 针对新用户召回,由于只有老用户才会有对应域的metapath。为了适应新用户模式,我们在模型训练时会以一定概率mask掉基于用户行为数据的那一路特征。

这一工作已经发表在KDD2020的会议上,针对每个设计的模块对应的效果提升在这里就不再展开了,论文中都展示了详细的数据。

图片

在多路召回中追加GNN召回后的系统在线上AB test的结果如图所示。消费类的指标较为小幅的显著提升,即点击率、用户在直播间的观看时长都有比较显著的提升。更加值得关注的是,针对新用户的次留指标,追加GNN召回后也有显著的提升。

03

GNN的实时训练和在线推理

图片

从整个场景出发,我们整个系统可以分为两个部分:图存储和计算框架。上图罗列了一些场景需求,其中对于图存储而言,最重要的是高可用性。在微信场景下,我们要求五个9的稳定性,而相对地,对于数据并不要求强一致性,只要求最终一致性。除此之外,图存储还需要支持快速扩容能力。在系统的另一个部分——计算框架,相对于高性能、我们更关注开发的便利性,模型上线时不需要做额外的开发,保存的模型可以通过标准tfserving服务便可以直接部署至线上使用。如此上线模型,还能通过tensorflow的原生功能保证线上推理和线下训练的逻辑一致。

图片

我们整个系统的设计如上图所示。图存储是基于微信的Mkv/Fkv做的扩展。微信的KV支持通过Web Assembly技术,在存储端执行用户自定义逻辑。开源的Redis也支持类似的扩展方式,其他公司的同学也可以尝试使用这类方法来快速的扩展传统 KV 成为图存储。基于KV开发的好处在于微信的KV已经服务了非常多的业务场景,它的稳定性与性能都是非常有保障的,满足线上7*24 不间断服务的要求。在计算框架方面,我们选择了以静态图版本的Tensorflow为基础,扩展图操作和图卷积算子支撑实时图学习算法。

图片

下面介绍一下如何在KV上扩展图存储的支持。其中的难点在于如何在以Key Value的形式去存储图的拓扑结构。目前存在2种常见的方法来存储图拓扑结构:

  • 将一个顶点的所有邻居存储至一个键值对中,这种方式的查询效率较高但是插入性能较低(针对全内存存储而言),因为每次插入一条新边需要读写整个Value;

  • 另一种方式是对于每条边都建立一个键值对进行存储,这样的好处在于插入效率比较高,但是在做邻居节点采样时的查询效率较低。

而我们最终采用的方案是两者的折中,即将一个节点的所有邻居划分成大小相等的N个块进行存储。这样的方式平衡了插入和查询的效率,同时相对于存储每一条边的键值对信息,我们还减少了数据库中键值对的数量,降低了存储的压力。

图片

有了图结构存储的基础,我们还在此之上针对图学习算法定制各种索引结构来加速采样操作,最终使其推理时延达到在线服务的要求。配合图存储,我们开发设计了一套图查询的接口,其基于Tensorflow Resource接口实现。为了最大化性能,在训练阶段,我们结合Tensorflow-Dataset做子图并行预取,提升吞吐;在推理阶段,配合属性的Cache、子图Cache以及部分图查询操作的融合,降低图查询耗时,压缩推理时延。

图片

如果仅仅使用Tensorflow的数据结构和算子其实是不能高效的执行图卷积操作的。因为Tensorflow中使用的稀疏数据结构是COO,它对一些图操作并不高效。例如我们想得到一个顶点的所有邻居,这种类型的操作就比较低效。所以,我们针对图学习的场景定制了CSR、CSC的数据结构,并且配合这两种数据结构定制了专用的算子库,结合一些计算优化技术来提升整体的计算效率。

图片

对于在线推理,因为整个系统是基于Tensorflow的,所以整个过程会较为简单,其上线方式与经典的DNN模型是类似的——即使用Tensorflow进行在线训练,训练完成之后定期(或者配合一个在线PS服务实时的)把模型参数导出至线上。在线的模型服务就从模型存储里拉取最新的模型,便可以对外提供服务。这里唯一的不同点在于我们增加了一个图存储。为了达到数据实时性和一致性的要求,图存储会从消息队列接入增量的图数据,并24小时不间断地更新存储。此外我们增加了一个图存储接口层,其目的在于预防突发性的写请求直接冲击图存储,影响线上推理的稳定性。

04

精彩问答

Q:一张图需要占多大的内存,能否使用Redis存储?

A:根据我们的经验,我们做过含有千亿级别的边、十亿级别的点的图,单副本占用的存储空间约为2~3T。但是我们的存储不只限制于内存的形式,对于超大图我们还是使用磁盘。我们的微信kv是基于磁盘的。

Q:CrossGAT只是运用了DCN网络结构,而DCN本身结构对图任务看上去没有什么增益。请问是否运用了其他trick?

A:CrossGAT相当于一个双塔结构,我们追加cross网络的目的是为了利用特征交叉学习用户自身的兴趣特征。因为GAT的作用是将邻居节点的特征利用attention机制聚合至中心节点上,导致其更多得偏向图的拓扑结构特征。加入cross网络的输出特征并将其与GAT输出特征拼接在一起,在推荐场景下相当于融合用户的社交特征和自身兴趣、属性特征,进而使得最终的Embedding相较于GAT对用户有了更加个性化的表达。

Q:GAT 模型的负样本在广告定向应用中应该如何选取?与种子用户相邻的用户会不会作为负样本?有没有比较好的邻居采样的方法?

A:我们负样本的选取还是使用Pu learning的技术,它是一个半监督学习的思路。负样本可以随机选,也可以使用Pu learning根据学习的模型从得分比较低的样本中采样负样本,并进行迭代。针对邻居采样的算法,我们在更多情况下会采用业务规则去做。比如对于广告业务,我们会去计算两个好友之间历史的共同感兴趣的广告数,它可以作为比较强的业务规则来指导邻居采样。从算法上来说,我们可以使用attention机制,也可以使用自适应的邻居采样算法。我们团队在采样算法上正在做一些预研,目前还没有上线。

Q:目前有一些比较新的工作,他们引入元路径或者基于自监督学习来训练图模型,这些模型在实际落地时有什么困难?

A:我们针对异质图的图模型使用了metapath进行特征学习,而在广告定向业务中由于用户社交图是一个同构图,我们不需要使用metapath便可以学习图拓扑结构特征与节点特征。针对落地的问题,比如直播推荐中我们使用了基于metapath的异构双塔图网络模型。我们实际在落地应用时遇到的问题不是算法本身,而是图的规模导致查询操作在图引擎中出现一些性能问题。而这类问题对不同的算法其实是相通的。

Q:请问离线数据时怎么输入图存储的?离线流量怎么做隔离?离线数据需要保存多久?图存储支持点、边属性多版本回溯吗?

A:离线数据灌入图存储的方式其实就是写一个工具去输入就行了。离线流量的隔离本身就是kv的一个基本能力,即读写分离。因为在线服务基本上都涉及到读操作,更新图的时候kv保证读写分离就不存在冲突问题。离线数据的保存时间一般看业务场景,比如直播这种场景实时性比较强,保存一个月的数据就足够了。针对多版本回溯问题,我们暂时没有考虑过。

今天的分享就到这里,谢谢大家。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多