今天学习的是一篇 2018 年的工业论文《Real-time Personalization using Embeddings for Search Ranking at Airbnb》,介绍的是 Word2Vec 在 Airbnb 推荐场景中的应用。大概内容就是从用户日志中抽取用户行为并组成序列,然后通过 Word2Vec 完成训练,最后得到 Item 的 Embedding Vector。虽然看似简单,但这篇论文却拿到 KDD 2018 Best Paper,知易行难,在看本文文章之前,我们先来试着回答几个问题:
- 如果你是 Airbnb 的工程师,如何构建数据集,正例是什么,负例是什么?
- 旅游是一个低频行为,很大一部分用户一年可能只有一两次行为,这样就没法组成一个序列用于训练,这部分数据怎么处理?直接扔掉吗?
- 如何捕捉用户的实时兴趣和长期兴趣?
- Airbnb 这种体量的公司是如何在搜索中做到实时计算个性化,计算量不会很大吗?
- 如何解决新用户和新房源的冷启动问题的?
读者阅读完本文后将一一得到答案:
1. Introduction
工程师在 Airbnb 的应用场景中设计了两种 Embedding 方式:
- 一种是用来反应短期实时兴趣 Item Embedding;
- 另一种反应长期兴趣的 User-type & Item-type Embedding。
2. Item Embedding
我们先来看如何构建反应短期实时兴趣的 Item Embedding。
2.1 Model
我们将用户的点击行为构建为序列 s i = ( l 1 , l 2 , . . . , l m ) ∈ S s_i = (l_1,l_2,...,l_m) \in S si=(l1,l2,...,lm)∈S ,其中 S 为 N 个用户的行为序列集合。为了消除噪声和增强负反馈信号,我们需要对序列进行清洗:
- 删除用户停留时长小于 30 秒的 Item;
- 如果用户两次点击行为间隔超过 30 分钟,将重新构建一个新的序列;
我们使用 Skip-Gram 模型来训练 Embedding,窗口大小为 2m + 1 的损失函数为:
∑ − m ≤ j ≤ m , i ≠ 0 l o g ( P ( l i + j ∣ l i ) ) \sum_{-m \leq j \leq m,\ i \neq 0} log(P(l_{i+j}|l_i)) \\ −m≤j≤m, i=0∑log(P(li+j∣li))
整体样本的代价函数为:
a r g m a x L = ∑ s ∈ S ∑ l i ∈ s ∑ − m ≤ j ≤ m , i ≠ 0 l o g ( P ( l i + j ∣ l i ) ) argmax \quad L = \sum_{s\in S} \sum_{l_i \in s}\sum_{-m \leq j \leq m,\ i \neq 0} log(P(l_{i+j}|l_i)) \\ argmaxL=s∈S∑li∈s∑−m≤j≤m, i=0∑log(P(li+j∣li))
为方便起见,我们以下讨论的损失函数均为窗口的损失函数。
为防止每次迭代计算更新输出向量的所有参数值,我们采用 Negative Samping 进行负采样,损失函数为:
a r g m a x ∑ ( l , c ) ∈ D p l o g [ σ ( v c ′ v l ) ] + ∑ ( l , c ) ∈ D n l o g [ σ ( − v c ′ v l ) ] argmax \quad \sum_{(l,c) \in D_p} log[\sigma(v_c^{'}v_l)]+\sum_{(l,c) \in D_n} log[\sigma(-v_c^{'}v_l)] \\ argmax(l,c)∈Dp∑log[σ(vc′v