论文《Listing Embeddings in Search Ranking》笔记
——论文发表时间:2018年
——(Airbnb爱彼迎房源排序中的嵌入(Embedding)技术)
——作者:By Mihajlo Grbovic, Haibin Cheng, Qing Zhang, Lynn Yang, Phillippe Siclait and Matt Jones
注释:
1、Airbnb:是AirBed and Breakfast ("Air-b-n-b")的缩写,中文名:爱彼迎。是一家联系旅游人士和家有空房出租的房主的服务型网站。 Airbnb成立于2008年8月,总部设在美国加州旧金山市。Airbnb是一个旅行房屋租赁社区,用户可通过网络或手机应用程序发布、搜索度假房屋租赁信息并完成在线预定程序。 2019年3月,Airbnb收购酒店预订应用开发商HotelTonight。
2、Airbnb 平台:包含数百万种不同的房源,用户可以通过浏览搜索结果页面来寻找想要的房源,我们通过复杂的机器学习模型使用上百种信号对搜索结果中的房源进行排序。 当用户查看一个房源时,他们有两种方式继续搜索:返回搜索结果页,或者查看房源详情页的「相似房源」(会推荐和当前房源相似的房源)。我们 99% 的房源预订来自于搜索排序和相似房源推荐。
关键词笔记(基础知识储备):
(1)嵌入的背景:
将词语表示为高维稀疏向量 (high-dimensional, sparse vectors) 是用于语言建模的经典方法。不过,在许多自然语言处理 (NLP) 应用中,这一方法已经被基于神经网络的词嵌入并将词语用低维度 (low-dimentional) 来表示的新模型取代。新模型假设经常一起出现的词也具有更多的统计依赖性,会直接考虑词序及其共现 (co-occurrence) 来训练网络。 随着更容易扩展的单词表达连续词袋模型 (bag-of-words) 和 Skip-gram 模型的发展,在经过大文本数据训练之后,嵌入模型已被证明可以在多种语言处理任务中展现最佳性能。
最近,嵌入的概念已经从词的表示扩展到 NLP 领域之外的其他应用程序。来自网络搜索、电子商务和双边市场领域的研究人员已经意识到,就像可以通过将句子中的一系列单词视为上下文来训练单词嵌入一样,我们也可以通过处理用户的行为序列来训练嵌入用户操作,比如学习用户点击和购买的商品或浏览和点击的广告。 这样的嵌入已经被用于 web 上的各种推荐系统中。
拓展:
(
1、高维稀疏向量 (high-dimensional, sparse vectors)
这里,信号和图像都可以看成是一个数据对象在所有维度上的信号,本文统称为“数据对象”。因此,不难看出,这种数据对象必然是一个高维的。何为高维?举个例子:比如对一个10个人的薪酬表的描述。表的行是这10个人;列是这是个人的属性,比如姓名、生日、职位、基本工资、工作年限等一共20个属性。那么这个表就是一个10*20的表。每个人即一个数据对象,是20维的。那么问题来了,比如一个人脸的图像(简化一下,不是自拍照,是一寸照。再简化一下,比如这个图像要求的清晰度不高,只要32*32像素的)。那么可以理解成这个图像有32*32个点,每个点有一个表示颜色的数值(再进一步简化,这是黑白照片,每个点的数值表示的是这个点的深浅程度)。那么这个照片就有32*32=1024个点。如果我们有这样的照片100张,每张照片都有1024个表示颜色深浅的数据,那么就得到了一个100*1024的表。这明显是高维了。而真正的图像中,不可能是32*32的吧(难道都是小霸王里的超级玛丽?),要再是彩色的,俺的苍天啊,这个维度就更高了,高到我不想举例子了。在实际工作的研究领域,一般20维以上即可以算作是高维数据了。
2、高维数据的特点
(1、维灾:这个名字太贴切了,维度增加带来的灾难。这个概念是一个叫Bellman的大叔在1962年提出来的(好像不是大叔,大爷都不止了)。意思是对于一个多变量的函数,随着维数的增加(变量的增加),这样高维数据问题往往转化成为了一个多变量的优化求解问题。但由于维度太高了,传统的算法就不行了。比如,每个数据对象理解成一个点,我们一般用k近邻的概念时要找到距离这个点最近的k个点。但是在高维空间中,最近的点和最远的点的距离随维度增加而减小,换句话说,维度增加让远点和近点的差异减小,趋近于零。所以单纯用传统办法解决高维问题,没戏了。(这里的例子实际上是高维聚类问题)
2、未标记(UNlabeled):所谓标记,就是上面薪酬例子里的,姓名,年龄,这些东西,可以理解成为属性(即维度)的名字。但是现在这个社会,得到的大量数据往往是未标记的。比如,一个电子商务系统中,大量不同商品评论的情感分析,如果去手动标注情感倾向(比如积极的、消极的、中立的)十分不现实,要有愚公移山的精神,那就是子子孙孙无穷匮也。但这样显然没有意义。这里针对有标记的数据的学习过程一般称为有监督的学习,无标记的,自然就是无监(Unsupervised)学习了。
3、稀疏表示原理
看了高维数据的特点,怎么解决呢?既然维度高了,那就降下来吧。所以问题就变成了,把高维数据用低维度表示的问题了。线代学得好的人这里可能想到了什么正交啊,基的问题。差不多就是这个意思。举个不是特别贴切的例子(实在找不到好理解的例子了),比如,你现在的位置怎么表述,东经多少,北纬多少,海拔多少,三个维度。但其实换一个说法,宿舍床上。一个维度。为啥维度变了呢,参照物变了,也就是所谓的基变了。这里的字典就是这个基。 学术一点表示,字典就是一个矩阵(n维),这个矩阵比之前的的高维数据(k维)的维度要低得多,即n<<k。数据对象y可以表示成y=a1 x1 +…+an xn 其中,xi 是字典的列向量,ai 是一个线性组合,称之为稀疏表示系数,整个ai 构成的矩阵记为A。所谓的稀疏表示,其实就是求这个系数的矩阵。为了实现稀疏,系数矩阵的很多值,都是0。
参考博客网址:
https://www.cnblogs.com/Tavion/p/5166695.html)
(2)会话的由来:
HTTP的无状态,也就是说,每次请求都是独立的线程。举个例子吧:购物中,你选择了A商品,加入购物车,这就是A线程。然后在选择B商品就是B线程。可是每次线程独立(对容器而言,A、B成了不同的用户),线程A不知道有B,B也不知道A。如何一起付款呢?简答来说:怎么保存同个用户多个请求会话状态呢?自然HTTPS保证连接是安全的,可以使它与一个会话关联。
关于会话的原创出处网址:
(3)余弦相似性:
通过测量两个向量的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。两个向量有相同的指向时,余弦相似度的值为1;两个向量夹角为90°时,余弦相似度的值为0;两个向量指向完全相反的方向时,余弦相似度的值为-1。这结果是与向量的长度无关的,仅仅与向量的指向方向相关。余弦相似度通常用于正空间,因此给出的值为0到1之间。 注意这上下界对任何维度的向量空间中都适用,而且余弦相似性最常用于高维正空间。例如在信息检索中,每个词项被赋予不同的维度,而一个文档由一个向量表示,其各个维度上的值对应于该词项在文档中出现的频率。余弦相似度因此可以给出两篇文档在其主题方面的相似度。另外,它通常用于文本挖掘中的文件比较。此外,在数据挖掘领域中,会用到它来度量集群内部的凝聚力。(来自搜狗百科)
拓展
(
(1)余线相似度与欧氏距离的区别:
余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。相比距离度量,余弦相似度更加注重两个向量在方向上的差异,而非距离或长度上。
与欧几里德距离类似,基于余弦相似度的计算方法也是把用户的喜好作为n-维坐标系中的一个点,通过连接这个点与坐标系的原点构成一条直线(向量),两个用户之间的相似度值就是两条直线(向量)间夹角的余弦值。因为连接代表用户评分的点与原点的直线都会相交于原点,夹角越小代表两个用户越相似,夹角越大代表两个用户的相似度越小。同时在三角系数中,角的余弦值是在[-1, 1]之间的,0度角的余弦值是1,180角的余弦值是-1。
借助三维坐标系来看下欧氏距离和余弦相似度的区别:
从图上可以看出距离度量衡量的是空间各点间的绝对距离,跟各个点所在的位置坐标(即个体特征维度的数值)直接相关;而余弦相似度衡量的是空间向量的夹角,更加的是体现在方向上的差异,而不是位置。如果保持A点的位置不变,B点朝原方向远离坐标轴原点,那么这个时候余弦相似度cosθ是保持不变的,因为夹角不变,而A、B两点的距离显然在发生改变,这就是欧氏距离和余弦相似度的不同之处。
根据欧氏距离和余弦相似度各自的计算方式和衡量特征,分别适用于不同的数据分析模型:欧氏距离能够体现个体数值特征的绝对差异,所以更多的用于需要从维度的数值大小中体现差异的分析,如使用用户行为指标分析用户价值的相似度或差异;而余弦相似度更多的是从方向上区分差异,而对绝对的数值不敏感,更多的用于使用用户对内容评分来区分用户兴趣的相似度和差异,同时修正了用户间可能存在的度量标准不统一的问题(因为余弦相似度对绝对数值不敏感)。
(2)调整余弦相似度 —— Adjusted Cosine Similarity
在余弦相似度的介绍中说到:余弦相似度更多的是从方向上区分差异,而对绝对的数值不敏感。因此没法衡量每个维数值的差异,会导致这样一个情况:比如用户对内容评分,5分制,X和Y两个用户对两个内容的评分分别为(1,2)和(4,5),使用余弦相似度得出的结果是0.98,两者极为相似,但从评分上看X似乎不喜欢这2个内容,而Y比较喜欢,余弦相似度对数值的不敏感导致了结果的误差,需要修正这种不合理性,就出现了调整余弦相似度,即所有维度上的数值都减去一个均值,比如X和Y的评分均值都是3,那么调整后为(-2,-1)和(1,2),再用余弦相似度计算,得到-0.8,相似度为负值并且差异不小,但显然更加符合现实。
参考博客地址:https://blog.csdn.net/ifnoelse/article/details/7766123
TF-IDF与余弦相似性的应用:
(一):TF-IDF( 自动提取关键词 )网址:http://www.ruanyifeng.com/blog/2013/03/tf-idf.html
(二):余弦相似性(找出相似文章) 网址:http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html
(4)k 均值聚类 (k-means clustering)
k均值聚类(K-Means Clustering)算法由J.MacQueen(1967)和J.A.Hartigan还有M.A.Wong三人在1975左右提出的。简单的说,k-means聚类算法就是根据你的数据对象的属性特征将你的数据对象进行分类或者分组。再简单点儿说,k-mean聚类就是将你的数据分类用的。
K-均值是一个迭代算法,假设我们想要将数据聚类成 n 个组,其方法为:
1. 首先选择 K 个随机的点,称为聚类中心( cluster centroids)
2.对于数据集中的每一个数据,按照距离 K 个中心点的距离,将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一类
3.计算每一个组的平均值, 将该组所关联的中心点移动到平均值的位置
4.重复步骤 2-4 直至中心点不再变化
原文:https://blog.csdn.net/bdss58/article/details/40930275
)
文章笔记:
原文译文 1:
(我们的数据集由 N 个用户的点击会话 (Session) 组成,其中每个会话 定义为一个由用户点击的 n 个房源 id 组成的的不间断序列;同时,只要用户连续两次点击之间的时间间隔超过30分钟,我们就会认为是一个新的会话。 基于该数据集,我们的目标是学习一个 32 维的实值表示方式
来包含平台上所有的房源,并使相似房源在嵌入空间中处于临近的位置。
列表嵌入的维度被设置为 ,这样的设置可以平衡离线性和在线搜索服务器内存中存储向量所需的空间,能够更好地进行实时相似度的计算。
目前有几种不同的嵌入训练方法,在这里,我们将专注于一种称为负抽样 (Negative Sampling) 的技术。 首先,它将嵌入初始化为随机向量,然后通过滑动窗口的方式读取所有的搜索会话,并通过随机梯度下降(stochastic gradient descent)来更新它们。 在每一步中,我们都会将中央房源的向量更新并将其推向正向相关房源的向量(用户在点击中心房源前后点击的其他房源,滑动窗口长度为 ),并通过随机抽样房源的方式将它从负向相关房源推开(因为这些房源很大几率与中央房源没有关系)。
)
关键点:
( 数据集由 N 个用户的点击会话组成,每个会话定义为一个由用户点击的 n 个房源 id 组成的的不间断序列
,只要用户连续两次点击之间的时间间隔超过30分钟,我们就会认为是一个新的会话。
在每一步中,我们都会将中央房源的向量更新并将其推向正向相关房源的向量(用户在点击中心房源前后点击的其他房源,滑动窗口长度为 ),并通过随机抽样房源的方式将它从负向相关房源推开)
原文译文 2:
(为简洁起见,我们将跳过具体训练过程的细节,并着重解释为了更好地适用我们的场景而做的一些修改:
- 使用最终预订的房源作为全局上下文 (Global Context) :我们使用以用户预订了房源(上图中紫色标记)为告终的用户会话来做这个优化,在这个优化的每个步骤中我们不仅预测相邻的点击房源,还会预测最终预订的房源。 当窗口滑动时,一些房源会进入和离开窗口,而预订的房源始终作为全局上下文(图中虚线)保留在其中,并用于更新中央房源向量。
- 适配聚集搜索的情况:在线旅行预订网站的用户通常仅在他们的旅行目的地内进行搜索。 因此,对于给定的中心房源,正相关的房源主要包括来自相同目的地的房源,而负相关房源主要包括来自不同目的地的房源,因为它们是从整个房源列表中随机抽样的。 我们发现,这种不平衡会导致在一个目的地内相似性不是最优的。 为了解决这个问题,我们添加了一组从中央房源的目的地中抽样选择的随机负例样本集
。
考虑到上述所有因素,最终的优化目标可以表述为
在这里
是正在更新的中心房源的向量
是一对正对
,表示(中心房源,相关房源)元组,其向量在优化中会被互相推近
是一对负对
,表示(中心房源,随机房源)元组,其向量在优化中会被互相推离
是最终被预订的房源,被视为全局上下文并被推向中心房源向量
是一对目的地维度的负例对
,代表(中央房源,来自同一目的地的随机列表)元组,其向量被推离彼此
使用上面所描述的优化程序,我们通过使用超过 8 亿次的搜索点击会话,训练了 Airbnb 上 450 万个有效列表的房源嵌入,从而获得了高质量的房源展示。
冷启动嵌入:每天在 Airbnb 上都有新的房源提供。这些房源在新建时还不在我们的训练数据集中,所以没有嵌入信息。 要为新房源创建嵌入,我们会找到 3 个地理位置最接近、房源类别和价格区间相同的已存在的房源,并计算这些房源嵌入的向量平均值来作为新房源的嵌入值。)
关键点:
(
1使用最终预订的房源作为全局上下文 (Global Context):这一步用用户的最终预订的房源作为全局上下文 ,可以使得展现的房源更加符合用户的真实喜好。
2适配聚集搜索的情况:这是考虑到只是拿目的地用来表示正反例使得在一个目的地内相似性不是最优的,所以进行适配聚集搜索优化。
在以往的基础上使用了这两个修改:获得了高质量的房源展示。
冷启动嵌入:对于新房源的提供,先找到 3 个地理位置最接近、房源类别和价格区间相同的已存在的房源,并计算这些房源嵌入的向量平均值来作为新房源的嵌入值。
)
原文译文 3:
(
嵌入学习到的是什么?
我们用多种方式来评估嵌入捕获到的房源的特征。首先,为了评估地理位置相似性是否被包含,我们对用于学习的嵌入进行了 k 均值聚类 (k-means clustering)。下面的图显示了美国加州产生的 100 个聚类,确认了来自近似位置的房源聚集在一起。 接下来,我们评估了不同类型(整套房源,独立房间,共享房间)和价格范围的房源之间的平均余弦相似性 (cosine similarity) ,并确认相同类型和价格范围的房源之间的余弦相似性远高于不同类型和不同价格的房源之间的相似性。 因此我们可以得出结论,这两个房源特征也被很好的包括在训练好的嵌入中了。
虽然有一些房源特征我们可以从房源元数据中提取(例如价格),所以不需要被学习,但是其他类型的房源特征(例如建筑风格,样式和感觉)很难提取为房源特征的形式。 为了评估这些特性并能够在嵌入空间中进行快速简便的探索,我们内部开发了一个相似性探索工具 (Similarity Exploration Tool),在下面的视频中进行了演示。
线下评估
在对使用了嵌入的推荐系统进行线上搜索测试之前,我们进行了多次离线测试。同时我们还使用这些测试比较了多种不同参数训练出来的不同嵌入,以快速做优化,决定嵌入维度、算法修改的不同思路、训练数据的构造、超参数的选择等。
评估嵌入的一种方法是测试它们通过用户最近的点击来推荐的房源,有多大可能最终会产生预订。
更具体地说,假设我们获得了最近点击的房源和需要排序的房源候选列表,其中包括用户最终预订的房源;通过计算点击房源和候选房源在嵌入空间的余弦相似度,我们可以对候选房源进行排序,并观察最终被预订的房源在排序中的位置。
我们在下图中显示了一个此类评估的结果,搜索中的房源根据嵌入空间的相似性进行了重新排序,并且最终被预订房源的排序是按照每次预定前的点击的平均值来计算,追溯到预定前的 17 次点击。
我们比较了几个嵌入版本:
- d32 regular,没有对原始嵌入算法进行任何修改
- d32 booking global,被预订房源作为全局上下文
- d32 booking global + market negatives,被预订房源作为全局上下文,且加入了中央房源的目的地中抽样选择的随机负例样本作为负值(见上述目标优化公式)
从图中我们可以看出,第三个选项中的被预订房源一直都有较为靠前的排序,所以我们可以得出结论,这个选择要比其它两个更优。
)
关键点:
(
多种方式来评估嵌入捕获到的房源的特征:
1. k 均值聚类 (k-means clustering):评估了地理位置相似性
2.平均余弦相似性:评估了不同类型(整套房源,独立房间,共享房间)和价格范围
3.线下评估:评估嵌入的一种方法是测试它们通过用户最近的点击来推荐的房源,有多大可能最终会产生预订。其中采用了平均余弦相似性进行评估。
可以看出:被预订房源作为全局上下文,且加入了中央房源的目的地中抽样选择的随机负例样本作为负值这个选择要比其它两个更优。
)
原文译文 3:
(
基于嵌入的相似房源推荐
每个 Airbnb 房源详情页面都包含一个「相似房源」的轮播,推荐与当前房源相似并且可以在相同时间段内预订的房源。、
在我们测试嵌入前,我们主要通过调用主搜索排序模型来搜索相同位置、价格区间和类型的房源以得出相似房源。
在有了嵌入之后,我们对此进行了 A/B 测试,将现有的相似房源算法与基于嵌入的解决方案进行了比较。在基于嵌入的解决方案中,相似房源是通过在房源嵌入空间中找到 个最近邻居 (k-nearest neighbors) 来生成的。 更确切地说,给定学习好了的房源嵌入,通过计算其向量
与来自相同目的地的所有房源的向量
之间的余弦相似性,可以找到指定房源
的所有可预订的相似房源(如果用户设置了入住和退房日期,房源需要在该时间段内可预订)。最终得到的
个最高相似性的房源组成了相似房源列表。
A/B 测试显示,基于嵌入的解决方案使「相似房源」点击率增加了21%,最终通过「相似房源」产生的预订增加了 4.9%。
基于嵌入的实时个性化搜索
到目前为止,我们已经看到嵌入可以有效地用于计算房源之间的相似性。 我们的下一个想法是在搜索排序中利用此功能进行一个会话内的实时个性化,目的是向用户更多展示他们喜欢的房源,更少展示他们不喜欢的房源。
为实现这一目标,我们为每个用户实时收集和维护(基于 Kafka)两组短期历史事件:
:用户在过去2周内点击的房源 ID
:用户在过去2周内跳过的房源 ID(我们将跳过的房源定义为排序较靠前的房源,但用户跳过了此房源并点击了排序较靠后的房源)
接下来,在用户进行搜索时,我们为搜索返回的每个候选房源 做 2 个相似性计算:
:候选房源与用户点击过的房源的嵌入空间的相似性(来自
):
具体来说,我们计算来自 的目的地级质心之间的相似性并选择最大相似度。 例如,如果
包含来自纽约和洛杉矶的房源,那么这两个目的地中每个目的地的房源嵌入将被平均以形成目的地级别的质心。
:候选房源和用户跳过的房源嵌入空间的相似性(来自
):
上面这两个相似性衡量的结果,会作为之后通过搜索排序机器学习模型对候选房源进行排序时考虑的附加信号。
我们首先会记录这两个嵌入相似性特征以及其他搜索排序特征,来为模型训练创建一个新的标记数据集,然后继续训练一个新的搜索排序模型,之后我们可以通过 A/B 测试来和当前线上的排序模型进行对比。
为了评估新模型是否如预期地学会了使用嵌入相似性特征,我们在下面绘制了它们的部分依赖图。 这些图显示了如果我们固定住其他所有的特征值,只考虑我们正在测试的某个特征值,候选房源的排序分数会发生什么变化。
从左边的图中可以看出,较大的 值(用户最近点击的房源的相似房源)会导致更高的模型得分。
在右边的图中可以看出,较大的 值(用户最近跳过的房源的相似房源,即不喜欢的房源)会导致较低的模型得分。
所以部分依赖图的观察结果证实,特征行为符合我们之前预期的模型将学习的内容。除此之外,当新的嵌入特征在搜索排序模型特征中重要性排序很靠前的时候,我们的离线测试结果显示各项性能指标都有所改进。这些数据让我们做出了进行在线实验的决定,之后该实验取得了成功,我们在 2017 年夏季上线了将嵌入特征用于实时个性化生成推荐的功能。
)
关键点:
(
(1)对于房源推荐这一模块:
1.老方法:在嵌入之前前,主要通过调用主搜索排序模型来搜索相同位置、价格区间和类型的房源以得出相似房源。
2.改进的地方:在基于嵌入的解决方案中,相似房源是通过在房源嵌入空间中找到 个最近邻居 (k-nearest neighbors) 来生成的。 更确切地说,给定学习好了的房源嵌入,通过计算其向量
与来自相同目的地的所有房源的向量
之间的余弦相似性,可以找到指定房源
的所有可预订的相似房源(如果用户设置了入住和退房日期,房源需要在该时间段内可预订)。最终得到的
个最高相似性的房源组成了相似房源列表。
(2)基于嵌入的实时个性化搜索:目的是向用户更多展示他们喜欢的房源,更少展示他们不喜欢的房源。
通过计算候选房源与用户点击过的房源的嵌入空间的相似性和候选房源和用户跳过的房源嵌入空间的相似性作为之后通过搜索排序机器学习模型对候选房源进行排序时考虑的附加信号。通过绘制部分依赖图,可以发现,特征行为符合之前预期的模型将学习的内容。
)
文章的技术比以往改进的地方:
(
1.使用嵌入技术来实现相似房源推荐:
通过嵌入技术进行搜索排序和相似房源推荐,可以向用户返回更加符合口味的选择,让用户的体验感暴增,并且可以很快的找到自己心仪的产品。
2.实时个性化搜索:
同样是采用了嵌入技术,把学得的搜索机器搜索的前12个临近房源作为“猜你喜欢”推荐给用户,比以往更加人性化,用户可以在猜你喜欢中快速找到符合口味的产品。
)
读后总结:
(总而言之,把以前的搜索做的更加人性化,更加精准地“猜测”出用户想要的一类东西,大大提高了用户的体验感。)