[Elasticsearch] 控制相关性 (一) - 后面的相关度分值理论计算
从第一章翻译Elasticsearch官方指南Controlling Relevance一章。
控制相关度(Controlling Relevance)
对于仅处理结构化数据(比方日期。数值和字符枚举值)的数据库,它们仅仅须要检查一份文档(在关系数据库中是一行)是否匹配查询就可以。
虽然布尔类型的YES|NO匹配也是全文搜索的一个必要组成。它们本身是不够的。我们还须要知道每份文档和查询之间的相关程度。全文搜索引擎不仅要找到匹配的文档,还须要依据相关度对它们进行排序。
全文搜索相关度的公式,或者被称为相似度算法。将多个因素综合起来为没份文档产生一个相关度_score。在本章中。我们来讨论一下当中的一些变化的部分以及怎样控制它们。
当然相关度并不仅仅和全文查询相关;它或许会将结构化数据考虑在内。
我们可能在寻找一个拥有某些卖点(空调。海景,免费的WiFi)的度假旅店。
那么当某个度假旅店拥有的卖点越多。那么它也就越相关。或者我们希望除全文搜索本身的相关度外。同一时候将时间的远近,价格。流行度或者距离这类因素也考虑在内。
以上这些设想都是能够实现的,得益于ES中强大的分值计算功能。
我们首先会从理论角度来看看Lucene是怎样计算相关度的,然后从实际的样例出发来讨论一下怎样来控制该过程。
相关度分值计算背后的理论
Lucene(也就是ES)使用了布尔模型(Boolean Model)来寻找匹配的文档,以及一个被称为Prarical
Scoring Function的公式来计算相关度。该公式借用了词条频度/倒排文档频度以及向量空间模型的概念,同一时候也添加了一些更现代的特性比方Coordination Factor,字段长度归约。以及词条/查询子句提升。
NOTE
不要害怕!这些概念并不像它们的名字那般复杂。
虽然在这一节中提到了算法,公式以及数学模型,它们的作用也仅仅只是是方便人类理解。理解算法本身并不比理解它们对结果的影响更重要。
布尔模型(Boolean
Model)
布尔模型简单地应用查询中的AND。OR以及NOT条件来寻找全部匹配的文档。以下的查询:
full AND text AND search AND (elasticsearch OR lucene)
会仅仅包含含有全部full,text。search词条。以及词条elasticsearch或者lucene之中的一个的文档。
这个过程是简单且迅速的。
它用来排除那些不会匹配查询的文档。
词条频度/倒排文档频度(TF/IDF)
一旦我们拥有了匹配文档的列表。我们就须要对它们进行相关度排序。并非全部的文档都会包括全部的词条。而一部分词条也比还有一部分的词条更加重要。
整个文档的相关度分值取决于(部分)出如今文档中的每一个查询词条的权重。
一个词条的权重通过三个因素决定。这在什么是相关度中已经介绍过了。
对该公式的介绍是为了兴趣,你不须要记住它们。
词条频度(Term Frequency)
词条在当前文档中出现的有多频繁?越频繁的话,那么权重就越高。在一个字段中出现了5次的词条应该比仅仅出现了1次的文档更加相关。
词条频度通过以下的公式进行计算:
tf(t in d) = √frequency
词条t在文档d中的词条频度tf,是该词条在文档中出现次数的平方根。
假设你不在乎一个词条在一个字段中的出现频度。相反你在意的是词条是否出现过。那么你能够在字段映射中禁用词条频度:
PUT /my_index
{
"mappings": {
"doc": {
"properties": {
"text": {
"type": "string",
"index_options": "docs"
}
}
}
}
}
将index_options设置为docs会禁用词条频度以及词条位置信息。使用了该设置的字段不会记录词条出现的次数,也不能被用在短语或者邻近度查询中。精确值的not_analyzed字符串字段默认使用该设置。
倒排文档频度(Inverse Document Frequency)
词条在全部的文档中出现的频繁吗?出现的越频繁,权重就越低。像and或者the这种常见词条对相关度的贡献差点儿没有,由于它们在绝大多数的文档中都会出现。而像elastic或者hippopotamus这种罕见词条则可以帮助找到我们最感兴趣的文档。倒排文档频度的计算方法例如以下:
idf(t) = 1 + log ( numDocs / (docFreq + 1))
对于词条t的倒排文档频度(idf)。通过将索引中的文档数量除以含有该词条的文档数量,再取其对数得到。
字段长度归约(Field-length Norm)
字段的有多长?字段越短。那么其权重就越高。假设一个词条出如今较短的字段,如title字段中,那么该字段的内容相比更长的body字段而言。更有可能是关于该词条的。字段长度归约的计算方法例如以下:
norm(d) = 1 / √numTerms
虽然字段长度归约对于全文搜索而言是重要的,也有很多其他字段不须要。不管文档是否含有该字段,对于索引中每份文档的每一个字符串字段,归约大概需消耗1个字节的空间。对于精确值的not_analyzed字符串字段,归约功能默认是被禁用的。可是你也能够对analyzed类型的字段通过字段映射禁用归约:
PUT /my_index
{
"mappings": {
"doc": {
"properties": {
"text": {
"type": "string",
"norms": { "enabled": false }
}
}
}
}
}
在以上的样例中,该字段不会将字段长度归约考虑在内。这就意味着字段的长度不再被相关度计算考虑在内。
对于日志记录这样的用例,归约是没有多大用处的。你在意的仅仅是某个特定错误代码或者某个浏览器标识码是否出如今了某个字段中。字段的长度不会对结果造成影响。禁用归约功能也能够省下相当的内存空间。
结合起来
以上的三个因素 - 词条频度。倒排文档频度以及字段长度规范 - 都是在索引期间被计算和保存的。
它们被用来计算单个词条对于某一份文档的权重。
TIP
我们前面讨论的文档,实际上是在讨论文档中的字段。
每一个字段都有它自己的倒排索引,因此对于TF/IDF而言,字段的值和文档的值是等效的。
当我们将explain设置为true(參考理解分值(Understanding the Score)),然后再执行简单的term查询时,你会发现參与到分值计算过程中的因素就是我们前面讨论的那些:
PUT /my_index/doc/1
{ "text" : "quick brown fox" } GET /my_index/doc/_search? explain
{
"query": {
"term": {
"text": "fox"
}
}
}
前面的请求得到的解释(有省略)例如以下所看到的:
weight(text:fox in 0) [PerFieldSimilarity]: 0.15342641 result of: fieldWeight in 0 0.15342641 product of: tf(freq=1.0), with freq of 1: 1.0 idf(docFreq=1, maxDocs=1): 0.30685282 fieldNorm(doc=0): 0.5
第一行:对于Lucene内部文档ID为0的文档,词条fox在其text字段中的终于分值。
第五行 - 第七行:词条频度,倒排文档频度以及字段长度归约得到的结果。
当然,查询通常都会由不止一个词条组成,因此我们须要一种将多个词条的权重联系起来的方法。为此我们能够求助向量空间模型(Vector Space Model)。
向量空间模型
向量空间模型提供了一种多词条查询的比較方法。它的输出是一个代表了文档和查询之间匹配程度的分值。为了计算该分值,文档和查询都被表示成向量。
一个向量实际上就是一个包括了数值的一维数组,比方:
[1,2,5,22,3,8]
在向量空间模型中。向量中的每一个数值都是由TF/IDF计算得到的一个词条的权重。
TIP
虽然TF/IDF是在向量空间模型中默认被用来计算词条权重的方法,它并非唯一可用的方法。在ES中,其他诸如Okapi-BM25的计算模型也是可用的。TF/IDF因为其简洁性。高效性。产生的搜索结果的高质量而经受了时间的考验,从而被当做是默认方法。
如果我们查询了"happy hippopotamus"。一个像happy这种常见单词的权重是较低的,然而像hippopotamus这种罕见单词则拥有较高的权重。
如果happy的权重为2而hippopotamus的权重为5。
我们能够使用坐标来表达这个简单的二维向量 - [2, 5] - 一条从坐标(0, 0)到坐标(2, 5)的直线,例如以下所看到的:
如今,如果我们有三份文档:
- I am happy in summer.
- After Christmas I’m a hippopotamus.
- The happy hippopotamus helped Harry.
我们能够为每份文档创建一个类似的向量,它由每一个查询词条的权重组成 - 也就是出如今文档中的词条happy和hippopotamus,然后将它绘制在坐标中,例如以下图:
- 文档1:(happy,____________) — [2,0]
- 文档2:( ___ ,hippopotamus) — [0,5]
- 文档3:(happy,hippopotamus) — [2,5]
向量的一个非常棒的性质是它们可以被比較。通过測量查询向量和文档向量间的角度。我们可以给每份文档计算一个相关度分值。文档1和查询之间的角度较大,因此它的相关度较低。文档2和查询更靠近,所以它的相关度更高,而文档3和查询之间则是一个完美的匹配。
TIP
实际上。仅仅有二维向量(使用两个词条的查询)才可以被简单地表示在坐标中。幸运的是,线性代数 - 数学的一个分支,可以处理向量 - 提供了用来比較多维向量间角度的工具。这意味着我们可以使用上述原理对包括非常多词条的查询进行处理。
你能够获得关于使用余弦相似性来比較两个向量的很多其它信息:http://en.wikipedia.org/wiki/Cosine_similarity
我们已经讨论了点值计算的理论基础。现在让我们来看看Lucene什么分歧值计算。
[Elasticsearch] 控制相关性 (一) - 后面的相关度分值理论计算的更多相关文章
- 用 Mahout 和 Elasticsearch 实现推荐系统
原文地址 本文内容 软件 步骤 控制相关性 总结 参考资料 本文介绍如何用带 Apache Mahout 的 MapR Sandbox for Hadoop 和 Elasticsearch 搭建推荐引 ...
- ElasticSearch 2 (18) - 深入搜索系列之控制相关度
ElasticSearch 2 (18) - 深入搜索系列之控制相关度 摘要 处理结构化数据(比如:时间.数字.字符串.枚举)的数据库只需要检查一个文档(或行,在关系数据库)是否与查询匹配. 布尔是/ ...
- elasticsearch 深入 —— 相关度控制
控制相关度 处理结构化数据(比如:时间.数字.字符串.枚举)的数据库, 只需检查文档(或关系数据库里的行)是否与查询匹配. 布尔的是/非匹配是全文搜索的基础,但不止如此,我们还要知道每个文档与查询的相 ...
- Elasticsearch BM25相关度算法超详细解释
Photo by Pixabay from Pexels 前言:日常在使用Elasticsearch的搜索业务中多少会出现几次 "为什么这个Doc分数要比那个要稍微低一点?".&q ...
- Elasticsearch工作原理
一.关于搜索引擎 各位知道,搜索程序一般由索引链及搜索组件组成. 索引链功能的实现需要按照几个独立的步骤依次完成:检索原始内容.根据原始内容来创建对应的文档.对创建的文档进行索引. 搜索组件用于接收用 ...
- ElasticSearch 处理自然语言流程
ES处理人类语言 ElasticSearch提供了很多的语言分析器,这些分析器承担以下四种角色: 文本拆分为单词 The quick brown foxes → [ The, quick, brown ...
- [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段 <译>
multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在“了解你的数据”一节中提 ...
- elasticsearch学习笔记--原理介绍
前言:上一篇中我们对ES有了一个比较大概的概念,知道它是什么,干什么用的,今天给大家主要讲一下他的工作原理 介绍:ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户 ...
- [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段
multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据 ...
随机推荐
- 使用gulp创建ajax模拟请求
概述 之前一直使用gulp构建前端项目,这个基于node流并崇尚“编程而非配置”的工具让我深深的爱上了他.强大的gulp能做到的不仅仅是压缩和合并js.css,它能做到的还有更多.今天我给大家带来使用 ...
- 调用一个系统命令,并读取它的输出值(使用QProcess.readAll)
下面我们再看一个更复杂的例子,调用一个系统命令,这里我使用的是 Windows,因此需要调用 dir:如果你是在 Linux 进行编译,就需要改成 ls 了. mainwindow.h #ifndef ...
- Delphi中获取Unix时间戳及注意事项(c语言中time()是按格林威治时间计算的,比北京时间多了8小时)
uses DateUtils;DateTimeToUnix(Now) 可以转换到unix时间,但是注意的是,它得到的时间比c语言中time()得到的时间大了8*60*60这是因为Now是当前时区的时间 ...
- (并查集)POJ 1308 & HDU 1325
一开始以为两道题是一样的,POJ的过了直接用相同代码把HDU的交了,结果就悲剧了.最后发现HDU的没有考虑入度不能大于一. 题意:用树的定义来 判断吧,无环,n个结点最多有n-1条边,不然就会有环.只 ...
- 自学PHP 环境搭建
自学PHP之环境搭建 一..首先 安装 phpStudy2013.exe 程序集成包 安装完可能端口被占用 需要手动设置 然后打开http://localhost:8080/phpMyAdmin/ ...
- PhoneGap-----Contacts
Everything in the code!!! <!DOCTYPE html> <html> <head> <title>Contact Examp ...
- Hadoop之MapReduce程序应用三
摘要:MapReduce程序进行数据去重. 关键词:MapReduce 数据去重 数据源:人工构造日志数据集log-file1.txt和log-file2.txt. log-file1.txt内容 ...
- 《Android系统开发》笔记
<Android系统开发>笔记1:Android系统概述 Android四层架构: 1. Linux Kernel&driver层 a.依赖于Linux 2.6内核,包含安全性.内 ...
- Xah Lee Web 李杀网
Xah Lee Web 李杀网 ∑ Xah Lee Web 李杀网
- MVC之Session State性能
ASP.NET MVC之Session State性能问题(七) 前言 这一节翻译一篇有关Session State性能问题的文章,非一字一句翻译. 话题 不知道我们在真实环境中是否用到了Sess ...