上面我们已经说过了一些倒排索引的东西,并且也知道了如何来实现一个倒排索引完成检索功能,那么检索完了以后如何排序呢,这一篇简单的说一下倒排索引的文本相关性排序,因为排序实在是太复杂了,我们这里就说说文本的相关性排序,而且是最简单的TD-IDF排序,之后有机会可以再说说整个搜索的排序算法有些什么。

文本相关性排序

首先明白几个概念:

  • Term,分词以后最小的单位,比如用Golang写一个搜索引擎,分词以后就是golang一个搜索引擎,那么每一个词就是一个Term。
  • TF(Term Frequency),Term在文章中出现的频率,就是当前term在文章中出现的频率,就是term次数/总term数,比如上文中的搜索引擎这个term的TF就是1/5,TF越高那么这篇文章中的这个词就越重要。
  • DF(Document Frequency),文档频率,就是某个Term在总文档中出现的频率,比如总共有100个文档,其中搜索引擎这个term在10个文档中出现了,那么他的IDF就是5/100=0.5。
  • IDF(Inverse Document Frequency),逆文档频率,听名字就知道是和上面的DF是反的,用总文档数除以包含term的文档数,再求对数即可,上面的搜索引擎的IDF是log(100/5)

如何在一堆文章中找到包含关键词的文章,倒排索引技术已经帮我们解决了,只要分词分得准确,那么找文章没什么问题了。问题是找到一堆文章以后怎么进行排序,让最重要的文章排在最前面,这里介绍一下相关性排序。

TF-IDF相关性排序

上面我们看到TF和IDF的概念,TF明显作用就是表示一个term在文章中的重要程度,TF越高那么这个词在文章中的重要程度越明显,IDF呢,IDF主要用来描述term在整体文章中的重要程度(也就是区分程度),IDF越高,那么这个term的整体重要性越高,也就是区分度越大,越能体现这个term的重要性。

为什么用log呢?其实我个人觉得啊,用不用log其实区别没那么大,TF-IDF只是一种计算文本相关度的思想,并不是一个有严格证明的公式,所以用不用log区别不大,不过从信息论的角度看的话,妖人香农提出的信息量的公式就是logX的样子,值越大信息量就越大,正好可以套在我们这,IDF越大,信息量也越大。

信息量是什么大家可以自己去百度,简单描述起来就是某一件事情发生的概率的,如果某件事情发生的概率是P,那么他的信息量就是 -logP,注意有个负号,比如中国队男子足球队和巴西队男子足球队打比赛,假设中国队赢的概率是 0.01(可能高估了),但如果巴西队赢了,根据公式算出来信息量几乎没有,因为谁都知道巴西会赢,但如果(我是说如果)最后中国队赢了,那么信息量算出来就是巨大的,肯定上各个头版了,这也和我们的直觉比较一致,在IDF中,就是用的这个公式,不过吧负号放里面去了,变成了log(1/P),而P就是DF,term在总文档中出现的频率。

TF和IDF合起来表示这个term的相关性,就是把这两个值乘起来。

为什么要把这两个概念合起来呢,第一个TF已经可以描述term的重要性了,为什么还要用IDF呢,主要可以解决两个问题。

  • 去掉高频词的噪音,既然IDF可以简单理解为term的信息量,那么它主要就是为了去掉噪声,也就是去掉那些个信息量很小的term的影响。比如这个词,它的TF非常高,但实际上没什么含义,但是你一算他的IDF,基本是0,所以如果用TF*IDF的话,结果还是0,可以比较有效的去掉这类通用词的干扰。
  • 同时IDF还可以更好的区分重要的词,如果一个term的IDF越高,证明带这个term的文章的更加能用这个term来表示,这个很好理解,如果一个term只在某一篇文章中出现,那么这个词更能代表这篇文章的内容。

最后,多个term联合检索的时候,他们的相关性就是每一个term的TF-IDF加起来,

OK,TF-IDF就是这些了,实现的时候,如果是最初做全量索引的话,由于整体文档数是已知的,那每个term的TF-IDF一般是建立索引的时候就把它算好了,检索的时候按这个一排序就行了,我实现的时候由于没有全量索引的概念,所以只是在每添加一个文档的时候算好这个文档的TF存起来,检索的时候通过term倒排召回的文档数来确定IDF的值,实时算出TF-IDF的,如果是非常巨大的文档数量,那么实时算还是很吃亏的,所以说全量索引还是非常必要的,只是我这没有完整实现全量索引建立而已,但后面接下来我会说说全量索引如何建立。

词距

除了TF-IDF来进行相关性排序以外,还有一些其他的文本因素也可以用在排序上,一是term的距离,也就是词距,如果检索关键词是小米手机,那么明显的,如果一篇文章中这两个term(小米,手机)挨在一起,比如小米手机是一款很热门的手机手机应用中有很多关于健康的文章,比如吃小米有什么好处这两篇文档,明显第一篇的相关度比第二篇要高。

所以,为了保持词距的信息,我们在存储倒排的时候还需要将每个term的位置信息保存下来,检索的时候用过这些个位置信息计算各个词直接的词距,从而和TF-IDF合在一起来表述文本相关性。

位置信息

同时,除了词距以外,还有一个因素也影响相关度的排序,那就是term的位置,这个也很好理解,如果在标题摘要命中的话明显应该比在正文中命中term的权重高,一般这种情况是把标题摘要命中的TD-IDF乘以一个系数来扩大影响,从而影响最后的相关度计算结果。

其他模型

除了直接使用TF-IDF以外,现在还有很多其他的文本相关性的排序模型,比如BM25这种以概率为基础的排序模型,这里就不展开了,如果大家有兴趣,写完这些篇以后可以专门写几篇怎么排序的,包括文本排序,以及文本之后的重要性排序啊,怎么离线利用机器学习计算文档重要性来排序之类的,在说排序的时候我们会说一下如何将这些个所有的东西【文本相关性,词距,位置,重要性,销量,点击等】合起来进行打分

下面一篇文章会再讲讲倒排索引存储的一些我没有实现的东西,比如索引压缩之类的,然后会讲讲如何建立倒排,如果进行增量添加文档,如何进行索引合并。

如果你觉得不错,欢迎转发给更多人看到,也欢迎关注我的公众号,主要聊聊搜索,推荐,广告技术,还有瞎扯。。文章会在这里首先发出来:)扫描或者搜索微信号XJJ267或者搜索西加加语言就行

用Golang写一个搜索引擎(0x05)--- 文本相关性排序相关推荐

  1. 用Golang写一个搜索引擎(0x0B)--- 第一部分结束

    这一篇算给这一个系列告一个小的段落,之前开始写这些文章的时候,只是想把自己最近用Golang写的这个搜索引擎说一说,准备了大概3,4篇的量,但是一写下来,发现有点收不住,写到后面其实和Golang没什 ...

  2. 用 Golang 写一个搜索引擎(0x07)--- 正排索引

    最近各种技术盛会太多,朋友圈各种刷屏,有厂商发的各种广告,有讲师发的各种自拍,各种参会的朋友们各种自拍,好不热闹,不知道你的朋友圈是不是也是这样啊,去年还没这么多技术会议,今年感觉爆发了,呵呵,真是一 ...

  3. 用Golang写一个搜索引擎(0x07)--- 正排索引

    最近各种技术盛会太多,朋友圈各种刷屏,有厂商发的各种广告,有讲师发的各种自拍,各种参会的朋友们各种自拍,好不热闹,不知道你的朋友圈是不是也是这样啊,去年还没这么多技术会议,今年感觉爆发了,呵呵,真是一 ...

  4. 用Golang写一个搜索引擎(0x03)

    2019独角兽企业重金招聘Python工程师标准>>> 前面已经说了倒排索引的基本原理了,原理非常简单,也很好理解,关键是如何设计第二个倒排表,倒排表的第二列也很好设计,第一列就是关 ...

  5. 如何自己动手写一个搜索引擎?我是一份害羞的教程

    你或许无法再造一个百度或谷歌,但显而易见,即便是百度或谷歌,也有鞭长莫及的地方.垂直细分领域的精准搜索从来都是巨头们的软肋.也是很多技术开发者实现财务自由的良好开端. 今天给大家推荐的这个教程,将帮助 ...

  6. GoWorld – 用Golang写一个分布式可扩展、可热更的游戏服务器

    Golang具有运行效率高.内存安全等优良特性,因此是非常适合用来进行服务器开发.使用Golang开发游戏服务器有如下的优点: 运行效率远高于各种脚本语言,大幅度提升服务器承载能力 内存安全,不会像C ...

  7. java写一个搜索引擎_搜索引擎—-Java实现一个简单的网络爬虫

    Java实现一个简单的爬虫程序. package SearchCrawler;import java.util.*;import java.net.*;import java.io.*;import ...

  8. 用python写搜索引擎_用python做一个搜索引擎(Pylucene)的实例代码

    1.什么是搜索引擎? 搜索引擎是"对网络信息资源进行搜集整理并提供信息查询服务的系统,包括信息搜集.信息整理和用户查询三部分".如图1是搜索引擎的一般结构,信息搜集模块从网络采集信 ...

  9. 【游戏开发实战】用Go语言写一个服务器,实现与Unity客户端通信(Golang | Unity | Socket | 通信 | 教程 | 附工程源码)

    文章目录 一.前言 二.Go开发环境搭建(Windows系统) 1.安装Go命令行工具 2.创建GoWorkspace目录 3.配置GOPATH环境变量 4.配置GOPROXY代理 5.安装VSCod ...

最新文章

  1. 【Spring】spring5新特性
  2. 转:android实时语音问题分析
  3. c++ 编译器支持情况表
  4. POJ1018贪心(多路归并的想法)
  5. python做数据库压力测试_Python 写的一个MongoDB压力测试
  6. Jupyter Notebook使用说明
  7. Python 基础——tuple与list、append与extend
  8. Java:JSON解析工具-org.json
  9. Nginx configure
  10. ICCV 2021 论文汇总!Vision Transformer
  11. 阶段3 3.SpringMVC·_06.异常处理及拦截器_5 SpringMVC拦截器之编写controller
  12. 基于Matlab的海洋监视雷达检测仿真(附源码)
  13. 张国荣的25年演艺生涯
  14. 【PowerDesigner】PowerDesigner的下载及安装
  15. Java(汉字/拼音/简繁)转换, 文字分割, 关键字提取, 人名, 音译, 地名识别等等
  16. Centos7下的zabbix安装与部署
  17. win服务器上的虚拟机反应慢,Win10系统打开VMware虚拟机特别慢的解决方法
  18. 怎样理解人生观、价值观、世界观?
  19. 欢迎使用CSDN-markdown编辑器2
  20. 汽车的违章停车检测系统

热门文章

  1. eclipse从svn检出项目
  2. 将sqlite查询结果导入到文本文件
  3. Win7开机密码破解
  4. php查找多个字符串替换,php 替换多个字符串
  5. java中缀表达式转后缀表达式_数据结构Java实现06----中缀表达式转换为后缀表达式...
  6. Rust 所有权介绍
  7. docker初体验:docker部署nginx负载均衡集群
  8. 简单介绍Git合并分支的流程步骤
  9. JavaScript初学者编程题(18)
  10. android 代码获取图片信息吗,Android 通过网络获取图片的代码