Facebook搜索的向量搜索

Facebook搜索的向量搜索

1. 概述

不管是搜索系统还是推荐系统中,向量召回都是一个不可或缺的一个部分,担负着重要的作用。为应对大规模数据问题,通常采用多阶段的架构,分为召回,粗排,精排,重排等多个步骤,每一个阶段的数据量会极大较少,为后续的精细化排序节约大量的时间,可以由下图所示:

www.zeeklog.com  - Facebook搜索的向量搜索

而向量召回属于召回阶段,以搜索为例,传统的搜索以文本匹配为主,通过query中的词(如果是中文,需要首先对query进行分词)检索所有的候选doc,如果doc中出现了query中的词,则表示命中,最后返回所有命中的doc。在文本匹配中存在一些问题,如语义相似的问题,
比如“苹果手机”与“iPhone”指代的是同一个东西,而在传统的文本匹配中则无法解决。

注:在文本匹配中通常采用query扩展的方法匹配“苹果手机”和“iPhone”

基于向量的方法能有效解决语义鸿沟的问题。在向量召回中,通过embedding的方法分别将query和doc映射到同一个空间中,此时,query和doc的匹配问题就变成在该空间中计算query和doc的相似度。Facebook于2020年公布了其向量召回系统[1]。Facebook将向量召回应用在社交网络的搜索中,针对其场景的特殊性,提出将用户的上下文环境考虑进query的向量中。文章的主要贡献有:

  1. 提出统一的embedding框架
  2. 一个完整的embedding在线召回系统

在本文中重点阐述embedding模型进行以及相关性模块。

2. Embedding模型

2.1. Embedding模型结构

Facebook提出的统一embedding框架(以下简称为EBR)的结构如下图所示:

www.zeeklog.com  - Facebook搜索的向量搜索

为了将query和doc映射到同一个空间中,EBR采用了目前业界常用的双塔模型,即使用两个神经网络分别对query和doc的编码。

2.2. Embedding模型训练

对于一个模型的训练,包括样本准备,特征工程,损失函数定义以及效果评估等几个方面。

2.2.1. 样本准备

在召回模型中,正负样本的选择决定了模型效果的上限。对于正样本的选择,[1]中给出了两种思路,分别为:

  1. 曝光且点击的样本。
  2. 曝光即作为正样本。

以上两者在文中效果类似,在实际的工作中,通常采用第一种方案,即将曝光且点击的样本作为正样本,点击代表了用户的选择,因此可以作为正样本,而曝光即作为正样本,这样会导致选择的范围太大。对于负样本的选择,[1]中也给出了两种思路:

  1. 随机选取。即从文档候选集中随机选取样本作为负样本;
  2. 曝光中未点击的样本。

从实验结论来看,第二种方法比第一种方法效果差。通俗的解释是曝光的样本未必是与query不相关的,正样本也是与query相关的,这样会导致模型很难降正负样本区分开。在[2]中提出**千万不要在整个候选库里等概率抽样 **,因为存在“二八定律”,即少数热门物料占据了绝大多数的曝光与点击。正确的做法是:当热门物料做正样本时,要降采样;当热门物料做负样本时,要适当过采样,同时,也要保证冷门物料在负样本集中有出现的机会。

2.2.2. 难样本挖掘

在实际的训练过程中,为了能够使得模型具有更强的鲁棒性,通常希望模型能够对较难的样本具有正确的区分能力,较难的样本即比较难分的样本。难样本又分为:难负样本(hard negative)和难正样本(hard positive)。

对于难负样本的挖掘(hard negative mining),[1]中提到将召回位置在101-500位的召回结果作为难样本,同时对于随机负样本和难负样本的比例,控制在100:1效果最好。

2.2.3. 特征工程

在FaceBook的向量搜索中,基于其特定的场景,使用到的特征包括query和document的文本特征、位置特征、社交Embedding特征。

文本特征。在文本特征中使用的是字符n元组,这样,相比词n元组,得到的模型效果更好。

位置特征。在本地广告、小组或事件的搜索场景中,位置匹配是很重要的。query侧增加搜索人的城市,地区,国家和语言。document侧增加管理员打的小组地域标签。再加上前面的文本特征,模型能顺利学习到query和文档间隐式的位置匹配效果。

社交Embedding特征。基于Facebook的社交图谱学习用户和实体的Embedding。

2.2.4. 损失函数

在EBR中采用Triplet Loss作为模型的损失函数,即

L = ∑ i = 1 N m a x ( 0 , D ( q ( i ) , d + ( i ) ) − D ( q ( i ) , d − ( i ) ) + m ) L=\sum_{i=1}^{N}max\left ( 0,D\left ( q^{\left ( i \right )},d_+^{\left ( i \right )} \right )-D\left ( q^{\left ( i \right )},d_-^{\left ( i \right )} \right )+m \right ) L=i=1∑N​max(0,D(q(i),d+(i)​)−D(q(i),d−(i)​)+m)

其中, D ( u , v ) D\left ( u,v \right ) D(u,v)表示的是向量 u u u和 v v v之间的距离, m m m表示的是正负样本之间的最小距离。

3. 总结

在召回模型的训练中,为了使得模型具有更好的鲁棒性,模型的样本尤为重要,相比而言,负样本更重要,通常,选择曝光且点击的样本作为负样本,随机选择样本作为负样本,同时,在训练过程中适当插入难负样本对于模型的鲁棒性有很好的作用。

参考文献

[1] Huang J T, Sharma A, Sun S, et al. Embedding-based retrieval in facebook search[C]//Proceedings of the 26th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. 2020: 2553-2561.

[2]

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk