推荐系列论文四:Real-time Personalization using Embeddings for Search Ranking at Airbnb(下)

前言

在上篇里介绍了这篇论文中对于listing的Embedding方式,通过对于objective的调整使得Embedding结果更加符合Airbnb的场景,从而将Embedding用于相似推荐以及提高搜索性能。

上述的Embedding主要针对用户的短时兴趣,因为利用的是用户的click session形成的序列,这种Embedding均是基于用户短时偏好的连续性并且借助总体的用户群来对每个listing进行更新从而获得更为准确的结果,但是这种方式无法获取用户的长时偏好,因此,Airbnb就用户的长时偏好进行了针对User type以及Listing type的Embedding来更好地捕获用户的长时偏好信息。

为什么做User type以及Listing type的Embedding
  • 如上所说,listing的Embedding根据用户的点击序列生成,更多依赖的是短时间的偏好顺序信息,这种用于衡量listing的相似性是非常好用的,相当于其利用用户主动的感观表达来捕获潜在的相似性信息。

  • 而对于搜索来说,需要在没有session click信息的基础上把用户潜在感兴趣的内容排序并展示出来,这就很依赖通过用户的长时偏好信息来将召回数据进行排序,在成功的排序后通过用户的点击行为增加猜你喜欢来增加用户的点击以及booking概率。

面对的问题

首先,想要利用用户的booking信息来代表用户的长时偏好信息,但是利用用户的booking序列来训练listing Embedding存在以下一些问题:

  1. booking的序列长度非常短,因为Airbnb是一个短租平台,除了飞行达人,大部分人一年可能都用不上几次Airbnb。
  2. 许多用户的booking list甚至只有一个任务,而知道word2vec原理的同学应该都晓得长度为1的list将无法进行训练。
  3. 想要有效地学习一个listing的Embedding,那么其至少需要出现5-10次,但是实际上许多的listing总共的预定都没有5次。
  4. booking时间跨度非常大,用户在两次booking之间的用户属性可能发生了较大的变化,例如用户的年龄、职业等都可能已经发生了变化。
解决方式
listing type

Airbnb的做法是,既然listing id的粒度过细导致许多的listing的记录太少无法获得有效训练,Airbnb的做法是不再针对id级别的Embedding,而是将listing id表示为若干属性的交叉,其依据的表为下:

例如当前listing id为1,对应的属性为来自US,type为Share,平均每晚的价格小于40$等,那么就可以使用US#Share#<40来代表当前的listing的id,通过这种方式的mapping可以将许多不同的listing map至相同的离散表达中,相当于通过mapping来对listing来进行降维,对于Airbnb的场景而言其可以要求host来提供这些准确的信息,也就是使用的特征的可信度较高。

user type

对于user id而言,首先作者没有提到怎么对id做Embedding,我想法是既然可以利用user生成item,那么利用item也可以生成用户的 ,文章中提到也是对user_type进行Embedding,user_type和listing一样利用mapping来进行降维,使用的表如下:

对于那些没有预定结果的用户直接只使用最上面的五个信息来进行表示,这种表达方式也可以更加方便处理用户冷启动的情况。

目标

user type的Embedding最重要的捕获用户不断变动的偏好信息,而如何捕获用户不断变化的偏好信息么?Airbnb的做法是将user type的Embedding和listing type的Embedding做到一个向量空间,这种做法带来的是什么作用呢?就是说给你当前的user type以及listing type的embedding,通过二者的相似度度量用户的长期偏好是否与当前的listing想匹配。

  • 上述做法很美好,可以通过一个向量空间做表示,user的Embedding就相当于一个表示用户长时偏好的listing的Embedding
  • 私以为,这种是不是利用attention来进行更合适一些?有想法的同学欢迎留言讨论。

好,既然Airbnb的初衷已经表达好了,那么到底怎么做才能将user type和listing type嵌入到一个空间中从而使得二者之家记性交叉积等具有现实意义么?

###### 序列生成及train

之前使用的是每个用户的booked的listing id构成的列表,而现在将listing id替换为listing type,另外一点是将user type加入到序列中,与listing type构成一个二元组,并且由于用户的属性可能是不断变化的,所以某一个用户产生的booking list中的user_type是可能发生变化的,如下:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190624010646767.png)

训练的关键来了,到底是如何将二者表达嵌入到同一个向量空间呢?这是一件很神奇的事情,但是Airbnb的做法很简单,如下图:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190624010706950.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTMwMTk0MzE=,size_16,color_FFFFFF,t_70)

其中, U t i U_{t_i} Uti代表ti时间戳上的user type, L t i L_{t_i} Lti则代表ti时间戳上的listing type,将二者嵌入到同一向量空间的做法是利用当前的中心词同时更新上下窗口以及当前窗口词一组的user type或者listing type信息,当当前中西词为user type时,其objective为下图:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20190624010739788.png)

对于中心词为listing type时只需要进行替换即可,其中的不同主要是利用Negative Sampling时sample的对象不同。

explicit negatives for rejections

文中提到了,有些情况下host会拒绝guest的预定,那么如何将rejections信息encode入Embedding呢?还是从objective中入手,Airbnb采用将产生rejections的user与listing type对加入到objective中共同进行训练。

那么思考一下,host为什么会拒绝预定呢?通常是用户的信息不完整、用户的平均得分较低等,那么Airbnn认为理想的Embedding是将那些对于用户信息不完整或者打分低的不敏感的listing在向量空间上与这些user的Embedding更加接近,那么增加哪些Rejections到objective中呢?

  • 文中重点采样的是那些同一个用户成功booking前的rejection记录,即假设用户A被listing A拒绝了之后成功预定了listing B,那么user A与listing A组成一对负记录

增加了rejections后的objective变为以下:

D r e j e c t D_{reject} Dreject就是上面所说的获取的负记录,增加到整个训练的loss中,从而学习到更多的rejection信息。

效果

下面计算一下user_type与listing type的embedding结果相似度,如下:

uset_type是预定过一些高质量的、宽敞的并且有许多好评的多个在US的不同的类型的listing的用户,看sim最高的listing,也是位于US的large以及have lots of good reviews的listing,说明嵌入还是较为成功的。

小结

后面关于实验部分的章节就不展开进行介绍了,感兴趣的同学可以去翻看一下这篇论文,还是重点推荐一下。

这次的分享呢主要是介绍Airbnb如何处理用户的长时偏好信息,并且由于数据稀疏的问题Airbnb给出了他们的解决方案,这里抛出一个问题,大家可以思考一下。

  • 为什么将id粒度降维到type的组合可以有效解决数据稀疏问题呢?比如前面提到的很多的用户的预定列表只有一个元素,那么怎么解决这些列表的训练呢?

你可能感兴趣的:(AI,推荐与计算广告系列论文)