Fork me on GitHub

从 KDD 2018 Best Paper 看 Airbnb 实时搜索排序中的 Embedding 技巧

这里是 「王喆的机器学习笔记」 的第八篇文章,今天我们聊一聊KDD 2018的Best Paper,Airbnb的一篇极具工程实践价值的文章 Real-time Personalization using Embeddings for Search Ranking at Airbnb 。

相信大家已经比较熟悉我选择计算广告和推荐系统相关文章的标准:

  1. 工程导向的;
  2. 阿里、facebook、google等一线互联网公司出品的;
  3. 前沿或者经典的。

Airbnb这篇文章无疑又是一篇兼具实用性和创新性的工程导向的paper。文章的作者Mihajlo发表这篇文章之前在Recsys 2017上做过一个talk,其中涉及了文章中的大部分内容,我也将结合那次talk的slides来讲解这个论文。

废话不多说,我们进入文章的内容。

Airbnb作为全世界最大的短租网站,提供了一个连接房主(host)挂出的短租房(listing)和主要是以旅游为目的的租客(guest/user)的中介平台。这样一个中介平台的交互方式比较简单,guest输入地点,价位,关键词等等,Airbnb会给出listing的搜索推荐列表:

Airbnb的业务场景

容易想见,接下来guest和host之间的交互方式无非有这样几种:

  1. guest点击listing (click
  2. guest预定lising (book
  3. host有可能拒绝guest的预定请求 (reject

Airbnb的交互方式

基于这样的场景,利用几种交互方式产生的数据,Airbnb的search团队要构建一个real time的ranking model。为了捕捉到用户short term以及long term的兴趣,Airbnb并没有把user history的clicked listing ids或者booked listing ids直接输入ranking model,而是先对user和listing进行了embedding,进而利用embedding的结果构建出诸多feature,作为ranking model的输入。这篇文章的核心内容就是介绍如何生成listing和user的embedding

具体到embedding上,文章通过两种方式生成了两种不同的embedding分别capture用户的short term和long term的兴趣。

  1. 一是通过click session数据生成listing的embedding,生成这个embedding的目的是为了进行listing的相似推荐,以及对用户进行session内的实时个性化推荐。
  2. 二是通过booking session生成user-type和listing-type的embedding,目的是捕捉不同user-type的long term喜好。由于booking signal过于稀疏,Airbnb对同属性的user和listing进行了聚合,形成了user-type和listing-type这两个embedding的对象。

我们先讨论第一个对listing进行embedding的方法:

Airbnb采用了click session数据对listing进行embedding,其中click session指的是一个用户在一次搜索过程中,点击的listing的序列,这个序列需要满足两个条件,一个是只有停留时间超过30s的listing page才被算作序列中的一个数据点,二是如果用户超过30分钟没有动作,那么这个序列会断掉,不再是一个序列。

Click Session的定义和条件

这么做的目的无可厚非,一是清洗噪声点和负反馈信号,二是避免非相关序列的产生。

有了由clicked listings组成的sequence,就像我们在之前专栏文章中讲过的item2vec方法一样,我们可以把这个sequence当作一个“句子”样本,开始embedding的过程。Airbnb不出意外的选择了word2vec的skip-gram model作为embedding方法的框架。通过修改word2vec的objective使其靠近Airbnb的业务目标。

Airbnb的类word2vec embedding方法

我们在之前的专栏文章 万物皆embedding 中详细介绍了word2vec的方法,不清楚的同学还是强烈建议先去弄明白word2vec的基本原理,特别是objective的形式再继续下面的阅读。

我们假设大家已经具备了基本知识,这里直接列出word2vec的skip-gram model的objective如下:

在采用negative sampling的训练方式之后,objective转换成了如下形式:

其中σ函数代表的就是我们经常见到的sigmoid函数,D是正样本集合,D'是负样本集合。我们再详细看一下上面word2vec这个objective function,其中前面的部分是正样本的形式,后面的部分是负样本的形式(仅仅多了一个负号)。

为什么原始的objective可以转换成上面的形式,其实并不是显然的,感兴趣的同学可以参考这篇文章, Negative-Sampling Word-Embedding Method。这里,我们就以word2vec的objective function为起点,开始下面的内容。

转移到Airbnb这个问题上,正样本很自然的取自click session sliding window里的两个listing,负样本则是在确定central listing后随机从语料库(这里就是listing的集合)中选取一个listing作为负样本。

因此,Airbnb初始的objective function几乎与word2vec的objective一模一样,形式如下:

(给大家出个脑筋急转弯,为啥Airbnb objective的正样本项前面是负号,原始的word2vec objective反而是负样本项前面是负号,是Airbnb搞错了吗?)

在原始word2vec embedding的基础上,针对其业务特点,Airbnb的工程师希望能够把booking的信息引入embedding。这样直观上可以使Airbnb的搜索列表和similar item列表中更倾向于推荐之前booking成功session中的listing。从这个motivation出发,Airbnb把click session分成两类,最终产生booking行为的叫booked session,没有的称做exploratory session。

因为每个booked session只有最后一个listing是booked listing,所以为了把这个booking行为引入objective,我们不管这个booked listing在不在word2vec的滑动窗口中,我们都会假设这个booked listing与滑动窗口的中心listing相关,所以相当于引入了一个global context到objective中,因此,objective就变成了下面的样子

其中最后一项的lb就是代表着booked listing,因为booking是一个正样本行为,这一项前也是有负号的。

需要注意的是最后一项前是没有sigma符号的,前面的sigma符号是因为滑动窗口中的中心listing与所有滑动窗口中的其他listing都相关,最后一项没有sigma符号直观理解是因为booked listing只有一个,所以central listing只与这一个listing有关。

但这里的objective的形式我仍让是有疑问的,因为这个objective写成这种形式应该仅代表了一个滑动窗口中的objective,并不是整体求解的objective。如果是整体的objective,理应是下面的形式:

其中Db代表了所有booked session中所有滑动窗口中central listing和booked listing的pair集合。

不知道大家有没有疑问,我们可以在这块多进行讨论。

下面这一项就比较容易理解了,为了更好的发现同一市场(marketplace)内部listing的差异性,Airbnb加入了另一组negative sample,就是在central listing同一市场的listing集合中进行随机抽样,获得一组新的negative samples。同理,我们可以用跟之前negative sample同样的形式加入到objective中。

其中Dmn就是新的同一地区的negative samples的集合。

至此,lisitng embedding的objective就定义完成了,embedding的训练过程就是word2vec negative sampling模型的标准训练过程,这里不再详述。

除此之外,文章多介绍了一下cold start的问题。简言之,如果有new listing缺失embedding vector,就找附近的3个同样类型、相似价格的listing embedding进行平均得到,不失为一个实用的工程经验。

为了对embedding的效果进行检验,Airbnb还实现了一个tool,我们简单贴一个相似embedding listing的结果。

Airbnb Similar Listing

从中可以看到,embedding不仅encode了price,listing-type等信息,甚至连listing的风格信息都能抓住,说明即使我们不利用图片信息,也能从用户的click session中挖掘出相似风格的listing。

至此我们介绍完了Airbnb利用click session信息对listing进行embedding的方法。写到这里笔者基本要断气了,下一篇我们再接着介绍利用booking session进行user-type和listing-type embedding的方法,以及Airbnb如何把这些embedding feature整合到最终的search ranking model中的方法。

最后给大家三个问题以供讨论:

  1. 为什么Airbnb objective中正负样本的正负号正好跟word2vec objective的正负号正好相反?
  2. Airbnb加入booked listing作为global context,为什么在objective中不加sigma加和符号?
  3. 这里我们其实只得到了listing的embedding,如果是你,你会怎样在real time search ranking过程中使用得到的listing embedding?

这里是 **「王喆的机器学习笔记」**的第八篇文章,水平有限,欢迎大家拍砖、吐槽、讨论。觉得有收获的同学也欢迎点赞,谢谢。

参考资料:

  1. Search Ranking and Personalization at Airbnb Slides
  2. Real-time Personalization using Embeddings for Search Ranking at Airbnb
  3. Negative-Sampling Word-Embedding Method
  4. Recommender System Paper List

本文地址:https://www.6aiq.com/article/1548218172908
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出