购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

我们首先学习如何检索与用户需求相关的搜索结果。这将为你提供所需的搜索基础,以便理解深度神经网络如何帮助建立创造性的搜索平台。

第一个问题:什么是搜索引擎?它是一个系统,一个运行在计算机上的程序,人们可以用它来检索信息。搜索引擎的主要价值在于,它接收“数据”,并被期望提供“信息”。这一目标意味着搜索引擎应该尽其所能理解它得到的数据,以便提供用户可以很容易使用的内容。而用户很少需要关于某个主题的大量数据,他们需要的往往是特定的信息,并且更乐于看到一条答案,而非成百上千条结果。

当提及搜索引擎时,大多数人会想到谷歌搜索、必应搜索、百度搜索和其他大型、流行的搜索引擎,这些搜索引擎能访问大量来源不同的信息。但是,还有许多较小的搜索引擎,它们专注于特定领域或主题的内容。这些通常被称为 垂直搜索引擎 (vertical search engine),因为它们处理有限的一类文档或主题,而不是现有网络上的全部内容。垂直搜索引擎也扮演着重要的角色,因为它们通常能够提供更精确的结果——它们是为特定的内容量身定做的。它们通常会让我们得到 准确率 (accuracy)更高的、粒度更细的检索结果(对比一下使用谷歌搜索和使用谷歌学术搜索学术文章)。(本节不会讨论准确率的详细定义,只会把它当成一般意义上对问题回答的准确率。但准确率也是信息检索中一个定义明确的、用于度量检索结果有多好、多准确的标准术语。)现在我们不区分数据和用户基数的大小,因为下面的所有概念都适用于大多数现有的搜索引擎,无论搜索引擎大小。

搜索引擎的主要职责通常包括:

效率 (efficiency)在实际应用中非常关键。如果用户为获取信息花了太多的时间,那么下次他很可能会换一个搜索引擎。

但是搜索引擎如何处理页面、图书和类似的文本呢?在接下来的章节中,你将了解以下内容:

让我们从信息检索的基础知识(索引、查询和排序)开始。在深入研究这个问题之前,需要了解搜索引擎是如何完成对大型文本流的处理的。这很重要,因为它影响搜索引擎快速搜索和提供精确结果的能力。

站在图书管理员的角度想一想:他刚刚收到一条关于某个主题的图书查询。他如何知道一本书包含了关于某个主题的信息?他又怎么知道一本书里有某个特定的单词?

提取某本书所属的类别(如“人工智能”和“深度学习”这样更高层次的主题)与提取该书中包含的所有单词不同。例如,对于新手来说,分类使搜索一本关于人工智能的书变得更容易,因为他们不需要预先了解人工智能技术或作者。用户只需进入搜索引擎网站,浏览现有类别,并寻找与人工智能主题足够接近的内容即可。但是,对于人工智能专家来说,知道一本书中是否包含“梯度下降”(gradient descent)或“反向传播”(back propagation)这两个词,有助于发现关于人工智能领域中特定技术或问题的更细粒度的信息。

人类通常很难记住一本书中所包含的所有单词,却可以通过阅读书中的几段甚至从前言中看出一本书的主题。计算机的行为往往与此相反。它们可以轻松地存储大量文本,并“记住”数百万个页面中包含的所有单词,以便在搜索时使用;但是它们不擅长提取隐含的、分散的或没有在给定文本中直接表述的信息,比如一本书属于哪个类别。例如,一本关于神经网络的书可能根本没有提到“人工智能”(尽管它可能会提到机器学习),但是它仍然属于“关于人工智能的图书”这一宽泛的类别。

我们先看看计算机已经可以完成得很好的任务:从文本流中提取和存储文本片段[也称为 词项 (term)]。你可以把这个过程称为 文本分析 ,也就是把一本书的文本分解为所有组成它的单词。假设有一盘磁带,一本书的内容以流的形式写在这盘磁带上,还有一台机器(文本分析算法)。你将磁带作为输入插入这台机器中,输出是磁带的许多片段,每个输出片段包含一个单词、一个句子或一个名词短语(例如“人工智能”)。你可能会注意到,一些写在输入磁带上的单词被机器吞噬了,没有以任何形式输出。

因为文本分析算法要创建的最终单元既可能是单词,也可能是一组单词或句子,甚至是单词的一部分,所以我们将这些片段称为词项。词项可以被视为搜索引擎用来存储数据以及检索数据的基本单元。

这是最基本的搜索形式之一—— 关键字搜索 (keyword search)的基础:用户输入一组单词,并期望搜索引擎返回包含部分或全部词项的所有文档。几十年前,网络搜索就是这样开始的。尽管现在的许多搜索引擎要“智慧”得多,但是许多用户仍然根据他们期望的搜索结果所包含的关键字组合进行查询。这就是你现在要学习的内容:用户在搜索框中输入文本后,如何使搜索引擎返回结果。 查询 (query)就是我们所说的用户为搜索某物而输入的文本。虽然查询只是文本,但它传达了用户需求,以及用户如何将这种可能泛泛或抽象的需求(例如“我想了解人工智能领域最新和最重大的研究”)用简洁且具有描述性的方式表达出来(例如“人工智能的最新研究”,如图1-3所示)。

图1-3 搜索并获得结果

作为用户,如果你希望找到包含单词“search”的文档,搜索引擎将如何返回这些文档呢?一种比较笨拙的方法是从头到尾检查每个文档的内容,直到搜索引擎找到匹配的内容。但是,对每个查询执行这样的文本扫描将非常费时,对许多大型文档尤其如此。

当在搜索结果中找到属于查询的一个或多个词项时,就称为 匹配 命中

因此你需要找到一种方法,快速完成这个检索阶段。实现这一目标的一个基本方法是将“I like search engines”这样的句子分解成更小的单元:[I, like, search, engines]。这是实现被称为 倒排索引 (inverted index)的高效存储机制的先决条件。稍后会讨论倒排索引。文本分析程序通常被组织为一个管道,其中包含一条组件链,其中每个组件都以前一个组件的输出作为输入。这类管道通常由两种类型的构件组成。

这类文本分析管道的输出是一系列连续的词项,如图1-4所示。

{%}

图1-4 使用一个简单的文本分析管道获取“I like search engines”中的单词

现在你已经知道文本分析有助于构建快速搜索引擎。同样重要的是,它控制着如何将查询和文本放入索引中进行匹配。通常,文本分析管道可以用于过滤一些词素,这些词素被认为对搜索引擎无用。常见的做法是避免存储常用词项,比如搜索引擎中的介词或冠词,因为这些词语存在于大多数英文文档中。通常你也不希望一个查询返回搜索引擎中的所有结果,因为有些结果价值不大。这种情况下,你可以创建一个词素过滤器,负责删除诸如“the”“a”“an”“of”“in”等词素,同时又让所有其他词素在分词器生成词素时得以输出。在这个简单的例子中:

在现实生活中,尤其是在第一次设置搜索引擎时,通常会构建几种文本分析算法,并在希望放入搜索引擎搜索的数据上进行尝试。这样你就可以将这些算法处理内容的方式可视化,比如生成哪些词素,过滤哪些词素,等等。现在我们已经构建了这个文本分析链[也称为 分析器 (analyzer)],并希望确保它像预期的那样工作,过滤冠词、介词等。现在,让我们来尝试将第一个文本“the brown fox jumped over the lazy dog”输入到分析管道中,并删除其中的冠词。生成的输出流如图1-5所示。

{%}

图1-5 遍历词素图

生成的词素流已按预期删除了“the”词素,这一点可以从图开头的虚线箭头以及节点“over”和“lazy”之间看到。词素旁边的数字表示每个词素的开始和结束位置(以字符数为单位)。本例中最重要的一点是,对于“the”的查询将不会匹配,因为分析器已经删除了所有这样的词素,并且它们最终不会成为搜索引擎内容的一部分。在现实生活中,文本分析管道通常更为复杂,在后面的章节中,你将看到一些这样的情况。在了解了文本分析后,让我们看看搜索引擎如何存储用户要查询的文本(和词项)。

  1. 索引

    尽管为了快速检索,搜索引擎需要将文本切分成多个词项,但用户往往希望搜索结果以单个文档的形式呈现。想想谷歌搜索引擎的搜索结果:如果搜索“book”,人们将收到一个结果列表,每个结果由标题、链接、结果的文本片段等组成。虽然每个结果都包含该词项,但是显示的文档所包含的信息及内容比匹配词项的文本片段多得多。实际上,从文本分析得到的词素与它们所属的原始文本的引用存放在一起。

    词项和文档之间的这种链接使下列两点成为可能:

    • 匹配查询中的关键字或搜索项;
    • 返回引用的原始文本作为搜索结果。

    分析文本流并在搜索引擎中存储结果词项(及其引用的文档)的整个过程通常被称为 索引 (indexing)。

    采用这个术语的原因是这些词项存储在 倒排索引 (inverted index)中。倒排索引是一种将词项映射到最初包含它的文本的数据结构 6 。也许最简单的方法是把它看作一本实体书的分析索引,其中每个单词条目都指向提到它的页面。在搜索引擎中,单词是词项,页面是原始文本。

    从现在开始,我们将把要索引的文本片段(页面、图书)称为 文档 (document)。为了可视化文档被索引后的结果,假设有以下两个非常相似的文档。

    • “the brown fox jumped over the lazy dog”(文档1)
    • “a quick brown fox jumps over the lazy dog”(文档2)

    假设我们使用前面定义的文本分析算法(带有停用词“a”“an”和“the”的词素切分),表1-3显示了包含此类文档的倒排索引的良好近似。

    如表1-3所示,词项“the”没有条目,因为基于停用词的词素过滤器已经删除了这些词素。在该表中,你可以找到第一列中的词项字典和一个 记录列表 (posting list) 7 (一组文档标识符),它们与每一行的每个词项相关联。倒排索引检索包含给定词项的文档的速度非常快:搜索引擎选择倒排索引,查找搜索词项的条目,并最终检索记录列表中包含的文档。对于上面这个例子,如果你搜索词项“quick”,倒排索引将通过查看与词项“quick”对应的记录列表返回文档2。以上是一个将文本索引入搜索引擎的简单例子。

    表1-3 倒排索引表

    让我们思考索引一本书的步骤。一本书由很多页组成,这是书的核心内容,但同时它也有标题、作者、编辑、出版年份等信息。你不能对所有内容使用相同的文本分析管道,因为你不能从书名中删除“the”或“an”。知道书名的用户应该能够通过精确匹配找到它。如果文本分析链从书名“Tika in Action”中删除“in”,那么针对“Tika in Action”的查询将找不到它。此外,对于书的正文内容,你又想避免保留这些词素,于是就需要一个在过滤无用词项方面更主动的文本分析管道。如果文本分析链从书名“Living in the Information Age”中删除“in”和“the”,应该不会有问题,因为用户不太可能会搜索“Living Information Age”,他们更可能会搜索“Information Age”。这种情况下,信息可能有少许丢失或没有丢失,但好处是存储的文本更少。更重要的是,这样可以提高相关性(我们将在下一节讨论这一点)。在现实生活中,一种常用的方法是在同一个搜索引擎中使用多个倒排索引,为文档的不同部分建立索引。

  2. 搜索

    在搜索引擎中索引了一些内容后,请考虑一下搜索本身。历史上,第一个搜索引擎允许用户使用特定的词项(也称 关键字 )进行搜索,后来又引入布尔运算符,它允许用户确定搜索结果中哪些词项 必须 匹配、哪些 禁止 匹配或哪些 可以 匹配。最常见的情况是,查询中的词项 应该 匹配,但这不是强制性的。如果希望搜索结果必须包含这样一个词项,你必须添加相关的运算符,例如在词项前面使用+。像“deep+learning for search”这样的查询需要结果同时包含“deep”和“learning”,还可以选择性地包含“for”和“search”。允许用户指定匹配整个短语而不是单个词项,也是很常见的。这使得用户可以搜索精确的单词序列,而不是单个单词。为了返回必须包含“deep learning”序列以及可选的词项“for”和“search”的搜索结果,可以将前面的查询改为“‘deep learning’ for search”。

    虽然听起来可能令人惊讶,但是文本分析在搜索( 检索 )阶段也很重要。假设你想在刚才索引的数据上搜索 Deep Learning for Search 这本书,并且现在有一个Web界面,你可能会输入类似“deep learning for search”这样的查询。这项检索任务的难点是检索到正确的那本书。介于用户和传统搜索引擎界面之间的第一样东西是 查询解析器 (query parser)。

    查询解析器负责将用户输入的查询文本转换为一组子句,这些子句表明了搜索引擎应该查找哪些词项,以及在倒排索引中查找匹配项时如何使用它们。在前面的查询示例中,查询解析器负责理解符号+和”。另一种广泛使用的语法允许在查询词项之间放置布尔运算符:“deep AND learning”。在这种情况下,查询解析器将为“AND”操作符赋予一个特殊的含义:它左边和右边的词项是必需的。查询解析器可以被看作一个函数,它接受文本并输出一组约束条件用于底层的倒排索引,以便找到结果。让我们再看一个查询例子,如“人工智能的最新研究”(latest research in artificial intelligence)。一个智能的查询解析器创建的子句可以反映单词语义。例如,只为“人工智能”(artificial intelligence)创建一个子句,而不是为“artificial”和“intelligence”设置两个子句。此外,可能“latest”一词并不会参与匹配,我们不需要包含“latest”的结果,而希望检索最近“created”的结果。因此,一个好的查询解析器会将词项“latest”转换成一个可以表达的子句,例如用自然语言表示为“created between today and 2 months ago”。查询引擎将以一种更容易由计算机处理的方式编码这样一个子句,例如create < today() AND created > (today() - 60days),参见图1-6。

    图1-6 查询解析

    在索引过程中,使用文本分析管道将输入文本切分成要存储在索引中的词项,这被称为 索引时文本分析 。同样,在搜索过程中也可以应用文本分析,将查询字符串分解为多个词项,而这被称为 搜索时文本分析 。当搜索时生成的词项与该文档引用的倒排索引中的词项匹配时,就称该文档被搜索引擎检索到。

    图1-7左边展示了一个索引时文本分析,该分析用于将文档文本拆分为词项。这些词项最终都存放在索引中,都引用 文档1 。索引时文本分析由一个空白分词器和两个词素过滤器组成,其中前者用于删除不需要的停用词(如“the”),后者用于将所有词项转换为小写(例如“Fox”转换为“fox”)。在该图右上角,查询“lazy foxes”被传递给搜索时文本分析,该分析使用空白分词器切分词素,但使用一个小写过滤器和一个 词干 (stemming)过滤器进行过滤。词干过滤器转换词项,将词根的变形或派生词还原为词根形式,这意味着删除复数后缀、动词的ing形式,等等。在本例中,“foxes”(复数)被转换为“fox”(单数)。

    {%}

    图1-7 索引、搜索时分析和词项匹配

    验证索引和搜索文本分析管道是否按预期工作的常见方法如下:

    (1) 收集样本内容;

    (2) 将内容传递给索引时文本分析链;

    (3) 建立样本查询;

    (4) 将查询传递给搜索时文本分析链;

    (5) 检查生成的词项是否匹配。

    例如,通常在索引时使用停用词过滤器,因为这时执行过滤不会对检索阶段产生任何性能影响。但是,在索引或搜索阶段也可能有其他过滤器。有了索引时和搜索时文本分析链和查询解析,就可以了解检索搜索结果的过程了。

    你已经知道了搜索引擎的一项基本核心技术是文本分析(词素切分和过滤),它使系统能够将文本分解为你希望用户在查询时输入的词项,并将它们放入一个被称为倒排索引的数据结构中,实现高效的存储(空间上高效)和检索(时间上高效)。然而,作为用户,我们不想查看所有的搜索结果,所以我们需要搜索引擎告诉我们哪些结果应该是最好的。那么,什么是 最好的 结果?对于一个给定的查询,是否有一个度量来评判得到的结果有多好?答案是肯定的,这个度量就是 相关性 。对搜索结果进行准确的排序是搜索引擎必须完成的最重要任务之一。1.5.2节将简要介绍如何处理相关性问题。

6 基本上,大多数参考资料将inverted index译为“倒排索引”,本文也按此翻译。实际上倒排索引和排序没有任何关系。inverted index指从文档中摘出词项,再将词项作为关键字,建立词项与文档的映射。也就是说,这个词项本来是从文档中来的,是文档的属性,现在却以这个属性为关键字建立映射关系,所以这是一个反向或者说逆向过程。与之相对的是“正向索引”(forward index),即以文档为关键字,文档中的词项为其值建立的映射关系。——译者注

7 也有不少参考资料将posting list译为“倒排列表”,该列表会记录每个索引词项出现过的文档集合,以及命中位置等信息。——译者注

前文介绍了给定一个查询,搜索引擎如何检索一个文档。本节将介绍搜索引擎如何对搜索结果进行排序,以优先返回最重要的结果。这将使你对常见搜索引擎的工作原理有一个深入的了解。

相关性 是搜索中的一个关键概念,它是对结果文档相对于某个搜索查询的重要性的度量。人类常常很容易判断对于一个查询而言,为什么某些文档比其他文档更相关。因此,理论上可以尝试提炼一组规则来表示人们关于对文档重要性进行排序的知识。但实际上,这种做法可能会失败,因为:

信息检索领域的中心主题之一是定义一个无须工程师提炼规则的模型。这样的 检索模型 (retrieval model)应该尽可能准确地捕获相关性的概念。给定一组搜索结果,检索模型将对它们进行 排序 :结果越相关,分数越高。

大多数情况下,对一名搜索工程师而言,仅仅选择一个检索模型并不能得到完美的结果,毕竟相关性就像一头反复无常的野兽。在现实生活中,我们可能需要不断地调整文本分析管道和检索模型,并对搜索引擎内部进行一些细节优化。而检索模型可以提供一个固定的基线(baseline)来获得良好的相关性。

向量空间模型 (vector space model,VSM) 8 可能是最常用的信息检索模型之一。在这个模型中,每个文档和查询都表示成一个向量。我们可以把向量想象成坐标平面上的箭头,向量空间模型中的每个箭头都可以表示一个查询或文档。两个箭头越接近,它们就越相似(见图1-8);每个箭头的方向由组成查询或文档的词项定义。

8 参见G. Salton、A. Wong和C. S. Yang的文章“A Vector Space Model for Automatic Indexing”,刊载于 Communications of the ACM 18 ,1975年第11期,第613~620页。

图1-8 基于VSM的文档和查询向量之间的相似度

在这样的向量表示中,每个词项都与一个 权重 相关联。该权重是一个实数,它表示该词项在该文档或查询中相对于搜索引擎中其他文档有多重要。权重可以用不同的方法计算。本节不会深入讨论这些权重的计算方法,而会提到最常见的算法—— 词项频率-逆文档频率 (term frequency-inverse document frequency,TF-IDF)。TF-IDF背后的基本思想是,一个词项在一篇文档中出现的频率(即词项频率)越高,它就越重要;但同时,它又指出,一个词项在所有文档中越常见,它就越不重要(即 逆文档频率 )。因此,在向量空间模型中,搜索结果是根据查询向量进行排序的。文档越接近查询向量,其在结果列表中的排序或分数就越高。

向量空间模型是一种基于线性代数的信息检索模型。近年来,基于概率相关性模型的信息检索方法不断涌现。概率模型不计算文档和查询向量之间的距离,而是根据文档与某个查询相关的概率估计值对搜索结果进行排序。这类模型最常见的排序函数之一是Okapi BM25。本章不会深入介绍它的细节,但它已经显示出良好的效果,在不太长的文档上尤其如此。

后面的章节将探讨神经搜索如何帮助处理相关性的问题,但我们首先需要能够度量相关性。度量信息检索系统性能的一种标准方法是计算其 精确率 (precision)和 召回率 (recall) 9 。精确率是检索到的文档与查询相关的比例。如果一个系统具有很高的精确率,用户通常在搜索结果列表的顶部就能找到他们正在寻找的结果。召回率是检索到的相关文档的比例。如果一个系统有很高的召回率,用户会在搜索结果中找到所有相关的结果,但是它们可能并不都排在搜索结果的前列。

9 目前机器学习中度量检索结果的术语并没有统一译法,译者对本书中主要提及的术语统一如下。
准确率(accuracy):被分对的文档数量/系统中的文档总量,其中被分对的文档数量=被检索出的文档中相关文档数量+未被检索出的文档中不相关文档数量。
精确率(precision):又称为查准率,检索出的文档中的相关文档量/检索出的文档总量。
召回率(recall):又称为查全率,检索出的文档中的相关文档量/系统中的相关文档总量。
——译者注

我们注意到,要度量精确率与召回率,就需要有人判断搜索结果的相关性。在小规模的任务中,人工评判是可行的;但是对于大量文档,则工作量过大,很难以人工方式进行。要度量搜索引擎的有效性,一种选择是使用公开的数据集[如美国国家标准与技术研究院文本检索会议(NIST TREC)的数据集]进行信息检索,其中拥有大量排好序的查询,可以用于测试精确率和召回率。

本节学习了一些经典信息检索模型的基础知识,如向量空间模型和概率模型。下面我们将研究影响搜索引擎的一些常见问题。本书的其余部分将讨论借助深度学习解决它们的方法。 QFcKj7wUwU8D/Uxz1R64vd1ooL4av6hVYIqn4T8Za9dXdNN3uY8g6MtMgsWH2+3V

点击中间区域
呼出菜单
上一章
目录
下一章
×