设计一个文本搜索引擎

博客中的文章均为meelo原创,请务必以连接形式注明本文地址html

 

搜索引擎是一个十分神秘的事物,由于它铸造了google和百度两大传奇互联网公司。过去流传一种说法,世界上只有4个国家掌握了搜索引擎的核心技术,那就是美国、中国、俄罗斯和韩国,分别对应Google、百度、naver和yandex。曾经有国有背景的即刻搜索想承担起国家战略,国有企业在能源、基础设施领域雄踞一方,望风披靡,但即刻搜索最终却失败了。搜索引擎真的是那么高不可攀的技术吗?算法

其实,搜索引擎是诸多技术组成的复合体。囊括天然语言处理、并行计算、爬虫等领域。但其最基本的原理却并不复杂。北京大学在Coursera开设的程序设计与算法专项课程,从零基础开始教授C语言、算法、数据结构,当你过关闯将,完成6门课程以后,最后的毕业项目就是完成一个搜索引擎。毕业项目由7个部分组成,每一个部分都有明确的目标说明,须要完成搜索引擎的一个部分。当你完成全部7个部分的时候,你就真正搭建出来一个搜索引擎啦。动手实践是最佳的学习方式,你能够在学习理论的同时,及时地检验学习的效果。这篇文章我就来介绍在毕业项目中我学到了什么,顺便揭秘所谓“搜索引擎的核心技术”。数据库

一个网页搜索引擎主要有四个部分组成。分别是自动下载网页的爬虫、对网页创建索引、衡量网页的质量和评价网页和查询的相关性。首先我必须明确提出的是,毕业项目实现的是一个文本搜索引擎,和网页搜索引擎有必定差异。好比:文本搜索引擎无需经过爬虫遨游互联网下载网页,与之对应的是遍历硬盘上的文本文件;另外一个差异是文本搜索引擎无法像网页那样使用PageRank算法衡量网页的质量,PageRank算法是Google的两位创始人共同发明的,其核心思想是利用链接不一样网页的URL,若是有不少高质量的网页指向这一网页,那么说明这个网页也是一个高质量的网页,文本文件没有连接,所以不能应用PageRank算法。缓存

即使文本搜索引擎和网页搜索引擎有必定差别,但目标仍然是同样的。给定一个关键词或者是一句话做为查询(query),找到包含这个关键词或者这句话的文档,同时要求与查询越相关的文档排名越靠前。服务器

完成毕业项目的第一个难点就是理解文本搜索引擎的框架,这样在完成每个部分的时候,才能清楚你在作什么。数据结构

除去自动下载网页的爬虫和评价网页和查询的相关性,文本搜索引擎的核心就只包含对文档创建索引和评价文档与查询相关性两个组件了。下面我将介绍这两个组件是如何在这7个部分中完成的。框架

对文档创建索引函数

在正式进入话题以前,须要消除一个误解。搜索引擎搜索网页并非实时地检索整个互联网,如今完整请求一个网页就须要花费将近1秒,搜索引擎可以如此之快的返回结果,这是不现实的。取而代之的是,搜索引擎在数据库里创建了一个索引。学习

对文档创建的索引有两个。第一个索引是原封不动地把文档的内容存储到数据库里,就像“百度快照”同样,百度在它的服务器上,保存了一份网页的副本,若是网页没法打开,你仍然能够浏览这份副本。这对应于毕业项目的第2个部分,其实对于文本搜索引擎或者说在这个项目里,这个“快照”并无起到什么做用。搜索引擎

不一样文档的长度是不相同的,如何高效地存储是一个须要解决的问题。这在项目的要求中已经明确的给出了。分两个文件存储,第一个文件连续存储文档的内容,第二个文件存储每个文档在第一个文件当中的起始位置。第二个文件的每个记录就是定长的了,所以能够在常数时间内,获取文档的起始位置和结束位置。

第二个索引是倒排索引(inverted index)。倒排索引是搜索引擎如此之快的一个核心原理。对于一篇文档,包含语义的基本元素是一个个的单词。处理文档的第一步就是将文档分割为一个个的单词,这是毕业项目的第1部分。在中文里,单词之间并无明确的分隔符,分割单词须要涉及到天然语言处理。好在毕业项目所涉及的搜索引擎是一个英文的搜索引擎,英文单词之间有自然的空格分割,第1部分就是利用空格或者是标点符号做为分隔符,分割成单词,术语叫作Token。Token不只仅是单词,还包括单词出现的位置,这有助于判断两个单词是否相邻,提高搜索结果的相关性,在毕业项目中虽然保存了单词出现的位置但在搜素的时候并无使用这一信息。

倒排索引是一个表格,第一列是全部文档里出现的单词,第二列是由多个元组组成的列表,元组的第一项是文档编号,第二项是该文档中这个单词出现的次数,又叫作文档频率(text frequency)。有了倒排索引,在检索一个单词的时候,就无需遍历全部文档了,搜索倒排索引就能找到包含这个单词的文档。存储倒排索引就是毕业项目第3部分须要完成的内容,与存储原始文档面临的相同问题是,倒排索引也是不定长的,所以须要像存储原始文档那样,分两个表来存储。这就是创建索引的所有了。

评价文档与查询相关性

检索一般不是一个单词而是一个短语,短语中包含多个单词。好比个人检索词是“百度公司”,只要是介绍一个公司的文档就会包含“公司”这个单词,可是只有涉及“百度”的文档才会出现“百度”这个单词。这说明不一样单词的重要性不一样的,搜索引擎须要关注检索词中特殊的词语才能找到最相关的文档。系统性衡量单词重要性的指标是反转文档频率(inverse docuement frequency)。它经过公式log(1/df)计算获得,df表示文档频率(docuement frequency),是出现该单词文档的次数。与文档频率成反比意味着一个单词在不一样文档中出现的次数越多,越不重要,像“这”、“我”这些词汇,几乎会出如今每个文档里,能够说彻底不重要。这些词称为中止词(stop words)。
文档与查询的相关性就能够用一篇文档检索词出现的次数乘以反转文档频率tf×idf表示(又记做tf-idf),若是一篇文档出现了多个检索词,那么就是全部这些检索词的tf-idf之和。计算tf-idf即是毕业项目第4部分须要完成的任务。

一个检索词在一篇文档出现的次数能够经过查询倒排索引获得,若是一篇文档出现了一个单词,那么倒排索引在那个单词的记录中就会包含这个记录。只有出现这一单词的文档才会出如今倒排索引对应单词的记录中,文档的范围就大大减小了。在毕业项目里,倒排索引保持字典序,在检索一个单词的时候就可使用二分搜索,这就是毕业项目第5部分须要完成的任务。

正如以前所说的,检索词能够是一个短语,根据不一样搜索引擎的设计,短语中的单词能够要求同时出如今一个文档中,也能够要求至少出现一个单词。这对应两种组合多个单词构成最后检索结果的方法,相与和相或。更进一步,还能够要求搜索引擎不出现某一个关键词,在百度中能够经过一个减号“-”来表示。好比我想搜索“电子科技大学”,但不是“西安电子科技大学”,就能够输入“电子科技大学 -西安”。这些组合方式在数学上来讲,其实就是集合操做。三种基本的集合操做“与”、“或”、“非”正对应着这三种组合方式。这就是毕业项目的第6个部分

毕业项目的第7个部分是表达式求值的一个变种。在百度或者Google中,其实能够明确指出,多个单词之间是或的关系仍是与的关系。好比:我想要搜索“北京”或者“大学”,可使用检索词“北京 | 大学”,单词之间用竖线链接;若是想要同时检索“北京”和“大学”,可使用检索词“北京 & 大学”,单词之间用&链接。当检索词由多个单词相与、相或组成复杂的逻辑表达式,就须要专门的函数来处理这种复杂的检索了。好比检索词是“北京 - 北京 & 大学 - 清华”,表示我想查找北京的信息,可是不想看到北京大学或者清华大学的信息。这仍然是一个表达式求值的问题,可是不一样的是,表达式的值并非直接求出,而是被表达成一组复合的检索关系。这就是毕业项目的7个部分了,是否是并无想象的那么难。

完成了这个专项课程的毕业项目,我也能够说是,实现过搜索引擎的人了,虽然这个搜索引擎是最最简单的版本。在这个过程当中,搜索引擎的面纱也被一步步揭开,你会发现搜索引擎也不过如此嘛。

可是搜索引擎其实远不止如此,百度和Google为了加快检索的速度、提升搜索的相关性,还作出了不少的努力。好比缓存经常使用的搜索结果,搜索结果反做弊。

知识虽然漫漫无穷,值得咱们用一辈子去学习,但事物的本质与核心思想始终是简洁的。

相关文章
相关标签/搜索