知乎搜索框背后的Query理解和语义召回技术

一只小狐狸带你解锁 炼丹术&NLP 秘籍

前言

随着用户规模和产品的发展, 知乎搜索面临着越来越大的 query 长尾化挑战,query 理解是提升搜索召回质量的关键。本次分享将介绍知乎搜索在 query term weighting,同义词扩展,query 改写,以及语义召回等方向上的实践方法和落地情况。

知乎搜索的历史

首先回顾下知乎搜索的历史。现有的知乎搜索16年开始内部研发,17年中完全替换外部支持的系统。算法团队从 18 年初开始成立,规模5人左右,之后开始了快速的迭代过程。

主要进展有: 18年 4 月份上线 Term Weight;6 月份上线自研的 Rust 引擎并已对外开源;后续上线一系列的算法模型如纠错、语义相关性,以及今天会重点分享的语义索引和 query 改写;今年下半年工作主要集中在排序侧,主要为用 DNN 替换了树排序模型,并在此基础上继续上线了若干项收益不错的优化。由于今天分享的内容主要是在 NLP 范围,排序侧的内容可以后续有机会再分享。

知乎是一个问答类型的社区平台,内容以用户生产的问题和回答为主。问答网站的属性导致了知乎搜索 query 词的长尾化。实际上在大搜领域中问答类 query 也是相对满意度比较差的一类,而目前各类垂搜分流了原来大搜的流量,当中知乎搜索承担了一部分相对比较难处理的 query。

从我们内部实际数据来看,近一年知乎搜索的长尾化趋势也越来越明显。如上图右上部分是头腰尾部搜索比例,可以看到长尾 query 增长趋势明显。但在我们搜索团队的努力下,用户的搜索满意度并没有随着 query 难度的增加而下降。

长尾 query 特点

长尾 query 的多样性对于搜索系统来说是一个很大的挑战,原因有:

❶ 存在输入错误。例如上图中的错误 query "塞尔维雅" ( 塞尔维亚 ),对于这种错误我们希望系统能够自动的纠错;

❷ 存在表达冗余。例如输入 "孙子兵法智慧的现代意义",在这个语境下,"智慧" 是一个无关紧要的词。如果强制去匹配 "智慧" 的话,反而匹配不出真正想要的结果;

❸ 存在语义鸿沟。比如 "高跟鞋消音",其中 "消音" 这个词的表达较少见,使得同时包含 "高跟鞋" 和 "消音" 文档较少。而类似的表达如 "高跟鞋声音大如何消除"、"高跟鞋消声" 等可能较多。用户输入的 query 和用户生产内容之间存在了语义鸿沟。其他类型的难点还有表达不完整,意图不明等等。

我们先通过图右边这个query:"iPhone 手机价格多少" 来介绍如何解决上述问题:

❶ 对于输入错误,比如说用户输入的 query 是 iPhone,但是这个词输错了,会通过纠错模块将其纠正为正确的 query;

❷ 对于表达冗余,通过计算每一个词的重要程度也就是 term weight,来确定参与倒排索引求交操作的词。先对 query 进行分词,切成 iPhone、手机、价格、多少,之后判断各词对于表达意图更重要,重要的词会在检索时参与倒排索引的求交操作,不那么重要的词不严格要求一定在文档中出现;

❸ 解决语义鸿沟的问题。需要对原始 query 做同义词扩展,比如 "iPhone" 和 "苹果" 是同义词,"价格" 和 "售价" 是同义词。

所以在传统的搜索领域中的查询模块,往往包含这些子任务:纠错、分词、紧密度、同义词、词权重,以及其他的如实体词识别、意图识别等等。这些查询理解会生成一个结构化的数据,检索模块就可以通过结构化的查询串去召回相关的文档。

知乎搜索的召回和排序

知乎的召回系统主要分为两部分:

❶ 基于词的传统的倒排索引召回;

❷ 基于向量的向量索引的召回机制。

如图所示,实际召回中有三个队列,基于倒排索引的队列占两个,分别是原始 Query 队列和改写 Query 队列。改写队列是用翻译模型去生成一个表达更适合检索的 query,然后再去做 query 理解和索引召回。而第三个队列是基于 embedding 的索引。首先把所有 doc、原始 query 都转为向量,再通过空间最近邻的 KNN-Search,找到与 query 最相似的文档。

最终参与排序的就是这三个队列,并进行合并和精排,在精排之后会进行上下文排序。下面来介绍下各个模块具体的实现方法。

Query Term Weight

对于 term weight,最简单的实现方式是用 IDF 逆文档频率算出,即看这个词在语料里的出现次数,如果次数较少,则认为其包含的信息量是相对较多。

这个方法的局限是无法根据 query 上下文语境动态适应,因为其在不同的上下文中 weight 是一致的。所以我们再通过统计点击数据中进行调整。如图,如果用户的 query 包含 a,b 两个 term,并且点击了 Doc1 和 Doc4,其中 Doc1 包含 a,b, Doc4 只包含a,即 a 出现2次,b 出现1次。一个朴素的想法就是 a 的权重就是1,b 是0.5,这样就可以从历史日志里把每个 query 里的 term 权重统计出来。

这个方法对于从未出现过的 query 就无法从历史数据中统计得到。所以我们从 query 粒度泛化到 gram 粒度,按 ngram 来聚合。比如 a,b 就是一个 bigram,类似于 mapreduce 的 map 过程,首先会把 query 中的 ngram 先 map 出来,再发送到 reduce 里面统计。这样就能统计出每个 ngram 下较置信的权重。

对于 ngram,在实际操作中需要注意以下几点:

❶ 词表较大,往往在十亿量级以上;

❷ 字典更新较慢;

❸ 无法处理长距离依赖。基本最多到 3gram,多 gram 词不仅会使词表更加膨胀,词与词的依赖关系也将更难捕捉到;

❹ 无法解决过于稀疏的词,过于长尾的词会退化成 idf。

我们的解法是把 ngram 基于词典的泛化方法变为基于 embedding 的模型泛化方法。目标是想得到根据 query 语境动态自适应的 term weight。如果可以获取跟 query 上下文相关的动态词向量,那么在词向量的基础上再接 MLP 就可以预测出词权重了。目前的方法是通过 term 词本身的词向量减去 query 所有词 pooling 之后的词向量获得,今后也会尝试替换成 ELMo 或者 Transformer 的结构以获得更好的效果。

同义词扩展

对于同义词扩展策略,首先需要一个同义词词表。现在有可以直接应用的公开数据集。但是数据集的词与知乎搜索里的词可能由于分词粒度不一致而不匹配,并且同义词无法保证更新。所以我们主要用内部语料进行数据挖掘,主要方向为:

❶ User logs: session

用户搜索日志,利用用户搜索一个 query 后改写了的新 query,把两者当作相关关系,用对齐的工具将两者同义词找出;

❷ Query logs: click

类似的,利用两个 query 点击的相同 doc 构建 query 关系;

❸ Doc:pretrain embedding

Doc 本身的语料。主要利用知乎内部数据去训练 word embedding 的模型,用 embedding 的值计算相关性。

Word2vec 这一类的 embedding 计算方法,核心假设是拥有相似上下文的词相似。需要注意该方法无法区分同义词和反义词/同位词,例如最大/最小,苹果/香蕉。我们这里利用监督学习的信号,对训练完成的词向量空间进行微调。

❹ 外部数据

用一些规则如百科里 "XXX 又名XXX" 句式进行挖掘。

Query 改写

接下来分享的是 query 改写部分。为什么要做 query 改写?

在传统搜索里,一个 query 进来需要做多个子任务的处理。假如每个任务只能做到90%,那么积累起来的损失会非常大。我们需要一个方法一次性完成多个任务去减小损失,比如把 "苹果手机价格多少" 直接改写为 "苹果手机售价"。

用翻译方法可以实现这个需求,即把改写问题看成 src 和 target 语言为同一种语言的翻译问题,翻译模型用的是谷歌的 NMT 结构。

对于这个任务来说,训练语料的挖掘比修改模型结构更为重要,我们通过用户行为日志来挖掘训练语料。比如从 query 到 title,点击同一 doc 的不同 query,都可形成平行语料。

最后我们用来训练模型的语料用的是 Query -> Query 的平行语料,因为两者在同一个语义空间,长度也基本接近。如果 query 翻译成 title,则会因为 title 长度通常过长而加大训练复杂度。具体方法是:

❶ 语言模型的过滤

目的是把罕见的表达换为常见的表达。用 ngram 模型算一个得分,把较罕见的放在前面;

❷ 进行相关性过滤

考虑到点击日志噪声比较多,通过相关性过滤掉噪声;

❸ 确定切词粒度

用的是 BPE 的 Subword 方法。未用知乎内部的切词是因为未登录词无法预测,同时词表较大,训练速度较慢。

Query 改写 – 强化学习

具体来说,改写模型是拿共现数据做训练语料,但不能保证改写出来的结果一定可以召回有用的文档。我们参考了谷歌 2018 ICLR 的工作,为了将用户输入的 query 改写为更容易检索出答案的 query,把 QA 系统当做一个 environment,改写模型当做 agent,CNN 是对所有召回结果做选择的模块。

在我们的场景中,将图中灰色框里的 QA 对应一套倒排索引,CNN 对应在线排序服务模块。

首先会把原始 query 的召回结果和改写 query 的召回结果一并送入排序服务模块,然后得到 topK 的排序;之后统计这 topK 结果里有多少是改写 query 召回队列里的结果,将其作为 reward。

接下来,我们用强化学习 policy gradient 方法来 finetune 改写模型。利用强化学习的一个好处是,不再需要对齐文本语料,只需要随机的 query 即可。在利用强化学习训练时遇到的问题之一是 reward 稀疏问题。我们发送了很多 NMT 模型的结果给线上系统,但在返回来的 topK 列表里并不包含改写队列的召回。这导致了训练的过程非常的缓慢,也对线上系统造成了很大的开销。

为了缓解 reward 稀疏问题,参照 alphago 里面的模式,即由策略网络,价值网络和蒙特卡洛树搜索三个组件完成。我们可以把 NMT 当成是一个策略网络,然后这里主要添加了价值网络。价值网络用来评估一次改写完成以后,其实际能从系统当中拿到多少 reward。他的输入是两个拼接在一起的 query,输出是一个浮点值。用强化学习的经验来学习这个价值网络,然后将其后面的训练过程中来加速训练。

最后的优化效果非常明显,在加入价值网络以后 reward 比例提升了50%以上。同时,这个价值网络还可以用于在线改写触发 rerank。如下图所示,线上覆盖率有了明显提升, top20 包含 rewrite 比例的 query 数量占到了24%,query doc 数量占到了4%。在改写中我们还训练了从 title 到 query 的模型,解决了检索中的重要字段 clicked query 的覆盖率有限和展现偏置两个问题。Clicked query 字段是记录点击过这个文档的 query,就是说尽管这个 doc 不含 query 里的词,但如果有别的用户搜了类似的 query 所点击的 doc,也会将其召回。

记录 clicked query 会遇到点击噪音和展示偏置的问题。因为有点击的文档比没有点击的文档要多一个字段,使得在召回时有一定优势,从而形成正向循环,导致了展示偏置。

通过训练从 title 到 query 的模型,替换掉了 clicked query。这样把每个文档都写有这个字段。虽然模型的效果没有 query 到 query 的模型好,但因为这个模型建在索引里所以容错率会更高。

以上就是基于词的一些算法阶段的过程,最后分享一下语义召回。

语义召回

语义召回就是把 query 和 doc 都表示为向量,然后在向量空间中做最近邻的搜索。相对于图像领域,在 NLP 领域还不够成熟,因为用户输入的表达可能差一个字含义完全不同提高了语义召回难度。

在模型上需要训练深度语义模型,主要分为两种:

❶ 基于 interaction 的深度语义模型

Interaction based 用于判断两个文档的相似性。该方法提前算出 query 里每个词和 titile 里每个词的相似性,得到相似性矩阵。之后直接用例如 CNN 图像卷积的方法处理该矩阵,计算相似度。

❷ 基于 representation 的深度语义模型

Representation 的意思是先分别将 query 和 title 进行网络的处理,分别得到向量,再预测两者相似度的分数。

按照经验来说,interaction based model 效果会好于 representation based model。但是在向量召回这个任务当中,我们需要离线计算好所有文档的 embedding 并建成向量索引,所以语义召回采用的的是 representation based 模型。

语义召回 – BERT 模型

在 NLP 领域,做 embedding 召回难度大,原因为:

❶ Query 长尾,难以捕捉细粒度的差异

❷ 需要泛化

❸ 过多误召回伤害用户体验

目前BERT 模型带领 NLP 进入了新的时代,借鉴经典的孪生网络结构,我们用 BERT 模型分别做 query 和 doc 的 encoder,接着用 pooling 之后的 query doc cosine 距离当做输出,最后通过 pairwise 损失函数训练模型。在 pooling 方法上,我们也尝试过不同层 pooling,或者在多层上增加 attention 聚合 BERT 多层结果,效果和最后一层所有 token 做 average pooling 相当。损失函数方面,因为我们是做召回阶段的模型,所以参考过雅虎的方法,他们认为在一轮排序阶段使用 pointwise 损失函数的效果会更好,但是在我们的数据上 pairwise 还是会稍好一些。

在 BERT 模型的基础上,我们还做了两项优化:

❶ 优化预训练模型, mask token pretrain 这里主要是参考 百度 ernie 的做法,在知乎的语料上,用中文的分词粒度的数据继续做了 mask token pretrain,使得预训练模型能够更好的适应中文的词关系

❷ 数据增强,增加一些对于模型来说更难区分的负样本具体采样方法为:

用原始的脚本数据去微调一个模型,计算 doc 的 embedding 和 query 的 embedding。对 doc embedding 进行聚类,此时 doc 和 query 的 embedding 就在同一空间里,所以 query embedding 就可以对应到某一个类别。这时候即可从 doc 里直接采样一些负样本了。向量召回上线以后效果提升明显。如图右上方的 case,虽然 query 错误,但仍召回了正确结果。

后续方向

以上是知乎搜索最近一年在召回侧的一些工作,后续的其他方向有:

❶ GAN 在 query 改写的应用因为之前用的是真实系统计算 reward,代价较高,所以考虑用 gan 来代替真实系统去计算 reward,这样样本数据的计算会速度非常快。

❷ 预训练方面尝试把预训练模型做小以便用于更多场景中。目前由于参数规模大,时间开销大,导致无法广泛运用。

进一步探索强化学习在其他场景的应用如应用于 Query 的 term weight 中。

  • ACL2020 | FastBERT:放飞BERT的推理速度

  • ACL2020 | 对话数据集Mutual:论对话逻辑,BERT还差的很远

  • LayerNorm是Transformer的最优解吗?

  • 如何优雅地编码文本中的位置信息?三种positioanl encoding方法简述

  • 在大厂和小厂做算法有什么不同?

夕小瑶的卖萌屋

_

关注&星标小夕,带你解锁AI秘籍

订阅号主页下方「撩一下」有惊喜哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里P8架构师谈:分布式架构设计12精讲

分布式架构设计包含: 分布式缓存 分布式消息中间件 分库分表、读写分离 单点登录等 想成为阿里160万年薪的P8架构师?你必须掌握如下6大技能体系! 阿里P8架构师谈:分布式架构系统拆分原则、需求、微服务拆分步骤 阿里P8架构师谈…

【干货】推荐系统中的机器学习算法与评估实战

【导读】推荐系统是机器学习技术在企业中最成功和最广泛的应用之一。本文作者结合MLMU演讲【1】的Slides,对推荐系统的算法、评估和冷启动解决方案做了详细的介绍。 作者 | Pavel Kordk 编译 | 专知 翻译 | XiaowenMachine Learning for Recommender systems — P…

Google | 突破瓶颈,打造更强大的Transformer

一只小狐狸带你解锁炼丹术&NLP秘籍作者:苏剑林 (来自追一科技,人称“苏神”)前言《Attention is All You Need》一文发布后,基于Multi-Head Attention的Transformer模型开始流行起来,而去年发布的BERT模型更是将Transformer模…

阿里P8架构师谈:高并发网站的监控系统选型、比较、核心监控指标

在高并发分布式环境下,对于访问量大的业务、接口等,需要及时的监控网站的健康程度,防止网站出现访问缓慢,甚至在特殊情况出现应用服务器雪崩等场景,在高并发场景下网站无法正常访问的情况,这些就会涉及到分…

斯坦福CS224n追剧计划【大结局】:NLP和深度学习的未来

一只小狐狸带你解锁炼丹术&NLP秘籍简介Stanford CS224n追剧计划是由夕小瑶的卖萌屋发起的开源开放NLP入门项目,借助github和微信群为大家提供同期小伙伴打卡讨论、内容沉淀、作业笔记和FAQ共享、连线斯坦福等服务。关于该计划的详请见这里 。1. Github项目地址h…

KubeVela 高可扩展的云原生应用平台与核心引擎

https://www.oschina.net/news/121015/kubevela-open-source 目录什么是 KubeVela ?KubeVela 解决了什么问题?1. 应用开发者眼中的 KubeVela一个 Appfile 示例2. 平台工程师眼中的 KubeVela3. KubeVela vs 经典 PaaS快速入门安装KubeVela1. 安装Kubernet…

打造工业级推荐系统(三):推荐系统的工程实现与架构优化

打造工业级推荐系统(三):推荐系统的工程实现与架构优化 gongyouliu 阅读数:4148 2019 年 4 月 26 日导读:个性化推荐系统,简单来说就是根据每个人的偏好推荐他喜欢的物品。互联网发展到现在,推荐…

阿里P8架构师谈:什么是缓存雪崩?服务器雪崩的场景与解决方案

什么是应用服务雪崩 雪崩问题 分布式系统都存在这样一个问题,由于网络的不稳定性,决定了任何一个服务的可用性都不是 100% 的。当网络不稳定的时候,作为服务的提供者,自身可能会被拖死,导致服务调用者阻塞&#xff0c…

论文浅尝 | 基于RNN与相似矩阵CNN的知识库问答

链接:https://arxiv.org/pdf/1804.03317.pdf概述当前大部分的 kbqa 方法为将 kb facts 与 question 映射到同一个向量空间上,然后计算相似性. 但是这样的做法会忽视掉两者间原本存在的单词级别的联系与交互. 所以本文提出一种网络结构 ARSMCNN,既利用到语义的信息, 又利用到单词…

斯坦福大学最甜网剧:知识图谱CS520面向大众开放啦!

一只小狐狸带你解锁炼丹术&NLP秘籍受本次疫情的影响,斯坦福大学的2020春季知识图谱课程——CS520面向公众线上开放啦!连课名都是爱你的形状!简单翻译一下重点:今年的CS520面向公众开放,大家可以通过远程视频软件Zo…

一篇文章详解大数据技术和应用场景

“ 本文作者 陈睿 ,优知学院创始人 新技术、新趋势往往趋之若鹜却又很难说的透彻,希望这篇文章能让大家完整的理解什么是大数据:该篇包含:大数据、技术、场景应用以及大数据的岗位。 什么是大数据 说起大数据,估计大家都觉得只…

对话周明:回望过去,展望未来,NLP有哪些发展趋势?

HomeBlog 对话周明:回望过去,展望未来,NLP有哪些发展趋势? 2019年2月15日 by 打不死的小强 AI 新闻 0 comments 周明博士是微软亚洲研究院副院长、国际计算语言学协会(ACL)主席、中国计算机学会理事、中…

阿里P8架构师谈:MongoDB、Hbase、Redis等NoSQL优劣势、应用场景

NoSQL的四大种类 NoSQL数据库在整个数据库领域的江湖地位已经不言而喻。在大数据时代,虽然RDBMS很优秀,但是面对快速增长的数据规模和日渐复杂的数据模型,RDBMS渐渐力不从心,无法应对很多数据库处理任务,这时NoSQL凭借…

研讨会 | 知识图谱助力图书馆知识管理与智慧服务研讨会

知识图谱是大数据时代重要的知识表示方式之一,也是人工智能技术的重要支撑,在智能检索、数据分析、自动问答、知识推荐、知识管理等领域有着广泛的应用前景,为知识创新管理带来了新机遇。由于知识图谱实现了对象识别、文本理解、关系推理、机…

高效利用无标注数据:自监督学习简述

一只小狐狸带你解锁 炼丹术&NLP 秘籍 作者:huyber来源:https://zhuanlan.zhihu.com/p/108906502BERT的大热让自监督学习成为了大家讨论的热点,但其实word2vec和自编码器也都属于自监督学习范畴。本文通过整理自监督学习的一系列工作&…

TI-RTOS实时操作系统开发之功耗测试

文章目录写在前面CCS(code composer studio)开启Energy Trace配置电池参数设置测量时间在电流曲线图处点击右键开始测量写在前面 要测试一个产品的电流功耗方式有很多种: 1、电流转电压,通过在供电回路中串联10Ω电阻&#xff0c…

程序员真的只能干到35岁?——我的35岁危机度过之道!

“ 在我还是25岁的时候,我和很多程序员一样,其实都有同样的担心,老了以后怎么办?写代码难道还能写到35岁? 难道我这一辈子就做一个程序员就完了吗?难道这条路就不能走出更多的张小龙(foxmail开…

研讨会 | 知识工程与问答技术研讨会 (KEQA2018)

人工智能的迅速发展将深刻改变人类社会,而知识工程是人工智能领域中的一个重要研究主题。随着机器学习、自然语言处理和语义网技术的快速发展,知识获取与处理的能力得到了极大的提升,包括自然语言问答技术在内的智能应用也备受关注。本次研讨…

统计学-自然语言处理

摘要:主成分分析(英语:Principal components analysis,PCA)是一种分析、简化数据集的技术。主成分分析经常用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。常常应用在文本处理、人脸识别、…

在K40小破卡训练50层BERT Large的宝藏trick

前言 虽然TPU的显存令人羡慕,但是由于众所周知的原因,绝大部分人还是很难日常化使用的。英伟达又一直在挤牙膏,至今单卡的最大显存也仅仅到32G(参考V100、DGX-2)。然而,训练一个24层的BERT Large模型的时候…