文章作者:韩宇、张跃伟 阿里巴巴

内容来源:阿里云开发者

导读: 召回结果的好坏对整个推荐结果有着至关重要的影响,最近的一系列实践和研究表明,基于行为序列的深度学习推荐模型搭配高性能的近似检索算法可以实现既准又快的召回性能;与此同时,用户在天猫精灵上还可以进行实时指令操控,利用丰富的反馈信息改进召回模型的性能。

01 背景

传统的推荐系统通常由两部分构成,分别是 Candidate Generation(候选生成)和 Ranking(排序),以下图中经典的 YouTube 视频推荐为例[1],整个系统分为了两层:第一层是 Candidate Generation(候选生成),负责从全量的视频中快速筛选出几百个候选视频,这一步通常也被成为 Matching(召回);第二层是 Ranking(排序),负责对几百个视频进行精准打分并重新排序,决定最终向用户展示的结果顺序。

图 1 YouTube 视频推荐

本文主要研究 Matching(召回)部分,这部分通常面对的是整个推荐 item 集合,既要尽可能多的保留相关性高的结果,又要保证速度,召回结果的好坏对整个推荐结果有着至关重要的影响。最近的一系列实践和研究表明,基于行为序列的深度学习推荐模型[2-4]搭配高性能的近似检索算法[5]可以实现既准又快的召回性能(这套方案通常被称为DeepMatch),和传统的召回方法相比(比如 swing、etrec、SVD),DeepMatch 的优势主要如下:

  • 可以建模 user-item 间更深层次的非线性关系
  • 可以在模型中使用各种 user 和 item 的特征
  • 基于行为序列的模型可以建模用户不断变化的兴趣,并且能够融合用户的长短期兴趣

DeepMatch 已经广泛应用于天猫精灵推荐场景中(APP 信息流推荐、音乐推荐等)并取得了比传统 i2i 方法更好的效果,但目前的模型仍存在着一些问题,有一些关键的信息还未引入进来(以“我要听歌”场景为例,在这个场景中天猫精灵会根据用户的喜好来给用户推荐音乐):

负向反馈信号(Play Rate)

初始训练日志数据中仅包含正向反馈,也即使用播放完成率高的歌曲序列训练 DeepMatch 模型。而在天猫精灵的场景中,用户有主动切歌的行为,如主动的“停止播放”、“下一首”,其中大部分这类型是用户在出现不喜欢的歌曲时触发,这些信号可以作为用户的负反馈加入到模型中。而且一些实践已经表明了负向反馈的作用[6-7],如果能将这些信号有效的利用起来,模型有能力去捕捉用户时刻变化兴趣,在用户进行切歌行为时,减少同类型的音乐推荐。在这个场景中,我们用每首歌曲的播放完成率来表示用户反馈,完播率较大即为正反馈,完播率较小即为负反馈。

歌曲点播 query 意图信号(Intent Type)

天猫精灵歌曲的播放大部分由用户的 query 点播而来,每一首歌曲背后都有用户的点播意图,天猫精灵背后有一套专门的歌曲 query 意图解析,比如精确点播(歌名点播:“播放七里香”、歌手点播:“我要听刘德华的歌曲”)、推荐(风格流派推荐:“来点摇滚”、随便听听推荐:“放歌”)。通过对用户行为的分析来看,不同意图类型下的歌曲对于推荐模型贡献的权重是不同的,在模型中融入歌曲对应的意图 attention,能更准确把握用户的兴趣。因此本文提出了一种基于多任务学习和负反馈的深度召回模型。

02 方法

总体来说,由于近似最近邻检索算法的限制,我们的召回模型需要独立地对用户历史行为序列进行编码以生成用户的每一步的向量表示,然后再和 Target Item 向量做内积运算,得到打分,模型基于 Self-Attention 的架构来实现,总体结构如下:

图 2 模型总体结构

1. Input Representations

如前所述,为了建模负向反馈信号和用户意图类型信号,我们的模型引入了对 Play Rate 和 Intent Type 的表示。但初始数据集不包含这两种信号,因此我们用 Train Set 1 来表示初始数据集,Train Set 2 表示带有负向反馈信号和用户意图类型信号的数据集,我们对它们做了统一的表示。总的来说,用户历史行为序列中的每个 Item 的表示由如下四部分构成:

① Item Embedding

我们首先把每个 Item 嵌入到固定大小的低维向量中,Train Set 1 和 Train Set 2 共用一套 Item Vocabulary,不需要做区分:

\text{E}_i = \text{V}_i * \text{X}_i

其中,X_i 为 Item 的 One-Hot 表示,V_i是 Item Embedding 矩阵,另外需要注意的是输出层和输入层共用一套 Item Embedding,这样做的目的主要是节省显存占用空间,因为推荐场景的 Item 数量是巨大的,而且有很多工作已经证明了这样的做法对于模型性能影响不会很大[2]。

② Position Embedding

对于行为序列任务,我们需要使用位置嵌入来捕获行为序列中的顺序信息。我们采用不同于 Transformer 原论文[8]中的 sin 和 cos 方法,直接使用 Max Sequence Length 个 Embedding 来表示不同的位置。

③ Play Rate Embedding

播放完成率是用户对于 Item 接受程度的一个重要反馈,在天猫精灵上,对于不喜欢的歌曲,用户通常会直接使用“下一首”指令将其切掉,这些歌曲的播放完成率就会比较低。播放完成率是一个值域在 [0, 1] 间的连续值,为了实现后面将要提到的连续值特征和离散值特征的交互,我们参照了[9]中方案,将 Play Rate 映射到了与 Item Embedding 相同的低维向量空间,具体来说,我们将 Play Rate Embedding 表示为:

\text{E}_r = \text{V}_r * \text{X}_r

其中,X_r 是 Play Rate,V_r 是随机初始化的 Embedding,E_r 是最终得到的 Play Rate Embedding,由于我们 Train Set 1 数据只有播放时长较高的歌曲,并且没有播放完成率的信息,因此对于 Train Set 1,我们固定所有 Play Rate 为 0.99:

\text{X}_r = \left\{ \begin{array}{ll} \text{X}_r & \textrm{if Train Set 2}\\ 0.99 & \textrm{if Train Set 1}\\ \end{array} \right.

④ Intent Type Embedding

用户意图类型表示了用户进入这个 Item 的方式,比如在天猫精灵端,点播(用户明确点播出的歌曲)和推荐(天猫精灵为用户推荐的歌曲)就是两种不同的 Intent Type(天猫精灵的实际场景中类型会更多),类似 Item 本身的表示,我们把 Intent Type 也映射到了一个固定的低维向量空间:

\text{E}_t = \text{V}_t * \text{X}_t

我们不知道 Train Set 1 数据中的 Intent Type,在此我们假设所有的 Train Set 1 数据的 Intent Type 全部为点播:

\text{X}_t = \left\{ \begin{array}{ll} \text{X}_t & \textrm{if Train Set 2}\\ Order & \textrm{if Train Set 1}\\ \end{array} \right.

2. Factorized Embedding Parameterization

在推荐的任务中,Vocabulary Size 通常是巨大的,这导致了我们无法使用太大的 Embedding Size 来表示 Item,否则显存放不下,但很多使用 Transformer 的工作证明,提高 Hidden Size 可以有效的提升模型效果[10],参照 ALBERT[11] 压缩模型的方式,我们首先把 Item 的 One-Hot 向量映射到一个低维度的空间,大小为E,然后再映射回高维度的空间再输入Transformer,从而把参数量从 O(V×H) 降低到了 O(V×E+E×H),当 E≪H 时参数量会明显减少。

3. Feedback-Aware Multi-Head Self-Attention

在获得用户行为序列的特征表示后,我们就可以准备构建用户向量了,我们采用了注意力机制来编码用户的行为序列。如 Transformer[8] 中所述,注意力机制可以被描述为一个将 Query 和一系列的 Key-Value Pairs 映射到 Output 的函数,其中 Query,Key,Value 和 Output 都是向量,Output 被计算为 Value 的加权和,其中分配给每个 Value 的权重由 Query 与对应 Key 的打分函数计算,由于召回模型的限制,我们无法使用 Target Item 提前和用户行为序列中的 Item 做运算,因此采用 Self-Attention 的方式,直接把用户行为序列作为 Query,Key,Value 来进行计算。具体来说,我们使用了 Multi-Head Self-Attention 的方式来提升模型对于复杂交互的建模能力:

其中, W_i^Q、W_i^K、W_i^V 是线性投影矩阵,h 是 head 的数量。在经典的 Transformer 结构中,Q,K,V 由 Item Embedding 和 Position Embedding 构成,在我们的模型中,我们将外部信息(播放完成率和用户意图类型)引入到 Attention 中来,我们称之为 Feedback-Aware Attention,通过对这些信息的引入,我们的模型就有能力结合用户的反馈信息感知用户对于各个歌曲的不同的偏好程度了:

Attention(Q,K,V)=softmax(\frac{(Q+E{_r}+E{_t})*(K+E{_r}+E{_t})^T}{\sqrt{d_k}})(V+E{_r}+E{_t})

除此之外我们还参照 ALBERT[11],尝试了 Cross-layer Parameter Sharing 的方案,这种方案让每层 Transformer Layer 全部共享一组参数,同样量级(层数相同)下的 Transformer 采用该方案后实际上的效果是会有所下降的,但是参数量减少了很多,训练速度也会快很多,对于推荐这种数据规模比较庞大的场景,采用这种策略可以在尽量节约训练时间的前提下提升模型性能。

4. Sampled Softmax Loss For Positive Feedback and Sigmoid CE Loss For Negative Feedback

在获得用户的向量表示后,就可以定义多任务学习的目标了,由于之前我们已经统一了 Train Set 1 和 Train Set 2 的数据表示,因此这两个任务可以放在一起进行联合多任务训练。具体来说,我们的任务类似于语言模型:给定前 t 个已经听过的音乐,预测第 t+1 步用户想要听什么音乐,我们根据播放完成率的高低将信号分成两种(实际实现时会使用一个阈值来区分),一种是 Positive Feedback,这种的优化目标是使其打分排序尽量靠前,另一种是 Negative Feedback,这种的优化目标是使其打分排序尽量靠后。

如下图的左图所示,如果只做传统的 Positive Feedback Loss 的话,我们的模型可以拉近用户向量和喜欢的 Item(正向样本)的距离并拉大其和未观测 Item 的距离,但是不喜欢的 Item(负向样本)的距离可能并不会被拉开,我们希望我们的模型可以向右图一样,在做到上述特性的同时,拉大用户向量与不喜欢的 Item 的距离:

图 3 优化目标对比

因此我们使用了 Positive Feedback 和 Negative Feedback 结合的优化目标:

对于 Positive Feedback,我们使用 Sampled Softmax Loss 来优化。在之前的很多工作中[12-13],Sampled Softmax Loss 已经被证明非常适用于大规模推荐召回模型,它的定义如下:

在使用 Tensorflow 实现的时候,sampled_softmax 默认使用的采样器为log_uniform_candidate_sampler ( TF 版 Word2Vec 基于此实现 ),它基于 Zipfian 分布来采样,每个 Item 被采样的概率只跟他词频的排序相关,采样概率不是词的频率,但是推荐中的商品和 NLP 中的词可能不同,因此我们尝试了另外两个采样器:

  • uniform_candidate_sampler:使用均匀分布来采样
  • learned_unigram_candidate_sampler:这个分布会动态�