Elasticseach的评分机制
lucene 的评分机制
elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的。评分就是我们搜索的短语和索引中每篇文档的相关度打分。
如果没有干预评分算法的时候,每次查询,lucene会基于一个评分算法来计算所有文档和搜索语句的相关评分。
使用lucene的评分机制基本能够把最符合用户需要的搜索放在最前面。
当然有的时候,我们可能想要自定义评分算法,这个就和lucene的评分算法没有什么关系了。当然,我们大多数应该还是会根据自己的需求,来调整lucene本身的算法。 lucene的评分公式
lucene的评分是叫做TF/IDF算法,基本意思就是词频算法。
根据分词词库,所有的文档在建立索引的时候进行分词划分。进行搜索的时候,也对搜索的短语进行分词划分。
TF代表分词项在文档中出现的次数(term frequency),IDF代表分词项在多少个文档中出现(inverse document frequency)。 lucene的算法简单来说就是将搜索的短语进行分词得出分词项,每个分词项和每个索引中的文档根据TF/IDF进行词频出现的评分计算。
然后每个分词项的得分相加,就是这个搜索对应的文档得分。 这个评分公式有6个部分组成 coord(q,d) 评分因子,基于文档中出现查询项的个数。越多的查询项在一个文档中,说明文档的匹配程度越高。
queryNorm(q)查询的标准查询
tf(t in d) 指项t在文档d中出现的次数frequency。具体值为次数的开根号。
idf(t) 反转文档频率, 出现项t的文档数docFreq
t.getBoost 查询时候查询项加权
norm(t,d) 长度相关的加权因子
coord(q, d)
这个评分因子的计算公式是: public float coord(int overlap, int maxOverlap) {
return overlap / (float)maxOverlap;
}
overlap: 文档中命中检索的个数
maxOverlap: 检索条件的个数
比如检索"english book", 现在有一个文档是"this is an chinese book"。
那么,这个搜索对应这个文档的overlap为1(因为匹配了book),而maxOverlap为2(因为检索条件有两个book和english)。
最后得到的这个搜索对应这个文档的coord值为0.。 queryNorm(q)
这个因素对所有文档都是一样的值,所以它不影响排序结果。比如如果我们希望所有文档的评分大一点,那么我们就需要设置这个值。 public float queryNorm(float sumOfSquaredWeights) {
return (float)(1.0 / Math.sqrt(sumOfSquaredWeights));
}
tf(t in d)
项t在文档d中出现的次数 public float tf(float freq) {
return (float)Math.sqrt(freq);
}
比如有个文档叫做"this is book about chinese book", 我的搜索项为"book",那么这个搜索项对应文档的freq就为2,那么tf值就为根号2,即1. idf
public float idf(long docFreq, long numDocs) {
return (float)(Math.log(numDocs/(double)(docFreq+)) + 1.0);
}
这里的两个值解释下 docFreq 指的是项出现的文档数,就是有多少个文档符合这个搜索
numDocs 指的是索引中有多少个文档。
我在用es实际看这里的时候遇到一个问题,numDocs数和实际的文档数不一致,最后弄明白了,这里的numDocs指的是分片的文档数据,而不是所有分片的文档数。
所以使用es分析这个公式的时候,最好将分片数设置为1。 比如我现在有三个文档,分别为: this book is about english
this book is about chinese
this book is about japan
我要搜索的词语是"chinese",那么对第二篇文档来说,docFreq值就是1,因为只有一个文档符合这个搜索,而numDocs就是3。最后算出idf的值是: (float)(Math.log(numDocs/(double)(docFreq+)) + 1.0) = ln(/(+)) + = ln(1.5) + = 0.40546510810816 + = 1.40546510810816 t.getBoost
查询时期项t的加权,这个就是一个影响值,比如我希望匹配chinese的权重更高,就可以把它的boost设置为2 norm(t,d)
这个项是长度的加权因子,目的是为了将同样匹配的文档,比较短的放比较前面。
比如两个文档: chinese
chinese book
我搜索chinese的时候,第一个文档会放比较前面。因为它更符合"完全匹配"。 norm(t,d) = doc.getBoost()· lengthNorm· ∏ f.getBoost() public float lengthNorm(FieldInvertState state) {
final int numTerms;
if (discountOverlaps)
numTerms = state.getLength() - state.getNumOverlap();
else
numTerms = state.getLength();
return state.getBoost() * ((float) (1.0 / Math.sqrt(numTerms)));
}
这里的doc.getBoost表示文档的权重,f.getBoost表示字段的权重,如果这两个都设置为1,那么nor(t,d)就和lengthNorm一样的值。 比如我现在有一个文档: chinese book
搜索的词语为chinese, 那么numTerms为2,lengthNorm的值为 /sqrt() = 0.71428571428571。 但是非常遗憾,如果你使用explain去查看es的时候,发现lengthNorm显示的只有0.。
这个官方给出的原因是精度问题,norm在存储的时候会进行压缩,查询的时候进行解压,而这个解压是不可逆的,即decode(encode(0.714)) = 0.625。 示例
es中可以使用_explain接口进行评分解释查看。 比如现在我的文档为: chinese book
搜索词为: {
"query": {
"match": {
"content": "chinese"
}
}
}
explain得到的结果为: {
"_index": "scoretest",
"_type": "test",
"_id": "",
"matched": true,
"explanation": {
"value": 0.8784157,
"description": "weight(content:chinese in 1) [PerFieldSimilarity], result of:",
"details": [
{
"value": 0.8784157,
"description": "fieldWeight in 1, product of:",
"details": [
{
"value": ,
"description": "tf(freq=1.0), with freq of:",
"details": [
{
"value": ,
"description": "termFreq=1.0"
}
]
},
{
"value": 1.4054651,
"description": "idf(docFreq=1, maxDocs=3)"
},
{
"value": 0.625,
"description": "fieldNorm(doc=1)"
}
]
}
]
}
}
看到这篇文档的总得分为 0.8784157 tf(t in d):
idf: ln(/(+)) + = 1.4054651
norm(t,d): decode(encode(/sqrt())) = 0.625
总分: 1.4054651 * 0.625 = 0.8784157
Elasticseach的评分机制的更多相关文章
- lucene 的评分机制
lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...
- Solr In Action 笔记(2) 之 评分机制(相似性计算)
Solr In Action 笔记(2) 之评分机制(相似性计算) 1 简述 我们对搜索引擎进行查询时候,很少会有人进行翻页操作.这就要求我们对索引的内容提取具有高度的匹配性,这就搜索引擎文档的相似性 ...
- Wifi 评分机制分析
从android N开始,引入了wifi评分机制,选择wifi的时候会通过评分来选择. android O源码 frameworks\opt\net\wifi\service\java\com\and ...
- Lucene Scoring 评分机制
原文出处:http://blog.chenlb.com/2009/08/lucene-scoring-architecture.html Lucene 评分体系/机制(lucene scoring)是 ...
- Lucene 的 Scoring 评分机制
转自: http://www.oschina.net/question/5189_7707 Lucene 评分体系/机制(lucene scoring)是 Lucene 出名的一核心部分.它对用户来 ...
- Apache Lucene评分机制的内部工作原理
Apache Lucene评分机制的内部工作原理' 第5章
- Android 8.0/9.0 wifi 自动连接评分机制
前言 Android N wifi auto connect流程分析 Android N selectQualifiedNetwork分析 Wifi自动连接时的评分机制 今天了解了一下Wifi自动连接 ...
- elasticSearch(5.3.0)的评分机制的研究
1. ElasticSearch的评分 在用ElasticSearch作为搜索引擎的时候,如果采用关键字进行查询,ElasticSearch会对每个符合查询条件的文档进行评分,在5.3.0的版本中, ...
- ELASTICSEARCH 搜索的评分机制
从我们在elasticsearch复合框输入搜索语句到结果显示,展现给我们的是一个按score得分从高到底排好序的结果集.下面就来学习下elasticsearch怎样计算得分. Lucene(或 El ...
随机推荐
- 使用OAuth Server PHP实现OAuth2服务
在现在的网络服务中,OAuth2.0服务已经很普遍了,无论是facebook或者微博的第三方登录,还是手机APP登录,都有很广泛的应用.它主要的目的如下:如果用户的照片在A网站,他想要在B网站使用A网 ...
- html5视频播放解决方案
关键词:html5 nativeapp webapp mp4 H.264 html5没学习之前总觉的很神秘.近期通过学习和研究html5有点成果,特总结分享给大家.众所周知应用开发分两种:一是原生的 ...
- e812. 强制弹出菜单为重组件
By default, Swing popup menus used by JMenu and JPopupMenu are lightweight. If heavyweight component ...
- AWT和Swing之间的基本区别
AWT和Swing之间的基本区别:AWT 是基于本地方法的C/C++程序,其运行速度比较快:Swing是基于AWT 的Java程序,其运行速度比较慢. 对于一个嵌入式应用来说,目标平台的硬件资源往往非 ...
- Ubuntu 12.04安装Java开发环境(jdk1.7 + Eclipse)
首先,去官网下载linux版本的jdk和eclipse tar包,并将其解压出来.我将jdk包发在了/usr/java/目录下,eclipse放在了/opt/目录下. 然后,配置java开发环境,即安 ...
- Java常用类(二)String类详解
前言 在我们开发中经常会用到很多的常用的工具类,这里做一个总结.他们有很多的方法都是我们经常要用到的.所以我们一定要把它好好的掌握起来! 一.String简介 1.1.String(字符串常量)概述 ...
- dpkg: error processing package libraspberrypi-doc (--configure): package is in a very bad inconsistent state;
dpkg: error processing package libraspberrypi-doc (--configure): package is in a very bad inconsiste ...
- 设置wetty不需要账号登录便可进行命令行操作
前一篇随笔我们将了Linux怎么安装部署Wetty服务,但是我们看到,在浏览器中输入http://127.0.0.1:3000进行访问的时候,还需要我们输入账号密码进行认证(如下图第一行所示). 但在 ...
- 【Deep Learning】RNN的直觉理解
https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/
- 小程序中监听textarea或者input输入的值动态改变data中数组的对象的值
Page({ data: { todoLists:[ { detail:"", date:"", location:"", priority ...