您的位置  > 互联网

如何设计一个高效的搜索引擎?百度怎么设计?

但如何设计一个高效的搜索引擎呢? 我们可以利用百度采用的技术方法来讨论如何设计一个实用的搜索引擎。 搜索引擎涉及很多技术点,比如查询处理、排序算法、页面爬行算法、CACHE机制、ANTI-SPAM等,这些技术细节作为百度等商业公司的搜索引擎服务商是不会公开的。 我们可以将现有的搜索引擎视为一个黑匣子。 通过向黑匣子提交输入,我们可以判断黑匣子返回的输出,从而粗略地判断黑匣子中未知的技术细节。

查询处理和分词是中文搜索引擎的必备任务,而百度作为典型的中文搜索引擎,一直强调其“中文处理”拥有其他搜索引擎所不具备的关键技术和优势。 那么我们来看看百度采用了哪些所谓的核心技术。

我们分两部分讲:查询处理/中文分词。

1.查询处理

用户向搜索引擎提交查询。 搜索引擎一般在收到用户查询后进行一些处理,然后从索引数据库中提取相关信息。 那么百度在收到用户询问后做了什么?

1. 假设用户提交多个查询字符串,例如“信息检索理论工具”。 那么搜索引擎首先要做的就是根据空格、标点符号等分隔符将查询字符串划分为多个子查询字符串。 例如,上面的查询将被解析为:三个子字符串; 原因很简单,我们接着往下看。

2. 假设提交的查询有重复内容,搜索引擎将如何处理? 例如,在查询“理论工具理论”时,百度将重复的字符串视为只出现一次,即将其视为等效的“理论工具”。 不过,显然不是合并,而是重复查询子串的权重。 增加加工。 那么你是如何得出这个结论的呢? 我们可以向百度提交“理论工具”,返回341,000条文档,粗略地看一下第一页返回的内容。

好的。 继续,我们提交查询“ Tool ”并查看返回的结果。 退回的文件还有那么多。 当然,这并不能说明太多问题。 我们先看一下第一页返回结果的排序情况。 你看到了吗? 顺序完全没有改变,只是排序略有变化。 这说明百度把重复的查询合并到一个流程中,基本不考虑字符串出现的顺序(考虑这个顺序关系)。

3. 假设提交的中文查询包含英文单词,搜索引擎如何处理? 比如查询“电影BT下载”,百度的做法是把中文字符串中的英文作为一个整体保留下来,以此作为断点来分隔中文。 这样,上面的查询被切入,无论中间的英文是字典中能查到的单词还是随机字符,都会被当成一个整体来处理。 至于为什么,查询“电影下载”看结果就知道了。 当然,如果查询包含数字,同样如此。

到目前为止,一切都简单明了。 百度如何处理用户查询? 可以概括为:首先根据分隔符分隔查询,然后查看是否有重复的字符串。 如果有,则丢弃多余的,只保留一个。 然后判断是否有英文单词或数字。 如果是这样,请输入英文单词或数字。 保持整体,将正反面中文剪掉。

接下来做什么? 是时候考虑分词了。

2. 中文分词

首先我们来说一下百度的分词时机或者条件。 难道是中文字符串,百度就剪掉了? 不,如果你想获得百度分词程序的殊荣,你必须注意条件。 你怎么能把它剪成一根绳子呢? 你以为百度卖锯片吗?

那么什么样的绳子才符合被剪断的条件呢? 简单来说,如果字符串只包含小于等于3个汉字,则保持不变。 当字符串的长度大于4个汉字时,百度的分词程序就会开始工作,对字符串进行转换。 肢解。

如何证明呢? 我们向百度提交“电影下载”,查看返回结果中的红色文字。 不难看出,查询语句已经被切成了两个词,说明分词程序已经启动。 如果是长于4个汉字的字符串,分词程序就更不厚道了。 必须将其分解成碎片,然后快速分解。 我们来看看三个人物的情况。 提交查询“当然”。 看来这个查询不伦不类。 那是因为我想看到这个字符串分为 365 个相关页面。 翻到最后一页。 ,发现红色标记的关键词都连续出现在“Of ”中,看起来没有分割,但还不确定,然后提交手动分割的查询“Of ”看看,结果是109万篇文章,基本可以确定没有进行分词。 当然,另一种解释是:先将这三个字符切分,然后将切分结果作为短语查询。 这样看到的效果与没有分割的效果类似。 的。

但我倾向于判断百度没有对小于3个字符的字符串进行分割。 奥卡姆不是说过“不必要时不要添加实体”吗? 为什么会徒劳无功呢? 那么如果没有切分的话,就会出现后续的问题,如何从索引库中提取出未切分的字符串呢? 这就涉及到索引的问题。 我认为百度应该采用两套索引机制,一套基于单词索引,一套基于N-GRAM索引。 至于索引的具体问题,我们稍后再详细讨论。

我们来看看百度采用的是怎样的分词算法。 现在分词算法已经比较成熟了。 有简单的也有复杂的,比如正向最大匹配、反向最大匹配、双向最大匹配、语言模型方法、最短路径算法等,有兴趣的可以搜索一下,增加理解。 我这里就不详细说了。 但要记住的一点是:判断一个分词系统好不好,有两个关键点。 一是消除歧义的能力; 另一个是字典中未注册的单词的识别,例如人名、地名、组织名称等。

那么百度是用什么方法呢? 我的判断是使用双向最大匹配算法。 至于是如何推导的,我们一步步来看。 当然,这里首先有一个假设。 由于速度问题,百度不会采用更复杂的算法。

我们提交了一个查询“博客园天涯海角北京华燕云”,又是一个难以理解的查询。 虽然难以理解,但也有它的道理。 我想看看百度的分词是如何消歧的,是否有字典里没有注册的单词。 识别函数,如果是正向最大匹配算法,那么输出应该是:“博客园天涯海角/北京/华/燕云”,如果是反向最大匹配算法,那么输出应该是:“毛/泽/东北/北京燕云”,我们看一下百度的分词结果:“博客园天涯海角/北方/北京燕云”,一个很奇怪的输出,和我们的预期相差很大,但是从中我们可以得到以下信息:百度分词可以识别人名也可以识别为“北京燕云”,这说明它具有识别字典中未注册的单词的功能。 我们可以假设分词过程分为两个阶段: 第一个阶段,首先查找专门的词典。 这本词典收录了一些人名,还有一些地名和一些普通词典中没有的生词。 这样,首先解析出“博客园天涯海角”,剩下的字符串“北京花烟云”,“北京/北京花烟云”就可以视为反向最大匹配分词结果。 这基本上是有道理的。 为了证明这一点,我们提交查询“发博花园天涯海角北”。 我们期望两个分词结果,一个是前向最大匹配,另一个是上述假设的结果。 其实百度输出就是第二种情况,所以基本可以确定百度分词至少使用了两种词典,一种是通用词典,一种是特殊词典(人名等)。 而且,专用词典先将其切掉,然后再用普通词典分割剩余的片段。

继续测试并提交查询“Cubby ”。 如果是前向最大匹配,那么结果应该是。 如果是反向最大匹配,那么结果应该是。 其实百度的分词结果是。 从这个例子看来,采用的是最大匹配算法; 另外,还有一些例子似乎使用了前向最大匹配; 不过等等,我们看一下这个查询“北京华研云”,正向最大匹配的期望结果是,反向最大匹配的期望结果是,百度实际输出的是后者,这说明反向最大匹配可能是用过的; 从这一点,我们可以猜测百度采用的是双向最大匹配分词算法。 如果正向和反向匹配分词结果一致就好了。 是的,直接输出即可; 如果两者不一致,则正向匹配一个结果,反向匹配另一个结果。 这个时候我们应该做什么呢?

从上面两个例子来看,在这种情况下,百度采用的是最短路径方法,即划分的碎片越少越好。 例如,与和比较,选择后者,与和比较,选择后者。 还有一些类似的例子,基本上可以解释这些输出结果。

但剩下的问题是:如果正向和反向分词不一致且最短路径也相同怎么办? 输出正结果还是负结果?

让我们看另一个例子。 提交查询“遥远的古代巴比伦”。 该查询经百度分词,表明字典中有“巴比伦”,但不确定是否有“老巴比伦”一词。 此时还不清楚是正向分割还是反向分割。 得到的结果改为“遥远的古代巴比伦”,分为“遥远/古代巴比伦”。 这表明字典中包含了“古代巴比伦”一词,这表明“遥远的古代巴比伦”是正确的术语。 达到最大匹配结果。 那为什么“遥远的古代巴比伦”不会被反向分割成“遥远/古代/古代巴比伦”呢? 在这种情况下,百度可能的选择是选择词数较少的那组分词结果。

当然,你可以继续问:如果分词后单词数量相同怎么办? 最后看一个例子。 如果查询“王强小:”,百度会将其分割为“大/强/小”,这就是正向分割的结果。 如果相反,则分为“大/强/小”。 ,表示存在歧义且单词相同,则选择正向切分结果。

好吧,看到这里你可能有点头晕。 最后总结一下百度的分词算法。 当然,这里面还是有猜测的成分的。 算法如下:

首先查询专用词典(人名、部分地名等),剪出专有名词,对剩余部分采用双向分词策略。 如果两次分词结果相同,则说明不存在歧义,直接输出分词结果。 如果不一致,则输出最短路径的结果。 如果长度相同,则选择单个词较少的分词结果组。 如果单词也相同,则选择正向分词结果。

百度一直宣扬自己在中文处理方面的优势。 从上面来看,分词算法没有什么特别之处,消歧效果也不太理想。 即使百度采用比上述分词算法更复杂的算法,也很难说是优势。 如果说百度有优势的话,唯一的优势就是它庞大的专用词典。 这个特殊的词典包含人名(如大长今)、头衔(如老太太)和一些地名(如阿联酋等)。 估计百度利用学术界发布的比较新的命名实体识别算法,不断从语料库中识别出字典中没有注册的单词,并逐步扩展这个专门的字典。 如果这就是优势的话,那么这种优势能够维持多久,就是一个显而易见的问题了。

拼写检查错误提示(及拼音提示功能)

拼写检查错误提示是搜索引擎具有的功能。 也就是说,用户向搜索引擎提交查询,搜索引擎检查用户的输入是否存在拼写错误。 对于中文用户来说,最常见的错误是输入法引起的错误。 那么我们来分析一下,看看百度是如何实现这个功能的。

我们对拼写检查系统的分析主要集中在以下几个问题:

(1)系统如何判断用户的输入是否是可能导致错误的查询?

(2)如果判断查询输入可能有错,如何提示正确的词汇?

那么百度是如何做到的呢? 百度判断用户输入是否错误的标准,我觉得应该是查字典。 如果发现字典中没有这个词,那么很可能是输入错误。 此时,错误提示功能被激活。 这个很容易判断,因为如果是正常的单词,百度一般不会给出错误提示。 如果你故意输入一个字典中无法收录的所谓单词,那么百度通常会提示你输入正确的搜索词。

那么百度如何提示正确的词汇呢? 显然是通过拼音法。 例如,当我输入查询“智才”时,百度提供的提示词汇是:“:制裁材料纸材料”,都是同音字。 所以百度必须维护一个同音词词典,保留同音词信息。 例如,它可以包含以下条目:“zhi caià制裁,优质材料,纸质材料”。 还有一个拼音标注程序。 现在能看到的基本流程是:用户输入“智菜”,查字典,发现没有这个词。 OK,启动拼音标注程序,将“”标注为拼音“zhi cai”,然后查找同音字词典,找到同音字“制裁、优质材料、纸”,然后提示用户可能的正确拼写。

整体流程看起来很简单,但是还存在一些遗留的小问题,比如是否要使用词汇表中的所有同音字作为用户的提示信息? 比如某个拼音有10个同音字,是不是都应该输出呢? 百度并没有将所有同音词都输出,而是选择一定的过滤标准,选择其中的几个进行输出。 如何证明这一点? 我们来看看拼音“liu li”的同音字。 紫光输入法提示“刘莉莉莉莉莉莉莉”有4个同音字。 我们看看百度返回了多少。 输入“Liu Li”作为查询。 在这里,你故意输入一个字典中没有的单词,这样百度的拼写检查器就开始工作。 百度提示:“六里六里”,这是什么意思? 意思是不是所有的同音字都输出,而是选择输出。 那么选择标准是什么?

我能猜测的方法是统计LOG中用户查询的情况,提取出用户查询比较频繁的同音字并输出。 如果是这样的话,上面的例子说明,用户搜索“刘丽”的次数比别人高,其次是“刘丽”,再次是“刘丽”,看来大家都喜欢查自己的姓名或他们认识的人的姓名。

还有一个小问题:同音词词典包含2个字词和3个字词,那么是否包含4个字词和更长的词条? 是否包含单字词? 这里很容易回答一个字词。 不用测试就知道它肯定不包括 ,因为当你输入一个单词时,谁知道它是否是错误的呢?

反正只要是汉字,词汇里都能查到,所以没有判断依据。 包括两个字符的单词。 上面有例子,也有三字词。 例如,查询“众成药”时,百度错误提示为:“中成药”,修改查询为“众成药”,仍然提示“中成药”。 再次修改查询为“崇城药”,百度仍然提示“中成药”。 那么4个字的词汇呢?

百度还是会给你提示的。 这是一个例子:

输入:京华烟云提示京华烟云

输入:无声谈话燕云提示京华燕云

输入:京华燕讯提示北京燕云

那么是否会提示较长的单词? 也是有提示的。 例如,如果我输入:“落花世界里有风军”,这个查询是什么意思? 我想读过古诗词的人都知道。 看看百度的提示“花落时再相见”。 , 这是什么意思? 这意味着同音词词典包含了不同长度的同音词信息。 这也说明了百度的核心中文处理技术,即词典,确实很大。

但是,如果用户输入的查询由两个或多个子字符串组成,那么百度的错误提示功能将不起作用。 例如,输入查询“哀悼尸体”,百度提示“艾提被踢了”,但输入的是“我哀悼尸体”,则没有错误提示。

还有一个更重要的问题:如果汉字是多音字,该如何处理? 百度比较懒,根本不处理多音字。 我们来看一下百度拼音标注的一个错误。 在看这个错误之前,我们先看看百度是如何提示多音字错误的。 我们输入查询“剧场”,百度提示“剧院导演”。 “Ju Chang”有两个拼音:“ju zhang /ju chang”。 可以看到,如果是多音字,那么会提示几种情况……现在我们来看看错误情况。 我们输入查询“戏剧张”,百度提示“:戏剧导演”。 提示符是“”,这当然很容易解释,因为它有相同的声音,但为什么呢? “导演”也会提示? 这意味着百度同音词典有错误,表明词条“鞠长”包含了错误的“导演”同音字。 我们顺着线索看看这个错误说明了什么问题?

表明百度同音词典是自动生成的,没有人工校对。 这也说明,在自动生成同音词典的过程中,百度并不是根据文章的拼音进行标记,然后提取词汇和对应的拼音信息来获取的,而是完全根据某个词典中的词条来标记音节。 ,

因此,无法识别由多音字符引起的错误。 如果章节有拼音标注,可能就不会那么容易发现错误的注释了。 当然,还有另一种解释,那就是“导演”是百度故意提示出来的可能正确的单词提示,因为考虑到南方人无法区分“zh”和“ch”的前后鼻音,是是这样吗? 我们继续测试一下到底是什么情况。 是百度有错还是这是百度高级算法?

我们考虑到了“长大”这个词,故意将其错误地输入为“豃大”。 如果百度考虑过前后鼻音的问题,应该会提示“长大了”,但百度的提示却是“隐藏大了”。 这是什么意思? 说明百度没有考虑前后鼻音的问题,根本就是系统错误。 我们输入查询“”,故意误输入为“”。 没有出现错误信息,说明确实没有考虑到这种情况。 前鼻音没有考虑,那么后鼻音考虑过吗? 我们输入“:常”,故意改成“经堂”的后鼻音。 百度提示“明声经禅”,但依然没有考虑后鼻音。 这基本上是百度系统错误造成的。

根据以上推导,我们可以得出以下结论:百度利用拼音标注程序将分词词典中的每个词条标注为拼音,然后形成同音词词典。 因此,两个词典同样大,而且这个词典也随着分词而变化。 字典还在不断增长。 至于多音词,百度在标注过程中并未考虑。 如果是多音词,则将其标记为多种发音组合,这样就形成了同音词典。 这样的同音词典显然包含很多错误。

最后一个问题:百度对英文有拼写检查吗? 我们来试试吧。 输入查询“china”。 是的,有很多结果。 百度主要搜索中文,也可以搜索英文。 这是一个意想不到的惊喜。 改变查询“chine”,是否会以更令人惊讶的方式让我们想起“china”?

百度提示:吃吧,原来是百度拼音搜索功能不小心触发了。 那么拼音搜索和中文查错是否使用同一套同音词典,我们来试试,搜索“”,百度提示“荣吉溶剂量”,OK,改中文查询“荣吉”,百度提示“荣吉溶剂”卷”,似乎用的是同一套同音词词典。 也就是说,百度的中文纠错和拼音搜索机制采用了类似的方式,中文纠错只是增加了一个拼音标注的过程。 这就是传说中的“其实是一个极其强大的拼音输入法”的百度拼音提示功能吗?

最后我们总结一下百度的拼写检查系统:

后台工作:

(1)我们在上一篇文章中说过,百度分词所使用的词典至少包含两个词典。 一种是通用词典,一种是专用词典(专有名词等)。 百度使用拼音标注程序按顺序扫描所有词典中的每个单词。 然后标出拼音。 如果是复音词,则标出所有的发音。 例如,“长大”将被标记为“zhang da/chang da”。

(2)根据注释词条创建同音词词典。 例如上面的“grow up”,就会有两个词条:zhang daà 成长”和chang daà 成长。

(3)利用用户查询LOG频度信息,给每个中文词条赋予权重;

(4) OK,同音词词典已经建立。 当然,随着分词词典逐渐扩大,同音词典也同步扩大;

拼写检查:

(1) 如果用户输入查询并且包含多个子字符串,则不进行拼写检查;

(2)用户查询时,先查分词词典。 如果找到该词条,则OK,不进行拼写检查;

(3)如果发现用户查询词未包含在词典中,则启动拼写检查系统; 首先使用拼音标注程序对用户输入的内容进行拼音标注;

(4) 扫描同音词典中标记的拼音。 如果没有找到拼音,则不会给出提示;

(5)如果找到条目,则按顺序输出几个权重较大的提示结果;

拼音提示:

(1)在同音词典中扫描用户输入的拼音,如果没有找到拼音,则不给出提示;

(2)如果找到条目,则按顺序输出几个权重较大的提示结果;

如上所述,经过分析,得出的结论是,百度分词系统采用的是双向最大匹配分词。 但后来发现推理过程存在漏洞,推导出来的百度分词算法步骤还是太繁琐,所以我们进行了进一步的分析,看看前面的推导是否有错误。

那么前面的分析有哪些缺陷呢?

我们推导百度分词具有反向最大匹配的依据是百度将“北京花烟云”分词为。 从这里看来,采用的是反向最大匹配,因为正向最大匹配的结果应该是,但由此我们可以推断,百度采用双向最大匹配还是太仓促了。 正如我们在上一篇文章中提到的,百度有两种词典,一种是普通词典,一种是专有词典。 而且,首先对专有词典的词汇进行分段,然后将剩余的片段交给普通词典。 要分段的词典。 那么上面的“北京花烟云”之所以被分割成两部分,还有一种可能是:“北京花烟云”这个词存储在一个专有的字典中,所以我们先对其进行分析,这样我们就可以得到“北京花烟云” ”,而剩下的“北”旁边,没有什么可以分割的,所以输出。

这只是一个假设,那么专有词典中真的有“北京燕云”吗? 我们再看一个“山东北京花烟云”的例子。 百度分词的结果是,如果“北京燕云”在普通词典中,如果是反向切分,那么结果应该是,如果是正向切分,应该是,无论如何都无法区分。 这是什么意思?

表明“北京燕云”在该专有词典中,所以先切分“北京燕云”,然后再用普通词典划分剩余的“山东东北”。 显然是前向最大匹配的输出。 当然,根据我们在第一篇文章中的算法在推导“山东北部”的分割时也会得出相同的结论,但它显然比前向最大匹配多了几个判断步骤。 既然效果是一样的,那么另一种更简洁的方法也是有意义的。 当然,我们应该选择简单的方法。 因此,我们初步判断百度采用的是前向最大匹配。

我们继续测试使用的是哪种分词算法。 为了减少专有词典分词的影响,查询中不能出现比较特殊的词。 为了构建查询“天才能量水平”,专有词典中不应出现任何单词。 百度分为,好像是前向最大匹配的结果。 另外,如果所有的查询词都出现在专有词典中,那么采用什么方法呢? 这样一来,首先要保证该词出现在专有词典中,这样才能保证这一点呢?

我们构造查询“陈晓东”,百度对其进行划分,可以看出“陈晓东”在专有词典中,所以先划分。 又如“山东东京市”,百度将其划分为,表示普通词典中“东京”即可,构造查询“陈晓东京华颜云”。 从前面的分析可以看出,这两个词都在专有词典中。 百度将其一分为二,可见专有词典的词也采用了前向最大匹配。 或者双向最大匹配。 然后使用反向最大匹配? 构造查询示例“陈晓东不败”,首先我们确定“陈晓东”和“东方不败”都出现在专有词典中。 如果是正向切分,那么应该是or,如果是反向切分,可以看出百度的切分是or,说明采用的是前向最大匹配。 通过分析,百度的词典中并没有“无敌”这个词,所以实际上百度上的分词结果是和我们之前推导的算法明显不一致,所以之前的分析算法确实存在问题,所以结论是百度采用前向最大匹配算法。

我们重新总结一下百度的分词算法体系:首先,使用专有的词典,采用最大前向匹配的方式进行分词,切出部分结果,将剩下的未分词的结果交给普通词典,普通词典也采用最大前向匹配分词,并最终输出结果。

另外还用了前向最大匹配分词算法,不过好像没有专门的词典,所以很多专有名词都被砍掉了。

从这一点来看,中文词典的建设比百度差,需要付出更多的努力,但也不是那么困难。