搜索基本概念

何为搜索?

举个简单的例子,如图所示,当我们想要买衣服的时候,我们可能会随手打开淘宝,在输入框输入“衣服”两个字,然后点击搜索按钮,淘宝网就会返回匹配的内容给用户浏览,这个过程其实就是搜索。

我们做个抽象和简化,搜索系统就是如下图所示的样子,用户输入查询条件,搜索引擎查找到条件匹配的内容后,将内容展示出来。



当然,有同学会立马有疑问,这个不就是一个查询吗,使用传统的关系型数据库也能满足需求,那么搜索和查询到底有什么区别呢?



还是以上述在淘宝搜索“衣服”为例,如果我们采用关系数据库存存储,那么我们可以等同于如下查询语法:



select * from item where name like '%衣服%'



很显然,这种情况下,name字段是没法走索引的,需要扫全表,查询会非常的慢。那有没有更简单的方法呢,可能会说能不能加个衣服的分类或者标签,可是如果新增一个商品品类怎么办呢?要无限制加下去吗?如何能更简单高效的处理全文检索呢?



答案就是搜索,通过词法语法分析、分词、构建词典、构建倒排表、压缩优化等操作构建一个反向索引(倒排索引),查询时通过词典快速获取结果,从而达到高效全文检索的目的。



分词 

分词就是对一段文本,通过规则或者算法分成多个单词。只有分词后有这个单词,搜索才能搜到,分词的正确性非常重要。分词粒度太大,搜索召回率就会偏低,分词粒度太小,准确率就会降低。如何恰到好处的分词,是搜索引擎需要做的第一步。



正确性&粒度

●分词正确性

        ○“中央饭店”,这句话如何分词?

        ○“中-央饭-店” [错误语义]

        ○“中央-饭店” [正确语义]

●分词的粒度

        ○“中华人民共和国”,这句话如何分词?

        ○“中华人民-共和国”,[搜索 中华 无结果]

        ○“中华-人民-共和国”,[搜索 共和 无结果]

        ○“中-华-人-民-共-和-国”,[搜索其中任意字都有结果]

分词的粒度并不是越小越好,粒度越小准确率越低,比如搜索 “中午” 也会出现上条结果,而且粒度越小,索引词典越大,搜索效率也会下降。如何准确的分词,涉及到 NLP领域,此处不细说,仅列举几个常见的分词器:

●IK:实现中英文单词的切分,可自定义词库,支持热更新分词词典

●jieba:支持分词和词性标注,支持繁体分词,自定义词典,并行分词等

●Hanlp:由一系列模型与算法组成的Java工具包,目标是普及自然语言处理在生产环境中的应用

●THUAC:中文分词和词性标注



停用词

很多语句中的词都是没有意义的,比如 “的”,“在” 等副词、谓词,英文中的 “a”,“the”等,在搜索看来都是无意义的,所以在分词构建索引时都会去除掉来节省索引空间,这种词叫停用词 (StopWord)。通常可以通过文档集频率和维护停用词表的方式来判断停用词。



词项处理

词项处理,是指在原本的词项上在做一些额外的处理,比如归一化、词形归并、词干还原等操作,以提高搜索的效果。并不是所有的需求和业务都要词项处理,需要根据场景来判断。

1.归一化

●9月30日 - 9/30 [中英文]

●color - colour [通假词]

●开心 - 高兴 [同义词扩展范畴]

这样查询9/30也能得到9月30日的结果

2.词形归并(Lemmatization)

针对英语同一个词有不同的形态,可以做词形归并成一个,如:

●am, are, is -> be

●car, cars, car's, cars' -> car

3.词干还原(Stemming)

通常指的就粗略的去除单词两端词缀的启发式过程

●automate(s), automatic, automation -> automat.

●可可爱爱 -> 可爱[中文重叠词还原]

英文的常见词干还原算法,比如Porter算法。



倒排索引

倒排索引是什么?简单一点讲,就是单词到文档id的反向映射关系



简单示例:

对以下三个文档进行分词(去掉停用词)构造倒排索引后的结果如下图所示

1a982a50feb1bbae42364ac967a1af0b.png

我们模拟下倒排索引的查询过程,比如查询包含“搜索引擎”的文档:

1、通过倒排索引获得“搜索引擎”对应的文档id列表,有1,3

2、通过正排索引查询1和3的完整内容

3、返回最终结果



倒排索引主要由两部分组成:

●单词词典(Term Dictionary)--内存

●倒排列表(Posting List)--磁盘

512216fe97de3456cc7d52ce5075c0b8.png



词典

单词词典是文档集合中所有单词的集合,它是保存索引的最小单位,其中记录着指向倒排列表的指针



单词词典的实现一般采用B+树,当然也可以采用LSM (Log Structured Merge Tree)、FST(Finite State Transducer)、SkipList等数据结构,我们以B+树为例,那么上述文档的词典结构如下:

819ef3b6b80450f4aa28b4c0ed29441f.png



倒排列表

倒排列表记录了单词对应的文档集合,由倒排索引项(Posting)组成,倒排索引项主要包含如下信息:

●文档id,用于获取原始信息

●单词频率(TF,Term Frequency),记录该单词在该文档中出现的次数,用于后续相关性算分

●位置(Posting),记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)

●偏移(Offset),记录单词在文档的开始和结束位置,用于高亮显示



以“搜索引擎”这个单词为例,其倒排列表如下:

d222946490d93164b410e5ce766f2245.png



上述词典和倒排列表整合在一起后的结构如下:

8dc868fc12654aa16838469a78d20d2f.png



正排索引

既然有了倒排索引,那么必然就有正排索引,那正排索引是什么呢?上文中也有描述,搜索过程可以简化为:通过倒排索引拿到文档ID后再通过正排索引拿到文档信息(单词),也就是文档id到单词的正向映射关系



以上述文档1和文档3为例,分词(去掉停用词)后的正向索引如下:

98c747ef40a298148afa8e2ae537a4e0.png

正排索引除了用于倒排索引的正向查询外,主要还用于文档的排序、聚合、统计等。如果聚合查询里有带过滤条件或检索条件,先由倒排索引完成搜索,确定文档范围,再由正排索引提取field(单词),最后做聚合计算。



算分排序

●搜索的相关性算分,实际上是描述了一个文档和查询语句匹配的程度,这个程度量化后就变成了分数_score

●打分的本质是排序,需要把最符合用户需求(打分越高)的文档排在前面,常见的打分算法有经典的TF-IDF、BM25等,当然也可以采用插件的方式,来自定义打分排序,此处不再细说



TF-IDF

TF(词频)-IDF(逆文档频率) 是公认的信息检索领域最重要的发明,除了在信息检索领域,在文献分类,和其他相关领域也有着非常广泛的应用。其中 TF 表示某个 Term(单词) 在 Document 里出现的频次,越高说明越重要;DF 表示在全部 Document 里,共有多少个 Document 出现了这个单词,DF 越大,说明这个单词很常见,并不重要,越小反而说明它越重要,IDF 是 DF 的倒数(取log), IDF 越大,表示这个单词越重要。评分公式如下:



f7b6c870cd96ad6abc32d3bfd426e792.png



BM25

上面解释了 TF 和 IDF,那么 TF 和 IDF 谁更重要呢,怎么计算最终的相关性得分呢?这就衍生了BM25。



BM25算法,一句话概况其主要思想:对Query进行语素解析,生成语素qi;然后,对于每个搜索结果D,计算每个语素qi与D的相关性得分,最后,将qi相对于D的相关性得分进行加权求和,从而得到Query与D的相关性得分。

BM25算法的一般性公式如下:

ae30e47c76d6b8cc5119322ebff4a7f1.png

其中,Q表示Query,qi表示Q解析之后的一个语素(对中文而言,分词后的单词可看成语素qi);d表示一个搜索结果文档;Wi表示语素qi的权重;R(qi,d)表示语素qi与文档d的相关性得分。



其中 Wi 通常使用 IDF 来表达,R 使用 TF 来表达;综上,BM25算法的相关性得分公式可总结为:

eaea11fed32d25fcae4449e751ae5fa8.png

BM25 通过使用不同的语素分析方法、语素权重判定方法,以及语素与文档的相关性判定方法,可以衍生出不同的搜索相关性得分计算方法,这就为我们自定义排序算法提供了较大的灵活性。

搜索框架选型

通过对国内外搜索技术的调研,我们总结出目前主流的搜索框架(简化版)大部分都是先用dump宽表merge所有数据源的数据,然后再全量转储到搜索引擎,search端传入用户搜索条件后,从搜索引擎进行召回、排序,最后进行结果展示,如下图左边部分所示。结合业务自身特点,可在主流搜索框架上做一些定制调整,比如国际卖家商品搜索去除了嵌套子文档,因此可以省掉dump宽表存储,采用局部更新的方式;同时search端可以忽略相关性算分,只需文本召回即可,如下图右半部分所示。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值