本来没有这篇文章,在公司分享ES的时候遇到一个问题,使用boost的时候,怎么从评分score中知道boost的影响。

虽然我们从查询结果可以直观看到,boost起了应有的作用,但是在explain的时候,找了很久也不明白,boost去哪了?

这个问题花了点时间,不过还是挺值得。由于没有直接用过lucene,也从没想过到lucene网站上去看文档。在Elastic的文档中发现这样一段描述

In fact, reading the explain output is a little more complex than that. You won’t see the boost value or t.getBoost() mentioned in the explanation at all. Instead, the boost is rolled into the queryNorm that is applied to a particular term. Although we said that the queryNorm is the same for every term, you will see that the queryNorm for a boosted term is higher than the queryNorm for an unboosted term.

大概是说:从explain中寻找boost是有点复杂的,因为它被放到queryNorm的计算当中了

queryNorm是怎么计算的?

首先我们应该很容易在explain计算idf的部分看到queryNorm。而计算queryNorm的方式是在底部序号为1的lucene的参考资料中。

计算公式如下:

从这里可以看出我们还需要一个公式

有了这两个公式,我们就可以计算queryNorm,而queryNorm中融合了t.getBoost()这就是我们所关心Boost。显然Boost不是简单的乘上了某个倍数,所以我们很难直观的从score中看到,评分被乘了10或者20,也是我们在分享的时候,找了半天,也没有找到一个整数倍数的原因。

在Elasticsearch 中queryNorm是怎么计算的?

虽然我们有了公式,不过利用公式带入到我们的查询参数中会发现,数值还是有点偏差,有一些细节在公式中并没有体现。通过实验(非源码)我大概能了解计算方式,这里我就举一个实际例子来看ES怎么计算queryNorm。

首先设计一条查询语句,这里不讨论idf的计算,设计的查询中idf都是1

{
"size":30,
"query":{
"bool": {
"should": [
{
"match": {
"name": {
"query": "便宜了",
"boost": 1
}
}
},
{
"match": {
"server": {
"query": "电信",
"boost": 1
}
}
}
]
}
}
}

这是一个bool查询,(Lucene (and thus Elasticsearch) uses the Boolean model to find matching documents,我们的很多查询其实都被看做bool查询,ES只是提供了比较友好的其他查询方式,比如terms查询就是一种bool的should查询,或者直观一点,就是or条件查询)。boost都是1,默认的boost也是1。根据公式,我们按照每个字一个词进行分词的情况下,一共搜索了5个字,计算queryNorm的方式如下:

1/Math.sqrt(5) = 0.4472136

符合我们的预期,如果我们修改boost呢?

{
"size":30,
"query":{
"bool": {
"should": [
{
"match": {
"name": {
"query": "便宜了",
"boost": 4
}
}
},
{
"match": {
"server": {
"query": "电信",
"boost": 1
}
}
}
]
}
}
}

按照公式t.getBoost() 在计算“便宜了” 三个字的时候,应该要乘以4,计算公式应该是

1/Math.sqrt((1 * 4)^2 * 3 + 2 * 1) =0.1414213

但实际情况并非如此,其实ES在处理这个时候,如果较大的boost命中,es将小的那个值变成了0.25,也就是4分之一

1/Math.sqrt(3 + 2 * (1 * 0.25)^2) = 0.5656854

反过来如果,较大的boost没有命中,就会放大较大的boost的影响,采用第一个算法取用 0.1414213,所以如果有两个文档分别命中:

  • name命中, 无论server是否命中,采用0.5656854
  • name无命中, server命中,采用,0.1414213

两个数相除正好是4倍左右,可以看到,如果字数差距再大一些,倍数可能不是4,会有一定偏差

note:以上分析结果基于试验,ES和lucene源码不一定是这样实现,毕竟公式可以各种变化计算来达到4倍差值。

参考资料:

  1. http://lucene.apache.org/core/4_6_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html
  2. https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html#field-norm

Elasticsearch 评分score计算中的Boost 和 queryNorm的更多相关文章

  1. Elasticsearch学习笔记(十四)relevance score相关性评分的计算(1)

    一.多shard场景下relevance score不准确问题     1.问题描述:            多个shard下,如果每个shard包含指定搜索条件的document数量不均匀的情况下, ...

  2. elasticsearch relevance score相关性评分的计算

    一.多shard场景下relevance score不准确问题 1.问题描述: 多个shard下,如果每个shard包含指定搜索条件的document数量不均匀的情况下,会导致在某个shard上doc ...

  3. ElasticSearch 评分排序

    背景 通过脚本改变评分 背景 近期有一个需求,需要对优惠券可用商品列表加个排序,只针对面值类的券不包括折扣券. 需求是这样的,假设有一张面值券 50 块钱,可用商品列表 A 100.B 40.C 10 ...

  4. ElasticSearch评分分析 explian 解释和一些查询理解

    ElasticSearch评分分析 explian 解释和一些查询理解 按照es-ik分析器安装了ik分词器.创建索引:PUT /index_ik_test.索引包含2个字段:content和nick ...

  5. WOE:信用评分卡模型中的变量离散化方法(生存分析)

    WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...

  6. 【主流技术】ElasticSearch 在 Spring 项目中的实践

    前言 ElasticSearch简称es,是一个开源的高扩展的分布式全文检索引擎. 它可以近乎实时的存储.检索数据,其扩展性很好,ElasticSearch是企业级应用中较为常见的技术. 下面和大家分 ...

  7. 如何在VS2013中进行Boost单元测试

    对于如何在VS2013中进行Boost单元测试,这方面资料太少.自己也因此走了不少弯路.下文将会阐述一下如何在VS2013中进行Boost单元测试. 在开始Boost单元测试之前,我们需要先安装VS2 ...

  8. ES 02 - 部署Elasticsearch单机服务 + 部署中的常见问题

    目录 1 准备工作 1.1 安装JDK 1.2 下载安装包 1.3 创建elastic用户 2 启动ES服务 2.1 修改配置文件 2.2 启动服务 3 验证ES服务是否可用 4 关闭与重启服务 4. ...

  9. FPGA计算中定标与位扩展的实现

    我不知道名字取对没有,在FPGA计算中有时往往需要在不溢出的情况下将数扩大,从而获得更好的计算精度. 比如.在一个8位宽的系统中,将x=0000_0010,算术左移m=5位之后得到xt=0100_00 ...

随机推荐

  1. 一个有意思的CSS样式库--BUTTONS

    我最近发现了一个有意思的CSS样式库,和Bootstrap相似,但是它是专门的一个高度可定制的,免费的并且开源的按钮CSS样式库,这里附上它的网址:http://www.bootcss.com/p/b ...

  2. Reading Notes : 180213 计算机的硬件构成与处理流程

    读书<计算机组成原理>,<鸟哥的Linux私房菜基础篇> 基本上接触过计算机的人,都多少知道计算机的具体构成,但是真正能讲明白的却说了很多,本节将讲解一下计算机的基本硬件构成和 ...

  3. MySQL---存储过程 及 条件语句、循环语句

    存储过程 存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行. 1.创建存储过程 -- 创建存储过程 delimiter // create procedure ...

  4. iOS 11.2 - 11.3.1 越狱教程

    iOS 11.2 - 11.3.1 越狱教程 一.准备相应的工具 (1) 下载 CydiaImpactor,官网地址是 http://cydiaImpactor.com (2) 下载 Electra, ...

  5. mysql 几种搜索引擎的比较

    mysql中常见的数据库引擎之间的比较  转载自 深入浅出mysql数据库 MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表. 若 ...

  6. S3C2440上LCD驱动(FrameBuffer)实例开发讲解(一)

    一.开发环境 主  机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2 二.背景知识 ...

  7. seleniun 爬取淘宝网

    import re from selenium import webdriver from selenium.common.exceptions import TimeoutException fro ...

  8. 请求报文的方法及get与post的区别

    请求报文的方法及get与post的区别 请求的起始以方法作为开始,方法用来告诉服务器要如何做. 在开发中通常有两种请求方式. get方式: 是以实体的方式得到由请求 URI 所指定资源的信息,如果请求 ...

  9. bedtools-Documentation

    https://media.readthedocs.org/pdf/bedtools/latest/bedtools.pdf

  10. python--模块之random随机数模块

    作用是产生随机数 import random random.random:用于生成一个0--1的随机浮点数. print(random.random())>>0.3355102133472 ...