【问题标题】:Elasticsearch scoring explanation not the same as practical scoring functionElasticsearch打分解释与实际打分功能不一样
【发布时间】:2017-07-19 13:30:43
【问题描述】:

https://www.elastic.co/guide/en/elasticsearch/guide/current/practical-scoring-function.html我们有以下计算分数的函数。

score(q,d)  =  
            queryNorm(q)  
          · coord(q,d)    
          · ∑ (           
                tf(t in d)   
              · idf(t)²      
              · t.getBoost() 
              · norm(t,d)    
            ) (t in q) 

但是,在查看解释下面的示例时,似乎存在一些不一致之处。 1) 解释只显示 idf 而不是 idf²。

2) 协调因素在哪里?

3) 从解释上看,score 似乎是这样计算的:(tf * idf * fieldNorm) + (number of Clauses * boost * queryNorm)

索引文档:

PUT test/type/1
{
  "text": "a b c"
}

查询:

GET test/type/_search
{
  "explain":"true",
  "query": {
    "match": {
      "text": "a"
    }
  }
}

结果:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.15342641,
    "hits": [
      {
        "_shard": 3,
        "_node": "5QvbXVlRSku-p_g81ZXpjQ",
        "_index": "test",
        "_type": "type",
        "_id": "1",
        "_score": 0.15342641,
        "_source": {
          "text": "a b c"
        },
        "_explanation": {
          "value": 0.15342641,
          "description": "sum of:",
          "details": [
            {
              "value": 0.15342641,
              "description": "weight(text:a in 0) [PerFieldSimilarity], result of:",
              "details": [
                {
                  "value": 0.15342641,
                  "description": "fieldWeight in 0, product of:",
                  "details": [
                    {
                      "value": 1,
                      "description": "tf(freq=1.0), with freq of:",
                      "details": [
                        {
                          "value": 1,
                          "description": "termFreq=1.0",
                          "details": []
                        }
                      ]
                    },
                    {
                      "value": 0.30685282,
                      "description": "idf(docFreq=1, maxDocs=1)",
                      "details": []
                    },
                    {
                      "value": 0.5,
                      "description": "fieldNorm(doc=0)",
                      "details": []
                    }
                  ]
                }
              ]
            },
            {
              "value": 0,
              "description": "match on required clause, product of:",
              "details": [
                {
                  "value": 0,
                  "description": "# clause",
                  "details": []
                },
                {
                  "value": 3.2588913,
                  "description": "_type:type, product of:",
                  "details": [
                    {
                      "value": 1,
                      "description": "boost",
                      "details": []
                    },
                    {
                      "value": 3.2588913,
                      "description": "queryNorm",
                      "details": []
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

【问题讨论】:

  • 协调因子是查询中出现在返回文档中的词条的数量。对于问题 2,由于仅搜索一个词,因此协调因子为 1,因此不显示。如果查询是针对“a b x”,那么协调因子将是 2/3。

标签: elasticsearch lucene


【解决方案1】:
  • 您缺少 idf 的一种情况,因为您的查询中只有一个子句。 idf 的第二个乘法是查询权重,在这样一个简单的查询中是看不到的。第二个 idf 被查询规范取消。 Querynorm(简化一点)是:1 / √ (∑ idf^2),用一个词就变成:1 / idf,所以查询权重变成 idf/idf。虽然所有这些都是隐含的,但只有一个子句,没有什么可以衡量该术语的,因此不需要计算查询权重。

  • 此查询中只有一个术语,因此无需考虑坐标。即 coord = 重叠 / maxOverlap = 1/1 = 1

  • 不知道这是从哪里来的。我相信您会遇到_type 查询。似乎是添加到针对给定 Elasticsearch 类型进行搜索的必填项。请注意,此查询的分数为零。因此,所有匹配项都必须符合指定的 _type,但该术语根本不应该影响分数。

如果您想查看评分算法中的所有工作,则需要使用更接近实际情况的测试数据集和查询。这个测试有一个简单的文档和一个简单的查询。在这种情况下,是的,算法看起来很简单:

score = tf * idf * fieldNorm = 1 * 0.30685282 * .5

但是您没有看到坐标、查询标准或整体重量计算,因为您的查询太简单了。您没有看到特别有意义的 idf(或 tf),因为只有一个文档和一个匹配项。您没有看到总和,因为您对一个术语进行了一次打击,因此没有什么可总结的。该算法的主要目的是从更大的数据集中产生有意义的分数。

【讨论】:

  • 但插入 idf 的值将是: =(1+ln(0.5)) =(1+(-0,69314)) =0.30685282 因此 idf^2 将接近 0.094158
  • @user6811487 - 误解了第一个问题。现已编辑。
猜你喜欢
  • 2014-07-05
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 2018-04-10
  • 1970-01-01
相关资源
最近更新 更多