社群推荐算法在腾讯游戏的实践

人工智能 算法
社交网络的定义是由节点(个人)和节点之间的社会关系(亲人、同事、朋友等)组成的网络结构。社交网络中的节点通常就是独立的个人,部分节点集合构成社群,一个社群通常由联系紧密的人组成,社交网络中通常有多个社群。

本次分享的题目是社群推荐在腾讯游戏中的应用。第一部分将回答什么是社群推荐,为什么要进行社群推荐,以及如何进行社群推荐。第二部分将讲解如何解决社群推荐冷启问题,我们提出了一个自适应的社群检测算法,相关论文已发表于 KDD 2024。第三部分将介绍一个有约束的社群推荐算法,主要解决腾讯游戏社群推荐数据稀疏的问题,相关论文发表在 KDD 2023。最后一部分是对我们团队的简单介绍。

一、社群推荐简介

1. 社交网络中的社群

社交网络的定义是由节点(个人)和节点之间的社会关系(亲人、同事、朋友等)组成的网络结构。社交网络中的节点通常就是独立的个人,部分节点集合构成社群,一个社群通常由联系紧密的人组成,社交网络中通常有多个社群。

图片

2. 为什么需要社群推荐

再来简单介绍下社群推荐任务的 motivation,我们希望通过社群推荐方式,为游戏内玩家推荐合适的社群,从而提升游戏内用户活跃度和付费率。

研究表明,游戏社交网络中的社群其实是游戏社区繁荣的体现,游戏社群对提升玩家付费活跃有正向作用。举个简单例子,同一个社群内玩家可能有高活跃度玩家,也有低活跃度玩家,他们都在一个社群就会产生一些交互,比如对局、组队等行为。通过社群内玩家的交互,可以使高活带低活,从而提升社群内玩家总体活跃度。

下面两幅图展示的是有社群玩家和无社群玩家的付费率,以及他们的游戏时间。可以发现有社群玩家游戏时间和付费率远高于无社群游戏玩家。所以我们希望通过为这些无社群玩家推荐社群,鼓励他们加入社群,来提升最终社群内用户活跃度和付费率。

除此之外,需要社群推荐还有一个原因,游戏内社群数量非常庞大,我们的一个游戏可能有几百万甚至几千万的社群数量,用户在真实情况下去选择想要加入的社群时,就会存在信息过载的问题。因此我们希望用 data-driven 或者 model driven 方法,去为每一个玩家挑选推荐更适合以及更可能加入的社群。

图片

3. 在腾讯游戏中应用社群算法

社群推荐面临诸多挑战。首先,游戏内用户和社群的交互极其稀疏。在极端情况下,比如游戏产品刚刚上线,可能大部分用户都没有跟任何社群交互过,对社群而言,里面存在的玩家数量非常少,在这种冷启动的情况下我们会结合一些社群发现算法通过 unsupervised learning 方式给玩家推荐一些潜在社群,推动玩家去构成一些新社群。

除此之外,游戏社交网络也是一个典型无标度网络,其规模非常巨大。在不同场景下,社交网络规模可能是几亿甚至十几亿节点的超大规模图。如何把 graph learning 的方法用到真实世界巨大规模的图上也是一个很有挑战性的事情。

这里就介绍一下我们怎么样在真实的腾讯游戏应用场景群中用社群推荐算法。首先给定一个游戏社交网络节点,玩家边代表玩家间的交互。社交网络是社群推荐算法的输入,我们通过算法和 data-driven 方式去挖掘关系紧密以及兴趣相似的玩家群体。然后给他们推荐相应的社群,或者鼓励他们去形成新社群。

在这里我们列了两个应用场景,一个是腾讯游戏中话题圈子推荐。顾名思义,话题圈子和社团其实都是由一部分玩家、一部分用户去所构成的子群体,我们要以一个群体为单位,将其当作一个 item 去推荐给不同的玩家,来鼓励他们加入到对应圈子或者社团中。

除此之外,还有好友和组队推荐等场景,我们也倾向于给同一个社群内的玩家去推荐好友,鼓励他们完成一系列组队或对局等活跃任务,通过社群内玩家高活拉低活的方式,提升社群内总体用户活跃度。

图片

接下来将具体介绍我们研发的两个社群推荐算法。

二、自适应 K-Free 社群检测算法

1. 真实业务痛点

首先是自适应 K-Free 社群检测算法,我们的目标是发现社交网络中潜在的社群,从而解决社群推荐冷启动问题。

在设计算法之前,我们首先对真实业务中遇到的痛点问题进行了抽象,将其形式化为科学问题(算法问题)。

社群检测算法在业务场景中的两个痛点为:

  • 兼顾社群的语义属性(玩家属性: 玩法偏好,付费,活跃......),网络结构(好友关系链的紧密程度)
  • 确定社群的数目和分布

当前算法无法同时解决两个痛点。传统算法(如 Louvain)不需要社群数目先验,但是无法感知节点和社群的语义属性。深度学习算法(深度图聚类)可以联合学习语义属性,但需要社群数目先验。

图片

这两种算法都没有办法解决我们的业务问题,所以我们提出了 K-free 社群检测问题。这个问题就是在真实社群数目 k 未知的前提下,挖掘同时有网络结构信息和语义结构特点的社群结构。

图片

以传统的算法为例,其优化目标为模块度,即社群网络结构的紧密程度,以模块度为目标优化出来的社群,其实是同一个社群内连边尽量稠密,社群间连边尽量稀疏。

但我们只考虑模块度指标是不够的,还要去考虑一些语义的 semantic 指标。比如衡量社群内节点语义属性的相似性,也有一些算法去针对这些指标做一些单独的优化。同时我们在真实社群中往往要权衡两类优化目标,正所谓物以类聚人以群分,我们希望最终的社群 modularity 和 semantic 指标都高。

图片

我们在真实实验中发现,像 Louvain 这种算法检测出来的社群数量比真实数值要高很多。比如左边这张图,我们以图上节点分类数据集为例,coral 数据集,我们发现它真实类别数是 7,但是如果用 Louvain 算法划分社群则能分成 105 个,远高于我们真实想得到的理想 k 值。但用 k-means 的话,虽然能刚好分成 7 个 cluster,但是它的 modularity 又非常低,可能仅仅是语义程度上相似,但是结构上完全不相似(图上距离非常远)。

图片

也有一些方法是用了现在比较火的图神经网络这种深度学习方法去做深度图聚类,图神经网络是聚合图中邻居信息,来更新当前节点的表示,这一方式可同时进行图上结构和属性信息的联合学习,虽然解决了痛点一,但有一个限制,它要跟现有的聚类方法结合,比如像 k-means,要有一个先验 k。真实业务情况下,我们不知道 k 到底是多少,所以这类算法实践起来会有一定困难。

图片

那么一定要有 k 吗?如果把深度图聚类中 k-means 聚类换一种聚类方式,比如密度聚类 DBSCAN 是不是就可以了呢?我们通过真实实验发现这其实是不可以的,因为 DBSCAN 也有一些比较强的先验参数,像搜索半径,而且它真实划分出来节点的一些特征空间分布会有一定崩溃问题。比如像下图展示的,Coral 数据集其实是有 7 个真实类别,DBSCAN 容易将其划分为 3 个 cluster,并不是理想的情况。

那么使用 k-means,通过遍历 k,选模块度最高的 k 是不是就可以呢?这是可以的,但它的缺点就是比较低效。首先我们要确定候选 k 的搜索范围,再去穷举或者搜索尝试,因此比较低效。

图片

既然这些方法都没有办法同时解决我们的痛点问题,我们就希望通过联合学习的方式,既兼顾特征与结构与语义信息,同时又自适应地确定划分社群数量。我们提出了深度自适应的生成式的 K-Free Community Detection 算法,简称 DAG。

DAG 主要由两个模块构成,这两个模块分别解决了前文的两个痛点。

  • DAG 首先用 Mask AutoEncoder (MAE) 作为节点 embedding 模块,并通过预训练模型让节点 embedding 包含自身拓扑邻居的语义信息。这解决了痛点一。
  • DAG 用 Community Affiliation Network (CAN)建模社交网络的生成,这样无需聚类,直接得出每个节点社群 id,在此基础上,DAG 将搜索 K 转化成了可微分的社群选择。这解决了痛点二。

图片

接下来详细介绍一下这两个模块是怎么工作的。在预训练阶段我们会用 mask attribute reconstruction 链目标,随机采样一组节点,将对应属性替换为 mask token。然后通过 graph auto encoder 将其解码,得到重建后的 attribute,使重建后的 attribute 和真实未 mask 前的 attribute 尽量接近。

第一步输入一个 input graph 即临界点矩阵 A,以及图属性矩阵■(~@X)。第二步随机 mask 一组 NODE 的对应属性,然后输入到 GNN encoder 里,再经过一层二重 mask,得到基于 mask 特征的节点表示。第三步通过 GNN decoder 得到重建后属性表示,最后计算 construction loss,这里是通过 GNN 聚合邻居消息的方式去恢复某节点被 mask 掉的属性信息。

图片

通过预训练 loss,我们既捕捉了节点的结构属性,又捕捉了节点的语义属性。接下来我们通过 readout 函数将节点划分成合适 k 值,通过 readout 函数得到每个节点对应的社群 ID,readout 是一个神经网络,它的输出是一个高维稀疏向量。这个高维向量里面只有稀疏的 k 个维度被激活,这 k 个维度对应该节点属于的社群。

如何保证模型训练得到高维稀疏矩阵的同时又能学到社群数量呢?

我们通过链路预测任务去捕捉网络中的结构属性,计算节点的 BPR loss,从而让网络中相邻的节点 embedding 更接近,不相邻节 embedding 会更远一些。

图片

介绍到这里,这个 loss 其实只能得到一个效果,就是让这个 community application 的 result 函数进一步得到图结构的信息。

但如何保证稀疏性呢?当 k-searching 搜索社群数量时,加入一组稀疏约束。通过 readout 函数输出的是每一个 NODE 属于的社群 ID 向量。我们会对这个向量做稀疏约束,比如对列做 L2 norm,同时对行做 L1 norm,L1 norm 是很强的吸入性约束。这样输出的 ID 向量分布概率在某一维比较大,其他维比较小,是一个横向稀疏向量。同时我们在列方向加 L2 norm 稀疏性约束,这会使得 readout 函数输出比较高维向量,但其实只有少数 k 维度对应的社群 ID 激活值比较高。

这样我们就无法把确定属性节点应该被划分成多少个社群的一个 case,通过稀疏约束方式,得到 readout hold,这个节点所属的授权 ID,同时保证社群数量适中,最终要保证预训练 loss,以及社群隶属 readout 函数 BPR loss 都比较低。再配合组稀疏 loss 就可以自适应地得到 k 个社群。

图片

除了模型外,我们还提出了社交网络划分社群质量的评价指标,称为 EDGE Metric。这个指标解决了传统指标例如 modularity、模块度或者语义相似性难以衡量网络结构和语义相似度的权衡。我们在原始论文中也做了一系列 theoretical 和 empirical study,去支撑指标的优势。

在真实的评估过程中,用户真实社群标签是未知的,训练虽然是 unsupervised learning,但评估其实还是需要用到少量人工标注的真实标签作为 Label,当标签比较少时,现在常用的解决方法可能是把一些分类数据集里样本的类别当作社群标签。

图片

我们发现在曝光转化率这个线上指标上,我们的 model 相比于 baseline 提升大概在 4% 到 9%,像 DGC model,它的提升就比较一般,甚至产生了负向增益。而我们的模型有着比较稳定的提升。

图片

三、有约束的大规模社群推荐算法 ComRec

我们想解决的另一个问题,就是在不知道社群数量k 的情况下去划分适当数量的社群,同时兼顾结构和语义属性。服务的场景为,针对一些刚起步不久的腾讯游戏做冷启动的社群推荐时,可以无监督地发现一些社群。但如果游戏已经是比较成熟的产品了,已经积累了一定用户和社群 item 的交互历史,利用这部分信息再结合一些传统推荐算法,可能会达到更好效果。基于此 motivation,我们又进一步做了有约束的大规模社群推荐算法 ComRec。这篇 paper 也同样发表在 KDD 会议上。

游戏场景中社群推荐约束问题中的约束该怎么理解呢?

不同于传统社群,社交网络中社群,每一个用户在同一时刻只能加入一个社群,也就是说他不能同时加入两个社群。在传统的社交网络里,一个用户可能是属于多个社群,不同社群之间存在 overlap。但在我们的 problem setting 限制下,有很强的 Constraint,用户在同一时刻只能在一个社群里面,用户只能从一个社群退出后,才能加入另一个社群。

社群推荐场景主要有两大挑战:

  • 交互数据稀疏:极度稀疏的 user-item 交互数据
  • 社群信息受限:游戏内社团没有额外的 side information,传统的推荐 item 可能有很丰富的 side information,比如 title description 或非结构化信息商品图片等。

图片

我们的社群推荐算法主要分为三个模块,一是标签模块机制-labeling agenda,它描述的是约束,同一个 NODE 在同一时刻只能加入一个社群。除此之外我们通过一个图神经网络模块去得到对应的 user item 表示。为了兼顾大规模图上的信息,及局部社群推荐,我们做了一系列的优化,将其分成了 global propagation 和 local propagation。

图片

社群标签机制是我们要用向量表示节点,它是否属于某一社群是比较简单的表示方式,比如有 k 个社群,就用 K 维 one-hot 向量表示该节点是不是属于其中一个社群。但是这样会有一个问题,我们的社群可能是百万甚至千万级别的数量,one-hot 向量维度会很高,会给模型 learning 过程造成困难。在实际设计中我们做了一定的约束放松,只会维护一个一维标签标注 NODE 是不是隶属于某一社群,而不区分它具体属于哪个社群。

基于 label 机制,我们的核心目的是希望标注 NODE 是否属于某一社群,还是不属于任何社群。我们要进一步思考图神经网络是如何做消息传递的。传统的图神经网络在做消息传递时,每一个节点在每一轮更新都会聚合所有邻居信息,把邻居信息特征聚合后,通过一个图卷集合,比如均值聚合得到一个向量,下一步就是通过聚合后的信息去更新当前节点向量表示。但在我们的 setting 下,面临大规模图挑战,同时需要做社群推荐,因此我们希望同社群内节点的表示更接近。

图片

我们的做法是,将其分成 global feature propagation 和 local feature propagation。Global feature propagation 是 column-wised propagation,比如维护一个 nd 维用户 feature embedding 表示矩阵,要在 column 维度上做一个 propagation,不同于传统的图神经网络,每一次都会用所有邻居特征更新所有节点。我们做了一系列优化,把原本 n^n 的复杂度变成了亚线性。

图上节点不是每一轮都会更新节点表示,而是会有一定延迟,我们的更新机制是每一个节点在累积接收 message 到一定程度下,才会去更新节点表示。在具体实现上,考虑到我们是应用到一些工业场景,核心的计算代码是用 C++ 实现的,这提升了很多效率。

最终效果,在 2000 万节点的图上,只需要 30 秒就可以完成一次快速计算。除了通过 global propagation 在整个图级别捕捉邻居节点信息和结构信息,以及结邻居分布的语义信息,还通过 local propagation 进一步增强社群表示,因为我们的模型是用来做社群推荐的,社群其实是一个子图,local propagation 可以理解为是一个 subgraph 级别的 propagation,下图红圈圈出来的节点属于同一个社群,我们就在同一个社群里进行消息传递,或者说进行 feature 的平滑,让同一个社群节点 feature embedding 更加接近,相似度更高。属于不同社群的节点,相似度更低一些。

通过分阶段 propagation,我们在兼顾高效率的同时增强了社群信息的语义结构学习。

图片

我们在大量数据集上进行了实验。首先是离线数据集的 setting,我们在四个腾讯游戏的内社交网络数据集上做了实验,这几个数据集都是百万节点及千万节点边的 setting。同时我们也对比了像传统的网络嵌入方法 (network embedding),以及仅使用属性特征的像 MLP 推荐模型,特征交叉的 learning model AutoIntCL,还对比了一些基于频率的协同过滤推荐算法,比如 LightGCN 和 LightGCN-E,以及 social recommendation 的 model,比如 GraphRec。

图片

最终 ComRec 相比于 baseline 方法都有 3.5%~5% 以上比较可观的提升。模型的离线效果是通过 hit rate 和 NDCG 等一些排序指标进行评估的。

图片

我们也把模型部署到了真实线上环境-游戏内社群推荐。真实世界中图的规模是比较大的,其中有 2000 万节点,28 万社群数量,1.6 亿条边,我们在这样一个大规模图上去进行线上实验,评价指标也换成了线上评价指标。比如 user item 点击率,以及把社群列表曝光给玩家之后的曝光通过率,即玩家点击社群,然后申请加入社群的比例是多少。我们的模型在线上指标上相比于 baseline model 也有着比较可观的提升。同时我们也对比了不同模型的运行时间,我们的模型在保留了更好的推荐效果的同时运行时间也是最少的。

感兴趣的同学也可以搜索我们的论文,相关代码也是开源的,欢迎大家来与我们做进一步交流。

图片

四、About Us

最后简单介绍一下我们的团队。我们是腾讯互娱 CDP 数据科学中心社交算法组,致力于研发高效且有效的社交网络算法和技术,通过挖掘海量图数据服务于游戏社交推荐的相关场景,比如前文中介绍的战队推荐、社群推荐、游戏内好友推荐,以及社交传播影响力最大化和社交营销等多种场景,希望助力于游戏场景提升用户活跃度和付费率。欢迎感兴趣的同学加入我们来共同探索社交算法在腾讯游戏中的无限可能。

图片

五、Q&A

Q1:第一个算法聚类是 unsupervised 聚类还是 supervised 聚类?

A1:第一个算法是 unsupervised 算法。我们第一阶段的优化目标,是 feature reconstruction 优化目标,也就是只需要知道节点的特征,我们是没有任何的节点标签的,优化目标其实是纯无监督目标。

第二阶段社群隶属模块 learning 部分,它的一部分优化目标是 link prediction,即拿到一个图结构后 mask 其中一部分 edge,然后预测这些 edge 存在的概率,也可以认为是一个 unsupervised 的过程,这个过程是 Nodewise 任务,但是并不涉及任何 Nodewise 标签,后面加入的 group sparsity 约束,是在 learning 出来的 representation 矩阵上做稀疏性约束,只需要算 L1 norm、L2 norm 和 optimization 相关 loss。整体算法流程是 unsupervised 过程,最终应用也是在无监督场景解决一些冷启问题。

Q2:前面提到的 BGC 算法能否用异质图解决?

A2:当然是可以的。像 DGC 算法,它是先通过图神经网络去学习节点级别表示,每一个样本都有对应向量,基于向量再去做聚类,比如通过 k-means 聚类成 k 个 cluster。我们真实的业务场景中是一个异质图,可能是多关系网络,只需要改变前面 encoder 模块,如果网络关系是同质图就选择同质图 GNN,如果是异质图只需换成 heterogeneous GNN。

后面聚类时,因为 heterogeneous graph 可能会存在多种类型节点和边,可能只能锚定其中某一类型节点,比如用户节点,在用户节点表示上做聚类,更准确地说是在同种可比的类型节点上做聚类。同质图和异质图不同就是 encoder 以及最后聚类逻辑上会有一点不同。

Q3:预训练任务和真实推荐任务是否有偏?

A3:预训练任务和推荐任务确实有偏差,比如像 DAG 这篇 paper,我们主要解决的是冷启动问题。当我们没有 user item 交互历史的时候,我们没有办法根据他的历史交互序列去精准捕捉用户意图,但是我们知道一些其他信息,比如用户在社交网络里亲密关系信息、他在具体下游任务当中的亲密关系。我们可以通过这些信息弥补这种偏差。但如果要完全消除这种偏差,后面介绍的 ComRec 算法还是要利用用户历史的 community 的交互序列,根据他的历史交互行为才能更精准刻画用户对社群偏好程度,才能做完全无偏推荐。

责任编辑:姜华 来源: DataFunTalk
相关推荐

2024-08-12 09:41:18

2019-04-09 15:02:36

OpenResty腾讯游戏营销技术

2015-06-11 10:09:04

大数据HBase

2015-12-01 14:51:43

2023-09-11 07:40:53

2024-10-16 20:31:25

2022-10-28 09:15:02

2022-10-28 08:31:43

2024-06-26 19:18:53

2019-07-10 14:22:50

存储

2023-07-26 07:51:30

游戏中心个性化

2024-09-11 19:36:24

2023-10-11 07:20:17

2015-09-23 10:25:41

Docker英雄联盟Docker实践

2023-02-20 13:45:31

数据分析腾讯 Alluxio

2023-06-28 07:28:36

湖仓腾讯架构

2017-05-10 16:01:39

推荐系统算法实践

2016-09-30 15:03:13

推荐系统算法

2013-07-24 10:10:08

2023-07-19 08:55:00

神经网络推荐系统
点赞
收藏

51CTO技术栈公众号