《这就是搜索引擎》读书总结
这些天在为以后工作做一些知识储备,所以想从总体上大致了解下搜索引擎的知识框架同时对较为重要的部分有个较为深入的了解。记得在微博上看到有人推荐张俊林同学的这本书,豆瓣上总体评价也不错就买来看了。这篇博客是对一个多月看此书的总结,第二部分用自己的话总结了搜索引擎的知识主线,其中结合了看书的笔记。
1 关于书的评价
总体评价的话,此书在讲解具体算法的流程的时候花了很多心思,印象最深刻的是,几乎所有算法都有图例,这一点可看出作者是下了很大功夫的。每章后面都付了本章的参考论文,虽然都是英文论文,但都是相关算法较为权威的参考文献,这点也做得不错,对于不懂的算法可以继续看论文。不足的话,主要感觉的一点是,对于某些具体算法,讲的不是特别深入,一般讲完一个算法的产生背景、是怎样一个算法步骤以及该算法的优缺点就结束一个算法的讲解了。在这一点我不敢苟同,因为有很重要的一点没有讲,那就是why,为什么这个算法是这样的,它用到了哪些关键的思维方法和思想。记得在看PageRank算法时,在看明白图例后,在想为什么会想到这样一个思路?为什么它可以收敛?如果能够多一点作者自己的思考会更好些,不过总体上看,这本书写的还是不错的,值得推荐。
2 书中主要知识总结(用白话总结搜索引擎的主线知识)
看完这本书后,让我对搜索引擎的整体框架有了一个了解,具体来说搜索引擎本质上是为了满足用户获取互联网上特定信息的需求而产生的。整个搜索引擎知识的主线可以由网页获取、索引生成和排名以及用户搜索交互等三个方面来理解。
2.1 网页获取--爬虫 书中第二、十章
自然的,搜索引擎的首要任务便是先尽可能地获取互联网上的信息:各种网页,这个由爬虫(Web Crawler)来完成。谈到爬虫就要说一下爬虫禁抓协议,这个是由网站所有者生成的一个指定文件robot.txt并放在网站根目录下,这个文件指明了网站中哪些目录下的网页是不允许爬虫抓取的(这个让我想起了之前一淘和京东等的口水战)。爬虫有三个很重要的指标:抓取网页的重要性、时效性和覆盖率。爬虫在抓取网页时有一定策略,也就是说以什么样的顺序从URL队列取出URL来解析,这就有了爬虫的四种抓取策略:宽度优先、非完全PageRank、在线页面重要性计算和大站优先等。爬虫不仅仅要去抓取“光天化日下”的网页,也要负责拿到暗网的页面,什么是暗网?暗网是指目前搜索引擎爬虫按照常规方式很难抓取到的互联网网页,例如需要通过组合查询得到的机票数据页面。这些页面经常要进行查询组合和文本框填写。目前大型商业搜索引擎都不可能用单机爬虫去完成网页的抓取任务,网页数据量实在太大,单机效率太低,目前用的都是分布式爬虫,其又分主从式和对等式两种。
爬虫阶段有一个问题需要解决,如果爬到了相同的网页怎么办?总不能用户查询一个最近火热的关键词,搜索引擎返回的都是内容相同的网页吧?这样的用户体验肯定非常不好。本书第十章便是讲解如果检测网页重复的。判断网页重复肯定不能用字符串一个个匹配,这个效率低和穷举没两样,常用的网页去重算法一般来说包括三个阶段:特种抽取、文档指纹生成和相似性计算。所以,好的解决方案是为这些字符生成所谓的指纹,然后比较指纹以免去字符串比较这么一个效率低下的办法。书中讲了4种典型的去重算法:Shingling算法、I-match算法、SimHash算法(目前效果最好的)、SpotSig算法。这里介绍前两种:
Shingling算法:
- 特征抽取:将文档中出现的连续单词序列作为一个整体,为方便后续处理,对这个单词片段进行哈希计算,形成一个数值,每个单词片段对应的哈希值成为一个Shingling,而文档的特征就是由Shingle构成的;
- 指纹生成:为了提高效率,可以使用多个哈希函数,将文档特征映射到固定大小;
- 相似度计算:使用Jaccard相似性计算;
I-Match算法:
- 特征抽取:事先计算出一个全局的特征词典,根据大规模的语料进行统计,对语料中出现的所有单词,按照单词的IDF值进行由高到低的排序,之后去除掉一定比例的IDF得分过高及得分过低的单词,保留得分处于中间段的单词作为特征词典;
- 指纹生成:对于需要去重的网页,扫描一遍即可获得在该页面中出现过的所有单词,对于这些单词,用特征词典过滤,保留特征词典中出现过的单词,以此作为表达网页内容的特征,之后利用哈希函数(SHA1)对文档的所有特征词汇整体进行哈希计算,得到一个唯一的哈希值,以此哈希值作为该网页的信息指纹;
- 相似度计算:比较哈希值,相等则相同;
- 缺点:短文本容易误判;稳定性不好。这些都是因为算法对于文档内容过于敏感,严重依赖于特征词典的选择,为了减少这种依赖性,可以考虑同时使用多个特征词典,这样如果这多个词典有一个判定相同就相同;
2.2 索引生成和排名 书中第三、四、五、六、七章
得到网页之后,是不能直接给用户搜索查询提供服务的,因为要满足用户查询,必须在短时间内返回搜索结果,所以对于网页存储的方法以及排名的方法都有讲究,否则不可能满足大规模并发和高效的查询。从本阶段涵盖的章节数可以看出这一阶段的重要性,这一阶段做的好坏可以有效说明这个搜索引擎是否优秀。一个好的商业引擎,必须有一个好的索引生成、压缩和提取算法,同时还必须有一个好的排名算法。
2.2.1 索引的生成
先谈索引,索引的主要形式是倒排索引。倒排索引是搜索引擎用来快速查找包含某个单词的文档集合的数据结构,其由单词词典和所有单词对应的倒排列表组成。单词词典:搜索引擎通常的索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向倒排表的指针,它的常用数据结构是:哈希加链表结构和树形词典结构(B/B+)。倒排列表由倒排列表项构成,一般倒排列表项包含文档ID、单词磁盘和单词在文档出现的位置,文档ID可能采取文档编号差值的编码方式以减少数值大小。创建索引的方法有:两遍文档遍历法、排序法以及归并法。
- 两遍文档遍历法:此法对文档集合扫描两遍,第一遍扫描文档集合时先不建立索引,而是收集一些全局的统计信息,例如文档集合的文档总数、文档集合内包含的不同单词个数、每个单词在多少个文档出现过(DF)等。将所有单词对应的DF值相加就可以知道为索引分配多少内存,有了这些信息可以为索引分配足够内存,同时将内存划分成不同大小的片段(以单词为单位),所以第一遍主要是做一些准备工作;第二遍扫描的时候,就真正建立每个单词的倒排表信。缺点:此法完全在内存中完成,所以对内存容量要求大,而且需要将文档读入内存两次速度上也不好;
- 排序法:对两遍法做了改进,始终在内存中分配固定大小的空间,用来存放词典信息和索引的中间结果,当分配空间被消耗光时,把中间结果写入磁盘,清空内存里中间结果所占内存,可见其内存需求是固定值,所以可对任意大小的文档集合建立索引。读入文档后,对文档进行编号,赋予唯一的文档ID,并对文档内容进行解析。对于文档中出现的单词,通过查词典将单词转换为对应的单词ID,如果词典中没有这个单词,说明是第一次碰到,则赋予单词以唯一的单词ID并插入词典。可对文档内每个单词建立三元组(单词ID、文档ID、单词频率),直到存储空间满,就按单词ID为主键,文档ID为此键对中间结果进行排序,将排好序的三元组写入磁盘,这时可清空内存以应对下一次处理。最后,需要对中间结果进行合并,由于已经按单词ID排序,所以直接归并即可。缺点:由于词典信息需要一直在内存中维护,所以其占内存会越来越多,导致后期中间结果所用内存变小,可能会致使频繁的排序和写入磁盘;
- 归并法:流程与排序法大致相同,其在内存中建立一个完整的内存索引结构,相当于对目前处理的文档子集单独在内存中建立起一整套倒排索引,和最终索引相比,其结构和形式是相同的,区别只是这个索引只是部分文档的索引。(即没有单词ID,直接以单词做第一列),最后归并是对每个单词的倒排列表合并。
这三种的每一种都是为了改进前一种方法的缺点而产生的。不过这些都是静态索引,但是由于文档集合是动态变化的,所以需要建立动态索引。动态索引包含临时索引和原倒排索引。对于动态所以的更新策略有四种:完全重建、再合并策略、原地更新策略以及混合策略。
- 完全重建策略:当新增文档到达一定数量,将新增文档和原先的老文档整合,然后利用静态索引创建方法对所有文档重建索引,新索引建立完成后老索引会被遗弃。此法代价高,但是目前主流商业搜索引擎一般是采用此方式来维护索引的更新(这句话是书中原话)
- 再合并策略:当新增文档进入系统,解析文档,之后更新内存中维护的临时索引,文档中出现的每个单词,在其倒排表列表末尾追加倒排表列表项;一旦临时索引将指定内存消耗光,即进行一次索引合并,这里需要倒排文件里的倒排列表存放顺序已经按照索引单词字典顺序由低到高排序,这样直接顺序扫描合并即可。其缺点是:因为要生成新的倒排索引文件,所以对老索引中的很多单词,尽管其在倒排列表并未发生任何变化,也需要将其从老索引中取出来并写入新索引中,这样对磁盘消耗是没必要的。
- 原地更新策略:试图改进再合并策略,在原地合并倒排表,这需要提前分配一定的空间给未来插入,如果提前分配的空间不够了需要迁移。实际显示,其索引更新的效率比再合并策略要低。
- 混合策略:出发点是能够结合不同索引更新策略的长处,将不同索引更新策略混合,以形成更高效的方法。
对于有结构的文档(包含标题、正文等)其是含有多个字段的,区分不同字段对于搜索引擎是有意义的,这便是多字段索引。实现多字段索引有三种方式:多索引、倒排列表和扩展列表。
- 多索引方式:针对不同字段分别建立一个索引;
- 倒排列表方式:将字段信息存储在某个关键词的倒排表中,这样读出用户查询关键词的倒排列表的同时,就可以根据字段信息,判断这个关键词是否在字段出现过,例如包含“标题”、“摘要”、“正文”等字段的页面,可以使用3个比特位来表示等;
- 扩展列表方式:实际用得较多。这个方法为每个字段建立一个列表,这个列表记载了每个文档这个字段对应的出现位置信息。
同样,索引也需要进行分布式的处理,常见的分布式索引方案包括:按文档对索引划分和按单词对索引划分。
2.2.2 Ranking(排名)
对于排名,大家首先想到的应该是著名的PageRank算法,这个算法源于Google的创始人,是一种非常著名的链接分析算法。谈到排名,总体上,搜索引擎对文档排名由两方面影响,一是文档和用户查询的内容相似性,越高则应该越相关,排名越靠前;二则是链接分析的计算值,它主要用来测评网页的重要性,同样相关的网页,重要性可不同,这个通过链接来分析。这两点共同构成了对网页排名的主要因素。
2.2.2.1 网页内容相似性计算
内容的相似性计算由搜索引擎的检索模型建模,它是搜索引擎的理论基础,为量化相关性提供了一种数学模型,否则没法计算。当然检索模型理论研究存在理想化的隐含假设,即假设用户需求已经通过查询非常清晰明确地表达出来了,所以检索模型的任务不牵扯到对用户需求建模,但实际上这个和实际相差较远,即使相同的查询词,不同用户的需求目的可能差异很大,而检索模型对此无能为力。几种常见的检索模型有:
- 布尔模型:数学基础是集合论,文档和用户查询由其包含的单词集合来表示,两者的相似性则通过布尔代数运算来进行判定;缺点是其结果输出是二元的(相关和不相关),无法得出多大程度相关的结果,也就无法排序,同时让用户以布尔表达式进行搜索要求过高;
- 向量空间模型:把文档看成是由t维特征组成的一个向量,特征一般采用单词,每个特征会根据一定依据计算其权重,这t维带有权重的特征共同构成了一个文档,以此来表示文档的主题内容。计算文档的相似性可以采用Cosine计算定义,实际上是求文档在t维空间中查询词向量和文档向量的夹角,越小越相似;对于特征权重,可以采用Tf*IDF框架,Tf是词频,IDF是逆文档频率因子指的是同一个单词在文档集合范围的出现次数,这个是一种全局因子,其考虑的不是文档本身的特征,而是特征单词之间的相对重要性,特征词出现在其中的文档数目越多,IDF值越低,这个词区分不同文档的能力就越差,这个框架一般把Weight=Tf*IDF作为权重计算公式,当然向量空间的缺点是其是个经验模型,是靠直觉和经验不断摸索和完善的,缺乏一个明确的理论来引导其改进方向,例如求Tf和IDF值的时候为了惩罚长文档,都需要加入经验值;
- 概率模型:是目前效果最好的模型之一,okapi BM25这一经典概率模型计算公式已经在商业搜索引擎的网页排序中广泛使用。概率检索模型是从概率排序原理推导出来的,其基本思想是:给定一个用户查询,如果搜索系统能够在搜索结果排序时按照文档和用户需求的相关性由高到底排序,那么这个搜索系统的准确性是最优的。在文档集合的基础上尽可能准确地对这种相关性进行估计就是其核心。
- 语言模型:1998年首次提出,其他的检索模型的思考路径是从查询到文档,即给定用户查询,如何找出相关的文档,该模型的思路正好想法,是由文档到查询这个方向,即为每个文档建立不同的语言模型,判断由文档生成用户查询的可能性有多大,然后按照这种生成概率由高到低排序,作为搜索结果。语言模型代表了单词或者单词序列在文档中的分布情况;
- 机器学习排序算法:随着搜索引擎的发展,对于某个网页进行排序需要考虑的因素越来越多,这是无法根据人工经验完成的,这时候用机器学习就是非常合适的,例如Google目前的网页排序公式考虑了200多种因子。机器学习需要的数据源在搜索引擎中较好满足,例如用户的搜索点击记录。其分成人工标注训练、文档特征抽取、学习分类函数以及在实际搜索系统中采用机器学习模型等4个步骤组成。人工标注训练可由用户点击记录来模拟人为对文档相关打分的机制。
评价搜索引擎检索模型常用指标有精确率、召回率、MAP和P@10等。精确率是指本次搜索结果中相关文档所占比例,分子为本次搜索结果中的相关文档,分母为本次搜索结果包含的所有文档。召回率则是说本次搜索结果中包含的相关文档占整个集合中所有相关文档的比例。其用于评价搜索系统是否把该找出的文档都找出来了。P@10:排在搜索结果最靠前的头10个文档有多大比例是相关的。对于搜索引擎来说,精确率尤为重要,因为搜索引擎处理海量数据,要找到所有相关文档可以有很多,全部召回相关文档对于满足用户需求意义不是很大,相反精确率就很重要,因为排在搜索列表前列的搜索结果如果有太多不先关的内容会直接影响用户体验。
2.2.2.2 链接分析
链接分析算法是排名中另一个非常重要的因素,为什么要分析链接?The PageRank citation ranking:bringint order to the Web这篇论文中说源自评判论文重要性看引用数量的习惯,这里的引用数量可以理解为入链,入链多且入链的源头质量越高(例如SCI一区等大名鼎鼎的杂志文章等)说明本文章质量越高,那么类比的思想用过来就产生了链接分析的算法。论文中还说曾经有人利用这个论文的引用分析下一届诺贝尔奖获得者,由此可见一斑。那么常见的链接分析算法除了鼎鼎有名的PageRank,还有HITS、SALSA、Hilltop以及主题PageRank等等。需要重点理解的是PageRank和HITS,后面这些算法都是以它们为基础的。
绝大部分链接分析算法建立在两个概念模型,它们是:
- 随机游走模型:针对浏览网页用户行为建立的抽象概念模型,用户上网过程中会不断打开链接,在相互有链接指向的网页之间跳转,这是直接跳转,如果某个页面包含的所有链接用户都不感兴趣则可能会在浏览器中输入另外的网址,这是远程跳转。该模型就是对一个直接跳转和远程跳转两种用户浏览行为进行抽象的概念模型;典型的使用该模型的算法是PageRank;
- 子集传播模型:基本思想是把互联网网页按照一定规则划分,分为两个甚至是多个子集合。其中某个子集合具有特殊性质,很多算法从这个具有特殊性质的子集合出发,给予子集合内网页初始权值,之后根据这个特殊子集合内网页和其他网页的链接关系,按照一定方式将权值传递到其他网页。典型的使用该模型的算法有HITS和Hilltop算法。
PageRank算法:
1997年由Google创始人之一Larry Page提出的链接分析算法,PageRank基于以下两个基本假设:数量假设:在Web图模型中,如果一个页面节点接收到的其他网页指向的入链数量越多,那么这个页面越重要;质量假设:指向页面A的入链质量不同,质量高的页面会通过链接向其他页面传递更多的权重。所以越是质量高的页面指向页面A,则页面A越重要;PageRank算法刚开始赋予每个网页相同的重要性得分,通过迭代递归计算来更新每个页面节点的PageRank得分,直到得分稳定为止。PageRank算法计算得出的结果是网页的重要性评价,这和用户输入的查询是没有任何关系的,即算法是和用户查询无关的。
步骤如下:
- 初始阶段,每个页面设置相同的PageRank值,以后这个值会不断更新;
- 在一轮更新页面PageRank得分的计算中,每个页面将当前的PageRank值平均分配到本页面包含的出链上,这样每个链接即获得了相应的权值。而每个页面将所有指向本页面的入链所传入的权值求和,即可得到新的PageRank得分。当每个页面都获得了更新后的PageRank值,就完成了一轮PageRank计算。
PageRank有时会出现链接陷阱,这时可用远程跳转解决,所谓远程跳转是指:在网页向外传递分值时,不限于向出链所指网页传递,也可以以一定的概率向任意其他页面跳转。
HITS算法:
全称是Hypertext Induced Topic Selection,是链接分析中非常基础且重要的算法。
算法中有两个关键概念:
- Authority页面:与某个领域或者某个话题相关的高质量网页;
- Hub页面:包含了很多指向高质量Authority页面链接的网页,例如hao123;
该算法通过一定技术手段,在海量网页中找到与用户查询主题相关的高质量Authority页面和Hub页面,尤其是Authority页面。该算法的基本假设是:
- 一个好的Authority页面会被很多好的Hub页面指向;
- 一个好的Hub页面会指向很多好的Authority页面;
步骤:
- 收到用户查询之后,将查询提交给某个现有的搜索引擎(或者自己的检索系统),并在返回的搜索结果中,提取排名靠前的网页,得到一组与用户查询高度相关的初始网页集合,这个集合被称为根集(Root Set);
- 然后HITS算法在根集的基础上进行扩充,原则是凡是与根集有直接链接指向关系的网页都被扩充进来,这是形成了扩展网页集合;
- 对于扩展网页集合,对每个网页都设立两个权值,分别用来记载这个页面是好的Hub页面或者Authority页面的可能性,初始可设为1;
- 之后进行迭代计算,更新方式是假设以A(i)代表i的Authority权值,H(i)代表某网页的Hub权值,计算方式是A(1)=H(2)+H(3)+H(4),H(1)=A(5)+A(6)+A(7);(1指向5,6,7而,2,3,4指向1)
- 如此更新直到稳定为止;
HITS缺点:
- 计算效率低,都需要在线计算,不如PageRank的离线计算;
- 主题漂移问题,可能给予与搜索主题无关网页而有较多链接指向的页面很高的排名;
- 易被作弊者操纵结果:可以设立一个网页,页面内容增加很多指向高质量网页或者著名网站的网址,这样形成一个很好的Hub页面,之后作弊者再将这个网页链接指向作弊网页;
- 结果不稳定:如果添加删除个别网页或者改变少数链接关系,排名结果会有很大变化;
与PageRank算法比较:
- HITS与查询密切相关,而PageRank无关;
- HITS计算效率低,PageRank可以进行离线计算,所以效率高;
- HITS算法只对扩展集合做计算,所以计算对象小,PageRank是全局性的,所以计算对象大;
- HITS比PageRank易受作弊者影响;
曾经有人说搜索引擎的研究是互联网公司很好的技术储备,这点不错,因为搜索引擎的研究和开发中会遇到非常多的大规模数据量计算和存储的问题(数以亿计的网页数据),这直接推动着云计算和云存储的研究,作为世界上最大最牛的搜索引擎Google也是云计算和云存储研究最早和目前最牛的企业之一。本书第七章介绍了一些云计算和云存储的知识。
2.3 用户搜索、交互和体验 书中第八、九、十一章
有了以上两个阶段的铺垫,接下来就可以响应用户的请求了,这一阶段要处理的问题有以下几个:
- 如何更好的明白用户查询的需求?有时候用户自己都不知道搜索什么词去表达自己想要获取的信息或者表达不完全不够清楚,这个时候就需要利用用户查询意图分析的一些方法去解决(本书第九章);
- 用户查询后每次都需要通过链接分析计算和内容相似性计算生成结果后再返回给用户查看吗?这会多么耗时!在计算机系统里面,缓存就会派上用场了,例如cpu和主存之间的cache,数据库中的cache等,几乎随处可见缓存的影子。同样,搜索引擎也可以有缓存(本书第十一章);
- 关于搜索引擎有一个叫SEO(搜索引擎优化)的东东,有一些站长希望提高自己网站在搜索引擎中的排名,使用这些技术,本来说无可厚非,但是却被不法分子利用,将一些垃圾网站的排名搞上去,这个直接影响用户的搜索体验,从此网页作弊和反作弊开始了一场持久战,本书第八章讲述这些知识。
由于篇幅关系,这三个方面本文不展开白话,内容实在太多,不过比起之前的爬虫、索引和排名这些相对不那么重要。
3 后记
总的来说很感谢本书作者的辛苦耕耘,这本书在国内计算机专业书来说质量应该是上乘的,一来作者专业背景深厚,二来作者写此书确实阅读了大量文献(从每章后面附的各种论文可以看出),花了很多心血,如果国内能多些这样的书该多好。关于搜索引擎的学习不能局限于书本,这些算法都是死的,需要不断的实践和再总结,其实整个计算机的学习都是如此。
参考文献:
《这就是搜索引擎》--核心技术讲解 作者:张俊林