如何构建一个新闻搜索引擎

首先展示一下项目效果图: 

index

recommend

前言:

本项目会指导大家从零开始开始构建一个针对于新浪新闻的搜索引擎.首先我们明确一下我们的目标和所需要做的工作:

目标:

  • 构建一个搜索引擎 

所需工作:

  • 准备数据
  • 一个搜索引擎的查询算法
  • 一个为每个新闻的推荐其他相似新闻的算法

所以下面我会分这三个部分来介绍这个项目,目前这个项目已经开源.开源的地址:

https://github.com/lsq960124/News_Search_Engine 

欢迎star.

 

准备数据

       打造一个搜索引擎有一个很重要的基础,就是我们需要有满足搜索引擎的数据。我们的目标是打造一个新闻类的搜索引擎,所以我们需要得到新闻的数据。关于得到新闻的数据,我们基于下面的步骤:

  • 首先获取新浪新闻不同业务板块下的新闻页面的所有链接。
  • 循环上面所有的链接爬取其新闻的内容信息。

    以上面的步骤来看,首先我们需要一个新浪新闻链接的爬虫,来爬取新浪新闻对应新闻链接数据。作为一个新闻的搜索引擎,我们希望它不同与百度,新闻类的搜索引擎,应当可以按不同的新闻类别做一定的筛选,比如体育,财经...所以在我们爬取新闻的时候,还需要保存每个新闻对应的类别,也就是频道。

      从新浪新闻的主页可以看到新浪新闻以及帮我们做好了很多新闻类别的分类。得到这个信息后,我们可以以每一个类别对应的根目录作为起始,来爬取这个类别下的所有新闻。我们以体育类别为例子,其根目录为:http://sports.sina.com.cn/。而每个关于体育类别新闻的URL都是类似下面的组成:http://sports.sina.com.cn/china/national/2019-06-04/doc-ihvhiqay3565850.shtml。从这个规律来看,只用关键字“sports.sina”以及类如“2019-06-04”这样的时间表示在这个链接里面,我们就可以确定这个链接为体育类别的链接。通过这个信息,我们可以定制一个深度优先遍历的链接爬虫。

      对了,我们不会将新浪新闻的所有新闻全部爬取,新浪新闻的数据比较多,在这个项目中我们选定2000条作为阈值,每个类别爬取2000就可以满足项目要求了。

      有了思路的支撑,我们就可以撸代码了。代码在git项目中可以查看,这里只展示链接爬虫的结果,我们会得到一个包含所有链接信息的文件 links.txt,如下图:

        在有了链接的本地文件之后,我们只用做一个基于内容的爬虫,就可以爬取到所有关于链接对应的文章标题、内容、发布时间等信息。这里我们加入了一些多线程多进程的方式来加速爬取。将链接爬取到的内容,我们存到数据库中。如图:

     以上是为一个搜索引擎准备数据的过程和思路,在这一部分完成后,我们就要试图来构建一个搜索引擎算法来制作一个搜索引擎了。

 

搜索引擎检索算法

    首先我们以一个常规的思路来想想怎么做一个搜索引擎.

    这可能会是很多人会想到一个办法,当得到用户的输入后,我们和所有的已经爬取到的新闻计算一下相似度,然后对结果排序,这个就能实现一个搜索引擎算法了。这样的算法可行吗?很显然是可行的,但是会遇到一个很严重的问题。

    举个例子,如果爬取到的新闻,不再是这个几万条,而是几百万,几千万。这时候,对每个用户输入,我们还是按照上面的做法,去和所有的数据计算相似度。这个过程是相当费时间的。作为一个搜索引擎,你需要毫秒级的响应速度!这时候,应该怎么做呢?

    我们换一个思路,假如我搜的是”nba的球星",那么搜索引擎返回给用户的内容应当是很多需要涉及到"nba"和"球星"相关的内容新闻,而不会返回一些涉及家庭纠纷,或者国际政治这类无关新闻内容。换句话说,是否有一个算法可以只去计算与输入相关的文档,而抛开一些无关的文档。这样就能加快很多检索的效率。

    有了上面的思路,我们做了这样的解决方案。

    我们提前算出这样一个表,这个表里面存的是所有文档中出现过的单词其所在的文档,如下表:

单词 所在文档的文档编号
nba <2>,<30>,<42>,<55>....,<71>,<993>,<3156>,<4008>
球星 <1>,<5>,<56>,<91>,....,<201>,<655>,<3500>
...  
北京 <9>,<18>,<70>,<120>,....,<980>,<4010>,<9000>

        这样我们在输入nba,球星的时候,我们可以从上面这个表中,知道nba和球星出现在了那些文档中,那么我们只用去和这些文档计算相似度就行了,而其他不包含这些关键字的文档,就会被我们舍去,不去计算。这样对于每个用户的输入,我们的相似度计算都不是全量的,这样节省了很多计算的效率。

      这个思想就是bm25的算法原理。而上面这个表,就是我们意义上的倒排索引表。

    我们再优化一下上面这个表,提出2个想法:

  • 如果一个单词在一篇文章中多次出现,那么他的重要性是高于仅出现过一次的文章的.
  • 如果一个文章很短,出现了一次某单词.和一个文章很长,也出现了一次某单词.那么这个单词在短文章的重要性高于长文章

     上面的两点是很有解释性的,以上面2点的思想我们优化一下上面的表.

单词 <文档标号,出现次数,文档长度>
nba <2,2,10>,<30,1,30>,<42,3,50>,<55,2,34>....<4008,1,20>
球星 <1,1,10>,<5,2,40>,<56,3,15>,<91,5,50>,....,<3500,1,30>
...  
北京 <9,1,34>,<18,2,80>,<70,3,44>,<120,5,24>,....,,<9000,2,60>

         可以看到上面的表中,对于每个单词所在的文档,我们还添加了其出现的词频df,文档的长度length信息。这样我们就可以通过BM25的公式来计算出出现过用户输入过的单词的文档,然后再重新排序,公式如下:

        这就是一个搜索引擎的原理。从上面解释的角度,具体去深究bm25算法的公式,显得没那么有意义,我们重点理解其做到的内容,反而是关键的。最终我们制作的倒排索引表如下图所示:

 

推荐其他相似新闻的算法

     这里你需要一些word2vec的基础知识:https://blog.csdn.net/qq_41664845/article/details/82971728  

      推荐相似新闻的算法上,我们使用到了doc2vec,其实有很多推荐的算法,上面所使用的bm25也是一种可以拿来做现在这里的推荐的一个算法,我们换一个角度想,推荐新闻,在没有用户数据的情况下,做到的也就是通过一个检索算法,算出最相似的几条新闻作为其推荐新闻。

     使用doc2vec在这里是没什么原因的,就是觉得bm25这种虽然快速,但是从原理上更像是基于关键字的检索,而doc2vec是基于神经网络的,可以具备更多的语义信息。而且推荐的过程是离线的,从运行效率上不会要求那么高的效率。

    doc2vec的原理和word2vec基本类似,框图如下:

   在word2vec的基础上,我们加入了一个paragraph id,这样就将文档加入神经网络中训练了,在用户输入时,我们将用户输入转化为对应的向量(转化方式为,单词的词向量做average)这个得到了文档的向量表示。然后通过这个向量,与本地的模型矩阵做推理,这样就能得到相似度最高的几个文档id。 

 

总结:

    在这个知识基础上,我们已经可以搭建好一个属于我们的搜索引擎了,也可以替换别的数据,做一个你喜欢的领域的搜索引擎。当然这个项目还处于很浅显的阶段,入门是可以入门了。最近搜狗的CEO说,搜索引擎的未来在于问答。所以,现在很多的优化方式都可以安装问答机器人的思路来优化。之后我会介绍一下目前我负责搭建的一个问答机器人的项目。


本项目开源地址:https://github.com/lsq960124/Inverted-index-BM25

如果感觉有用,留个赞吧~~

QQ:470581985

微信:lsq960124

打赏一下作者:

      

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章