今天二胖看见一条特别有意思的新闻:在使用谷歌的图片搜索时,如果在图片搜索框里输入 idiot,会出现大量特朗普的照片。
刚看到这条消息的时候,我还有些半信半疑,因为英文单词idiot的中文释义是白痴、傻瓜。谷歌的算法难道出错了,还是有人刻意黑特朗普?所以我自己打开谷歌试了试,果然,事实就是这样,下图便是我亲自搜索 idiot 的结果。
这就非常有意思了,你们考虑过特朗普的感受吗?
后来有消息表明,这并不是谷歌的算法出了问题,而是特朗普的反对者故意用大数据“污染”了谷歌的搜索结果。
今天我们就这个话题来聊一聊搜索引擎的基本原理,我试图用比较简单的语言介绍搜索引擎中一些浅显的概念,因为我自己的了解也并不算深入。
1
搜索引擎与数据
提到搜索引擎,就不得不提全文检索。而在讲全文检索之前,我们先把数据分个类,即结构化数据和非结构化数据。
结构化数据通常指的是那些有固定格式、长度有限制的数据,比如传统关系型数据中的表里存的数据。举个例子:大学的学生信息表就那么几个字段(姓名、学号、性别、年龄、院系、班级....)。
非结构化数据指的就是那些长度无法事先知道、没有固定格式的数据,比如你现在正在读的我的这篇文章,我发布文章的平台事先并不知道文章会写多少字、会分成几段、写中文还是英文。
我们想要在数据库中查找一系列的结构化数据是比较容易的,因为结构化数据都被限定在固定的字段中,每条数据都有唯一的ID,这在关系型数据库中又被称为主键,这个主键和这条数据会事先在数据库中做关联,建立索引。
比如数据库常见的索引方式有平衡二叉树、Hash等,从算法层面来加速数据的查找,做的映射关系是一个ID到一条数据的映射。只要我们知道了这条数据的ID,我们就能拿到这条数据。就像对学生信息数据库而言,我们只要知道了一个学生的学号,就很容易通过学生的学号在极短的时间内查找到该学生的个人信息。
这种索引方式叫做“正向索引”,即利用ID找到某条记录。
上面讲的是查找结构化数据的常用方式,那么对于非结构化数据,我们该如何进行检索呢?
我们先来回忆一下非结构化数据的检索场景。相信大家都用过百度搜索吧,比如我就经常用百度搜索来查看有没有谁抄袭了我的文章。我最常使用的方法就是找出我文章中那些比较有代表性且重复度低的语句去百度搜索,这时候百度就会检索出很多和我使用了“相同语句”的文章。
这里我给大家举个小例子吧,比如我想查找一些网页,且网页中包含了我的公众号名字(大数据前沿)以及我的昵称(二胖)的页面。
如上图所示,百度返回的前几篇文章都是我写的,不知道他们怎么就把我的文章给搞过去了,我也没有授权他们转载。当然,我们今天不讨论侵权的事情,而是全文检索。
用百度搜索文章和查找结构化数据最大的差别是,我们不是使用一个固定的ID去查找某条记录,因为我们并不知道百度内部对某个网页设定的ID是什么,我们检索的结果是某些包含了我们输入的检索词的文章。
这就是查找结构化数据和查找非结构化数据之间最大的差别。
2
搜索引擎与全文检索
前文我们讲了讲查找结构化数据和非结构化数据的区别,下面我们继续聊聊全文检索。
刚才我们只是讲了什么是结构化数据和非结构化数据,还讲了非结构化数据的查找,可是我们没有讲如何查找非结构化数据。
使用过Linux系统的小伙伴应该都知道一个Linux文本查找命令:grep。比如我想知道一个名叫 a.txt 的文本文件中是否包含关键词 “二胖”,那么我可以这样写命令行查询:
cat a.txt |grep 二胖
这其实就是顺序扫描一遍文本文件 a.txt ,查看其中有没有关键词二胖。这是一种很低效的方式,如果你有一个500G的文件,那么你扫描一遍估计需要至少一个小时。
如果你使用百度查找数据,需要一个小时后才给你返回结果,你能忍吗?况且搜索引擎面对的是整个互联网上的公开数据,可不是几百G几千G那么简单,遍历文件的方式是绝对不行的。
所以,有一种新的方式出现了——全文检索。
全文检索指的是先对非结构化数据建立索引,然后再进行搜索。那么问题来了,怎么对非结构化数据建立索引呢?
在前文我们提到了一个词“正向索引”,我还专门加粗飘红了。对于结构化数据,我们建立正向索引即可,但是对于非结构化数据,我们需要建立倒排索引。别慌,我解释一下倒排索引。
比如我写了三篇文章,每篇文章只有一句话,如下所示:
数据入库之前会对文章的内容进行分词处理。比如文章1我用ik分词器(一种开源的中文分词工具)演示给大家看,虽然这个分词器分的不是那么准确:
以下是分词后的结果,二胖被分为了二和胖,扎心了,这个分词器并不是那么好,算是一次失败的分词吧:
可以看到,该分词器把一句话分成了一个个的词,所有的文章都会被分词,然后我们就会得到很多很多的词语。如果我们要记录包含二胖的文档(假设分词很成功),可以采用下面的方式:
上面的表格表示,二胖这个关键词在这三篇文章中的第一篇和第三篇出现了,并且在第一篇文章中出现了两次,位置分别是第0到2个字和第15到16个字。文章三同理。
所以,我们维护着一个很大的表,即词表。词表指明了当前词在哪些文章中出现过多少次、出现的位置等信息。
当我们进行搜索的时候,搜索引擎会对我们输入的关键词先进行分词,比如我前面举的例子,我搜索“大数据前沿 二胖”,搜索引擎很可能会把它分词为“大数据/数据/前沿/二胖”等关键词,然后再去数据库中检索这几个关键词(这个步骤是正向检索,速度很快),拿到这几个关键词的数据后,我们就可以得到包含这些关键词的文章ID。
接下来的事情就是排序了,一般地,含有权重和词频高的词的文章会放在前面。当然,像谷歌、百度这些牛逼的搜索引擎用了什么相关性评分的排序算法我们就不得而知了。
3
图片检索
除了文章,图片也会包含关键词信息。我们在一些平台上传图片的时候,这些平台会要求我们输入一段话对图片进行描述,这些描述同样会被分词,所以图片也被赋予了不少关键词。
现在就可以很好的解释特朗普为什么和 idiot 绑定在一起了,很可能是有人发表了大量包含“idiot”以及“特朗普”等关键词的图片。当然这只是一种猜测啦。
谷歌CEO给出了官方的解释:“我们为您在任何时候输入的关键词提供搜索,我们是谷歌,我们已经在索引中存储了数以十亿计的网络副本。我们获得关键词,将其与网页匹配,根据200多个信号对它们进行排序。”
谷歌的相关性算法还真是复杂,为了保证搜索引擎的准确性,用到了200多个参数。
特朗普还专门因为这件事发了推特吐槽谷歌,不过谷歌表示“我们的算法没有政治情感的感念,我们不带任何政治偏见地对待自己的工作。”
由此可见,谷歌的算法还是很准确的,没有刻意过滤,毕竟不是谁都敢把总统和白痴联系在一起的。
4
讲到这里,文章差不多就要结束了,有些朋友或许还不尽兴,你可能对搜索引擎、中文分词很感兴趣?
那我就要给你推荐一本书了,前谷歌研究员,原腾讯副总裁吴军博士写的《数学之美》(第二版),深入简出地介绍了中文自然语言处理和搜索引擎相关的知识。当当网购书链接奉上,最近五折秒杀,赶快下手吧。
然后,如果你想实践搜索引擎相关技术,我推荐你了解ElasticSearch,我在之前的文章中就推荐过了,你可以参见下面的文章,在这里就不赘述了。
领取专属 10元无门槛券
私享最新 技术干货