构建好倒排索引之后,就可以开始检索了。

检索模型有很多,比如向量空间模型、概率模型、语言模型等。其中最有名的、检索效果最好的是基于概率的BM25模型。

给定一个查询Q和一篇文档d,d对Q的BM25得分公式为:

公式中变量含义如下:

qtf:查询中的词频

tf:文档中的词频

ld:文档长度

avg_l:平均文档长度

N:文档数量

df:文档频率

b,k1,k3:可调参数

这个公式看起来很复杂,我们把它分解一下,其实很容易理解。第一个公式是外部公式,一个查询Q可能包含多个词项,比如“苹果手机”就包含“苹果”和“手机”两个词项,我们需要分别计算“苹果”和“手机”对某个文档d的贡献分数w(t,d),然后将他们加起来就是整个文档d相对于查询Q的得分。

第二个公式就是计算某个词项t在文档d中的得分,它包括三个部分。第一个部分是词项t在查询Q中的得分,比如查询“中国人说中国话”中“中国”出现了两次,此时qtf=2,说明这个查询希望找到的文档和“中国”更相关,“中国”的权重应该更大,但是通常情况下,查询Q都很短,而且不太可能包含相同的词项,所以这个因子是一个常数,我们在实现的时候可以忽略。

第二部分类似于TFIDF模型中的TF项。也就是说某个词项t在文档d中出现次数越多,则t越重要,但是文档长度越长,tf也倾向于变大,所以使用文档长度除以平均长度ld/avg_l起到某种归一化的效果,k1和b是可调参数。

第三部分类似于TFIDF模型中的IDF项。也就是说虽然“的”、“地”、“得”等停用词在某文档d中出现的次数很多,但是他们在很多文档中都出现过,所以这些词对d的贡献分并不高,接近于0;反而那些很稀有的词如”糖尿病“能够很好的区分不同文档,这些词对文档的贡献分应该较高。

所以根据BM25公式,我们可以很快计算出不同文档t对查询Q的得分情况,然后按得分高低排序给出结果。

下面是给定一个查询句子sentence,根据BM25公式给出文档排名的函数:

defresult_by_BM25(self,sentence):

seg_list=jieba.lcut(sentence,cut_all=False)

n,cleaned_dict=self.clean_list(seg_list)

BM25_scores={}

fortermincleaned_dict.keys():

r=self.fetch_from_db(term)

ifrisNone:

continue

df=r[1]

w=math.log2((self.N-df+0.5)/(df+0.5))

docs=r[2].split('\n')

fordocindocs:

docid,date_time,tf,ld=doc.split('\t')

docid=int(docid)

tf=int(tf)

ld=int(ld)

s=(self.K1*tf*w)/(tf+self.K1*(1-self.B+self.B*ld/self.AVG_L))

ifdocidinBM25_scores:

BM25_scores[docid]=BM25_scores[docid]+s

else:

BM25_scores[docid]=s

BM25_scores=sorted(BM25_scores.items(),key=operator.itemgetter(1))

BM25_scores.reverse()

iflen(BM25_scores)==0:

return0,[]

else:

return1,BM25_scores

首先将句子分词得到所有查询词项,然后从数据库中取出词项对应的倒排记录表,对记录表中的所有文档,计算其BM25得分,最后按得分高低排序作为查询结果。

类似的,我们还可以对所有文档按时间先后顺序排序,越新鲜的新闻排名越高;还可以按新闻的热度排序,越热门的新闻排名越高。

关于热度公式,我们认为一方面要兼顾相关度,另一方面也要考虑时间因素,所以是BM25打分和时间打分的一个综合。

比较有名的热度公式有两个,一个是Hacker News的,另一个是Reddit的,他们的公式分别为:

可以看出,他们都是将新闻/评论的一个原始得分和时间组合起来,只是一个用除法,一个用加法。所以我们也依葫芦画瓢,”自创“了一个简单的热度公式:

用BM25得分加上新闻时间和当前时间的差值的倒数,k1k1和k2k2也是可调参数。

按时间排序和按热度排序的函数和按BM25打分排序的函数类似,这里就不贴出来了,详细情况可以看我的项目News_IR_Demo。

至此,搜索引擎的搜索功能已经实现了,你可以试着修改./web/search_engine.py的第167行的关键词,看看搜索结果是否和你预想的排序是一样的。不过由于我们的数据量只有1000个新闻,并不能涵盖所有关键词,更多的测试可以留给大家线下完成。

基于python的搜索引擎论文_技术分享 - 基于python构建搜索引擎系列——(四)检索模型...相关推荐

  1. python缺少标准库_干货分享:Python如何自动导入缺失的库

    很多同学在写Python项目时会遇到导入模块失败的情况:ImportError: No module named 'xxx'或者ModuleNotFoundError: No module named ...

  2. python定期自动运行_干货分享 | 适合 Python 入门的 8 款强大工具,不会就你还不知道吧!...

    点击上方"人工智能Corner","星标或置顶公众号" 干货分享,第一时间送达 Python是一种开源的编程语言,可用于Web编程.数据科学.人工智能以及许多科 ...

  3. sql 拆分_技术分享 | 基于分布式中间件的SQL改造指南

    原创作者: 孙正方 4月12日,GOPS全球运维大会在深圳隆重召开,全球运维大会是国内第一个运维行业大会,爱可开源社区在基础架构及DevOps解决方案专场分享了<基于分布式中间件的SQL改造指南 ...

  4. 银行客户用户画像_技术分享 | 基于数据中台的银行客户画像体系构建

    背景 1.金融消费行为的改变,企业无法接触到客户 80后.90后总计3.4亿人口,日益成为金融企业主要的消费者,但是他们的金融消费习惯正在改变,他们不愿意到金融网点办理业务,不喜欢被动接受金融产品和服 ...

  5. python实现oa系统_技术讨论 | 利用Python程序实现某OA系统的自动定位

    前言 本文介绍了笔者通过python程序实现某OA系统自动考勤打卡功能及相关逻辑原理的解析. 声明:本程序仅供Python语言的学习交流用途,笔者不提倡利用程序自动考勤的做法,笔者不对滥用本程序导致的 ...

  6. python应用实例论文_番外篇——Python多进程应用实例一则

    前言: 现在的电脑普遍进入多核时代,当我们需要做一些计算密集型任务时,运用并行计算能够发挥CPU的性能,也够大大的节省我们的时间.在现在的数据挖掘中,Python是一门非常强大的语言,语法直接明了,易 ...

  7. 【华为云技术分享】自动驾驶网络系列四:我们谈自动驾驶网络到底在谈什么?

    很多人第一次接触自动驾驶网络的概念,会理解成--华为怎么搞起汽车来了? 其实还是搞网络产品,就是网络的自动驾驶.那网络的自动驾驶是什么?这个问题,每个人都有自己的理解,接下来我将按照自己的理解来回答一 ...

  8. 【华为云技术分享】MongoDB经典故障系列四:调整oplog大小,引起从库宕机怎么办?

    一不小心调整了自建MongoDB数据库的oplog大小,从而引起从库宕机怎么办?别急,华为云数据库给您支招:一是取消延迟配置,先扩容延时从库的oplog大小,再扩容主库的oplog:二是对主库先降级再 ...

  9. jdbc连接teradata仓库_技术分享:如何基于对象存储打造一个高性能、完全托管的PB级MPP数据仓库...

    本文将介绍北京一家初创企业 HashData 构建基于云原生的 MPP 平台的过程.该企业利用对象存储作为数据持久层,Alluxio 作为云中的数据编排层,最终构建了一个原生云高性能 MPP 共享的体 ...

最新文章

  1. 索引键的唯一性(2/4):唯一与非唯一聚集索引
  2. One-shot Learning with Memory-Augmented Neural Networks
  3. 数据结构与算法--解决问题的方法-顺时针打印矩阵
  4. tensorflow 特征预处理总结
  5. ios中strong和weak的解释理解
  6. stata基本操作(二)
  7. webservice框架 java_JAVA开发Web Service几种框架介绍
  8. ”教你如何抓住短视频时代风口,进行流量红利变现
  9. 海思3516ev300+ imx335 原理图,其他PCB、软件资料齐全
  10. 利用AD13设计PCB的问题总结21-30
  11. 固态硬盘系统经常假死_固态硬盘经常卡死什么情况
  12. 个人八股文集合一、C/C++语言
  13. Andriod7.0之wifi开启流程(含流程框图及流程图)
  14. springboot集成solr实现全局搜索系列
  15. linux调整逻辑卷大小,调整Linux逻辑卷大小
  16. 这个被上帝抛弃的国家,创立了全球一半的科技公司
  17. .net famework 版本过低,请升级至4.6.2或更新版本
  18. lol全队消息怎么发_lol怎么发给所有人 LOL里面怎么给所有人发送消息
  19. “拧毛巾”和“吹泡泡”
  20. 【neutron】Neutron的基本原理与代码实现

热门文章

  1. AQS.transferForSignal
  2. MyBatis 核心对象
  3. 请解释Spring Bean 的生命周期?
  4. BeanFactoryPostProcessor执行时间
  5. Spring对于Bean管理的核心组件
  6. 方法的重写-覆盖父类方法,重写子类方法实现
  7. 构造函数和实例对象之间的关系 构造函数创建对象带来的问题 原型
  8. 常见MOS管型号及参数对照表
  9. 编写自适应高度的 textarea
  10. 熬过了互联网“寒冬”,接下来的金三银四你该怎么面试进BAT?