图片来源:https://unsplash.com/photos/Q...
作者:左冯翊
一、项目背景
云音乐依托音乐主站业务,衍生了不少创新业务。不管是音乐、直播还是播客等业务,都面临着如下两个冷启动的问题:
- 如何为新用户(或不活跃用户)分发内容
- 如何将新内容(或冷门内容)分发给用户
每个业务都沉淀了一些解决冷启动的方法,比较常见的一种方法是引入用户在其他场景的行为数据,比如在直播冷启中,我们会引入用户对音乐的偏好。
随着业务的不断发展,越来越多的场景希望能有一种效果比较好、开发成本低、通用性比较强的方案适用于解决云音乐各业务早期和中期的冷启动。
我们调研了冷启动的多种解决方案,如跨域推荐、新老用户分层、元学习和关系链传递等。 最后发现基于关系链的传递比较适合做成一种通用的基础方案,而且不少互联网产品(如微信视频号、拼多多等)也将其作为一种重要的冷启动方法。
但是云音乐没有显性的好友关系链,应该怎么做呢?隐性关系链就在这样的背景下诞生了。
那怎么构建用户的隐性关系链呢?
云音乐以泛音乐内容为核心,通过内容连接人与人,用户基于内容产生了一些行为偏好。那么,我们可以通过综合使用用户在云音乐各核心业务场景的行为数据(考虑到用户隐私和数据安全,相关数据均做了脱敏处理,后续文章提到的用户相关数据,不再特别注明),来学习用户的向量表示,然后基于向量的相似度,来刻画用户的隐性关系强弱,一方面能获得用户的一些偏好表征,另一方面也进一步对用户的隐私进行了脱敏。
基于以上背景,本项目的主要目标是通过融合用户在云音乐的全生态行为数据,来学习用户的向量表示,从而构建用户的隐性关系链。基于隐性关系链,实现不同的下游推荐任务,如用户冷启、内容冷启、相似召回和种子用户 Lookalike等。
二、项目挑战
项目遇到的挑战主要有:
第一、数据规模大
数据规模大主要表现在3个方面,业务多、场景多、用户交互行为类别多。
针对这个问题,我们对各业务数据情况做了一个摸底,这些用户行为数据的总量是很大的。综合考虑模型训练效率和用户兴趣的时效性等,我们也没有必要使用全量的数据。因此,我们对业务数据做了两方面的处理:
- 使用业务的核心数据。比如在音乐这个业务,我们使用脱敏后的用户音乐偏好行为
- 对数据做了一些脱敏、清洗、限制和过滤等,有效减少了数据量级
通过以上的一些处理,我们得到了一份质量比较高的用户行为数据。
第二、如何建模
用户的隐性关系链,不是一个具体的业务场景,缺乏明确的 label,也缺乏明确的优化目标,因此我们不能直接使用业务中的排序模型进行建模。另外,用户的行为高度异构,由用户和内容(指歌曲、直播、播客等)构成的图就是异构的,并且不仅包含异构的节点(用户和多种内容),而且包含异构的边(用户和内容的多种交互行为,比如点击、播放等)。
针对如何建模这个问题,我们将在第三部分进行重点介绍。
第三、如何评估
前面说到,我们不能直接使用排序模型,也就意味着我们不能直接使用 auc 等排序指标。通过分析和调研,我们综合使用以下几种方法进行评估:
- 定性评估
- case 分析。这种方法通过分析用户行为序列的交集个数或者 Jaccard 系数等,来判断关系链是否靠谱。这种方法比较直观,也具有一定的可解释性。但其实也存在一个问题:如果模型判定两个用户的相似度是 0.8,他们的行为序列重合度是否就很高?不一定。比如,用户 A 对歌曲 S1 和 歌曲 S2 有红心行为,而用户 B 对歌曲 S3 和 S4 有红心行为,且这几首歌曲是比较相关的歌曲(比如这几首歌曲经常出现在很多其他用户的行为序列中,或者来源于同一个艺人等),尽管他们的行为没有交集,我们也可以认为这两个用户的兴趣是有相似之处的。
- 可视化分析。我们得到了用户的向量表示之后,可以通过 TensorFlow 的 Embedding Projector 等工具对 Embedding 进行可视化,然后观察具有相同标签的用户是否聚到了一起,标签重合较少的用户是否是分开。
- 定量评估
- 上线实验。通过 u2u、u2u2i 等方式进行召回上线,根据线上收益进行评估。这种方式比较直接,置信度比较高,但实验成本也较高,应该先进行离线评估再确定是否上线实验。
- 离线评测。把用户向量当成特征,输入到排序模型中,评估离线 AUC 或者 loss 等指标的收益;或者离线生成 u2i 的推荐列表,然后评估召回的精确率和召回率等。这两种离线评测方式相对上线成本低一些,虽然不是直接对 u2u 进行评估,但也是一种可行的方法。
第四、如何对外提供服务
用户的隐性关系链,是一个基础建设,为了方便各业务场景能快速接入,我们需要做成一个在线服务,其中就涉及到一个问题:亿级别用户向量如何进行毫秒级相似检索?
云音乐参考业界的一些向量检索引擎框架(如 Faiss、milvus 和 Proxima 等),自研了 Nsearch,实现了大规模向量的高性能相似检索,支持高并发低延时、算法复杂动态扩展和增量导入等。
另外,为了支持不同业务场景定制需求的能力,我们也设计了一套比较好的服务架构,面向业务提供统一接口,支持快速接入、迭代的能力。
关于提供对外服务这个问题,我们将在第四部分重点介绍。
三、技术演进
为了构建用户的隐性关系链,首先我们需要生成用户的向量表征。为此,我们调研和实现了多种算法,在多个业务场景上进行了良好的实践,也进行了许多有益的尝试。
如图所示,我们将调研过程按技术深度和建模方式分为 5 个阶段:
第 1 个阶段是摸索阶段,我们调研了 SimHash 算法。SimHash 算法其实是用于计算文本间的相似度,在我们这里,就是把用户的行为序列看成一段文本。
第 2 个阶段是起步阶段,我们调研了 item2vec 模型。item2vec 来源于 word2vec,它的基本原理是最大化出现在中心词附近的那些上下文词的共现概率。
第 3 个阶段是探索阶段。我们在 item2vec 上面做了一些优化,比如将全局负采样改为约束负采样,将 user_id 作为 global context,这些优化可以进一步增强向量的表征能力。
第 4 个阶段是发展阶段。我们调研了异构图模型 metapath2vec,它可以对多种实体关系进行建模,泛化性比较强。
第 5 个阶段是创新阶段。原始的 metapath2vec 没有添加 side information,泛化性能还不够强,因此我们正在做一些改进与优化。
下面,我们主要介绍下 SimHash、Item2vec 和 MetaPath2vec 。
SimHash
SimHash 算法用于计算文本间的相似度,它是 Google 用于海量文本去重的一种算法,也是一种局部敏感哈希(Locality Sensitive Hashing)算法:两个字符串具有一定的相似性,在 hash 之后,仍能保存这种相似性。
SimHash 的基本原理是将原始的文本映射为 n 位的二进制数串,然后通过比较二进制数串的汉明距离(Hamming distance)来度量原始内容的相似性。它的基本步骤如下:
- 关键词抽取。将 Doc 进行分词,去掉停用词,然后为每个词赋予一个权重(比如该词的出现次数或者 TF-IDF 值等)。
- Hash。通过 hash 算法把每个词映射成 hash 值(二进制串)。
- 加权。按照词的权重计算词的二进制串的加权,1 的位置乘以权重,0 的位置乘以权重并取负。
- 合并。把各个词算出来的加权序列值累加,变成一个序列串。
- 降维。把合并得到的序列串转换成 01 串,即为最终的 SimHash 值。转换规则:如果该位的值大于 0,则取 1,小于 0,则取 0.
如图,是一个简单的示例:
因此,经过 SimHash 算法处理后,一个文本字符串就变成了只有 0 和 1 的数字串,然后再通过汉明距离来判断两个文本的相似度,一般认为汉明距离小于 3 的两个文本是相似的。
那么,我们如何用 SimHash 来构建用户的隐性关系链?事实上,我们通过一些规则来聚合每个用户在各业务场景的行为序列,以此得到每个用户的 id 序列,把每个 id 当成词,然后赋予每个 id 权重,便可以依据 SimHash 的算法流程得到每个用户的 SimHash 签名(只有 0 和 1 的数字串)。
看起来,我们的问题已经解决了。然而,在实际应用过程中,我们要检索一个用户与哪些用户是比较相似的,如果和全库的数据做比较,那效率是很低的。这里,我们为每个用户生成了 64 位的 01 串,那么可以将构建隐性关系链这个问题抽象为:
假设有 10 亿个不重复的 64 位的 01 串,给定一个 64 位的 01 串,如何快速从这 10 亿个串中找出与给定串的汉明距离小于等于 3 (比较相似)的字符串。
如何实现高效的检索呢?我们可以将 64 位的 01 串,分为 4 个 16 位的段,根据抽屉原理,如果两个字符串是相似的(汉明距离在 3 以内),那么它们必有一个段是相等的。
基于上述思想,我们可以这样设计检索流程:
入库:遍历全量的 SimHash 指纹,对于每一个 SimHash 指纹,执行如下步骤:
1)将 64 位的 SimHash 指纹拆分成 4 个 16 位的段
2)将每个段通过 kv 数据库或者倒排索引存储,比如段 1 存储到库 1,段 2 存储到库 2,让 key 为 16 位的 01 串,value 为 key 相等时的指纹集合- 检索:对于需要检索的 SimHash 指纹,执行如下步骤:
1)将 SimHash 指纹拆成 4 个 16 位的段
2)分别将每一个段去对应的数据库进行等值查询,根据上面的抽屉原理,查询到的即是疑似相似的指纹
3)把待检索的指纹和疑似相似的指纹进行汉明距离的比较,即可判断是否相似
整体流程可以表示成下面的图:
假设全库有 2^30(约 10 亿)条数据,假设数据均匀分布,则每个 16 位 (16 个 01 数字随机组成的组合有 2^16 个) 倒排返回的最大数量为 2^30/2^16=16384 个候选结果,4 个 16 位,则总共候选有 4*16384=65536。因此,通过上面的入库检索流程,原来需要约 10 亿次比较,现在最多只需要 65536 次即可得到结果,大大提升了检索效率。
SimHash 是我们调研的第一种算法,它简单、快速、不用训练,但缺点也比较明显:
- SimHash 结果具有一定的随机性,两个随机序列的汉明距离存在一定的概率比较接近,需要通过 ensemble 降低这个概率,成本比较高
- SimHash 对用户相似度的表征比较粗粒度(计算汉明距离,而汉明距离是一个整数)
- SimHash 不能学习用户行为上下文序列的关系,不能对 i2i、u2i 等进行建模
Item2Vec
微软于 2016 年发表了一篇论文,Item2Vec:Neural Item Embedding for Collaborative Filtering。作者受 NLP 运用 embedding 算法学习 word 的 latent representation 的启发,参照了 google 的 word2vec 方法,把 item2vec 应用到推荐场景的 i2i 相似度计算中。它的主要思想是:把 item 看做 word2vec 中的 word,把用户的行为序列看做一个 sentence,item 间的共现为正样本,并按照 item 的频率分布进行负采样。
这篇论文是微软将 word2vec 应用于推荐领域的一篇实用性很强的文章。item2vec 方法简单易用,极大地拓展了 word2vec 的应用范围:从 NLP 领域直接拓展到推荐、广告、搜索等任何可以生成 sequence 的领域。
Item2Vec 的负采样存在一个问题:负样本过于简单。比如,用户听了一首粤语歌,使用全局负采样,可能是一首英文歌,而这样会减弱向量的表征能力。为此,我们可以进行约束负采样,从而提高向量的表征能力。如图:
注意到,Item2Vec 生成的是 item 的向量,那么怎么得到 user 的向量呢?事实上,在生成 item 向量之后,我们可以根据用户历史上与 item 的交互行为,计算 mean pooling 获取用户的向量表达。有了用户的向量表达之后,我们就可以利用高维向量检索引擎(如云音乐自研的 nsearch、Facebook 的 Faiss 等)进行相似向量的快速检索。
除了通过上面的方式间接得到用户向量,我们还可以参考 Doc2Vec,当我们通过 user 与 item 的交互历史构建出训练的序列时,可以将 user id 作为 global context 加入到训练中,同时学习出 user 和 item 的向量。
MetaPath2Vec
Item2Vec 是处理同构网络的方法,实际在使用的时候我们是分业务单独建模再融合的,而 MetaPath2Vec 是
YuXiao Dong 等于 2017 年提出的一种用于学习异构信息网络(Heterogeneous Information Network, HIN)节点表示的模型。
在论文中,异构网络被定义为图 G=(V,E,T),其中 V 表示节点集合,E 表示边的集合,T 表示节点类型和边类型的集合。对于每个节点 v、每条边 e 都有对应的映射函数,f(v): V -> T_V,g(e): E -> T_E,T_V 和 T_E 分别表示节点和边的类型,同时 |T_V| + |T_E| > 2,即图节点类型和边类型的类别总量大于 2。
MetaPath2Vec 可用于学习包含不同节点类型、不同边类型的图节点的低维表示。MetaPath2Vec 的核心思想主要有两点:
- 元路径
- 异构 Skip-Gram
下面,我们以用户-歌曲-艺人的网络进行说明。如图所示,该网络有三种类型的节点,不同类型的节点以不同的颜色区分。
首先,我们看看什么是元路径。元路径是在图中选取的由节点类型构成的组合路径,具有一定的业务含义。比如
「用户-歌曲-用户」,它表示两个用户对某首歌曲有共同行为。我们通常将元路径设计成一种对称的形式,这样可以重复循环进行多次随机游走。比如基于「用户-歌曲-用户」的元路径可以采样出「用户1-歌曲1-用户2-歌曲2-用户3”的序列。
与一般的随机游走相比,基于元路径的随机游走有以下优点:
- 避免游走偏向于出现频率高的节点类型
- 避免游走偏向于相对集中的节点(即度数高的节点)
- 能够捕获不同节点类型之间的联系,从而可以将不同类型节点的语义关系融合到异构 Skip-Gram 模型中
接下来,我们看看异构 Skip-Gram,它的优化目标是最大化节点和其异构上下文的共现概率。
异构 Skip-Gram 的目标函数如下,和普通 Skip-Gram 模型的主要区别在于中间多了个求和符号,分别对节点与其异构邻居的关系进行建模。
四、服务部署
有了用户的向量表征之后,我们就可以构建隐性关系链服务了。服务的整体架构如图所示,至底向上依次是算法层、向量引擎层和服务层。
在算法层,我们通过 simHash、item2vec 和 metapath2vec 等模型学习用户的向量表示,在这个过程中,同时也会产出内容的向量表示,即 Embedding。
在向量引擎层,我们把用户和内容的 Embedding 导入到向量引擎进行索引构建。这里的向量引擎,用的是云音乐自研的 nsearch,实现了高维向量相似检索、高并发低延时等查询需求。
在服务层,采用的是云音乐自研的服务框架 rtrs,实现了动态发布、多级缓存和异步处理等工程需求。当请求来了之后,框架会对协议参数进行解析,召回模块会去配置中心加载相应的业务配置,然后执行该场景的业务召回。
通过以上这套框架,我们可以支持多种隐性关系链的召回方式,包括 u2u、u2i 和 i2i 等,另外,每种召回方式能够支持不同业务场景定制需求的能力。
五、项目成果
隐性关系链从业务中来,最终也应该回到业务中去,服务业务,为业务创造价值。
第一,隐性关系链从无到有,提供了隐性关系服务的能力。在这个过程中,我们除了构建用户的隐性关系,也构建了内容和艺人等的隐性关系链。如图所示,展示了艺人的隐性关系链。
第二,目前隐性关系链为音乐、播客和动态等 9 个业务的 13 个应用场景提供了隐性关系服务,取得了良好的效果。其中,在陌生人一起听这个场景,效果提升显著(人均连线时长 +9.4%)。
第三,目前隐性关系服务,高峰期 QPS 在 5000 以上,平均时耗在 10 毫秒。
六、总结与展望
隐性关系链是一个基建项目,虽然不是直接做业务,但是也和做业务殊途同归,都需要为业务创造价值。我们已经在一些业务场景取得了一些效果,但还有不少地方需要进一步完善:
第一,隐性关系链基于神经网络模型,神经网络的黑箱特性使得很多模型不具有可解释性,使得隐性关系链无法应用在一些需要显性关系的业务,比如在用户推荐场景提供推荐理由。对于这个问题,我们将引入图数据库辅助建模。
第二,隐性关系链的数据价值还没有得到充分挖掘,比如 KOL 挖掘、社群发现等。
第三,模型的泛化能力还不够强,还需要添加更多 side information 。
第四,模型还不够鲁棒,模型容易被活跃用户、热门内容带偏,导致对不活跃用户、长尾内容的学习不够充分。对于这个问题,我们将引入 contrastive learning(对比学习)进行建模。
参考文献
- Charikar, Moses S. (2002), "Similarity estimation techniques from rounding algorithms", Proceedings of the 34th Annual ACM Symposium on Theory of Computing, p. 380, doi:10.1145/509907.509965, ISBN 978-1581134957.
- Gurmeet Singh, Manku; Jain, Arvind; Das Sarma, Anish (2007), "Detecting near-duplicates for web crawling", Proceedings of the 16th International Conference on World Wide Web (PDF), p. 141, doi:10.1145/1242572.1242592, ISBN 9781595936547.
- Barkan O, Koenigstein N. Item2vec: neural item embedding for collaborative filtering[C]//2016 IEEE 26th International Workshop on Machine Learning for Signal Processing (MLSP). IEEE, 2016: 1-6.
- Dong Y, Chawla N V, Swami A. metapath2vec: Scalable representation learning for heterogeneous networks[A]. Proceedings of the 23rd ACM SIGKDD international conference on knowledge discovery and data mining[C]. 2017: 135–144.
- Thomas N. Kipf and Max Welling. 2017. Semi-Supervised Classification with Graph Convolutional Networks. In ICLR.
- Xiangnan He, Kuan Deng ,Xiang Wang, Yan Li, Yongdong Zhang, Meng Wang(2020). LightGCN: Simplifying and Powering Graph Convolution Network for Recommendation
本文发布自网易云音乐技术团队,文章未经授权禁止任何形式的转载。我们常年招收各类技术岗位,如果你准备换工作,又恰好喜欢云音乐,那就加入我们 staff.musicrecruit@service.ne... 。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。