Lucene fieldNorm 相似度计算与查询时值的差异

标签 lucene indexing metrics

我想了解如何 fieldNorm计算(在索引时),然后在查询时使用(并且显然重新计算)。

在所有示例中,我都使用没有停用词的 StandardAnalyzer。

调试 DefaultSimilaritycomputeNorm在索引内容时使用方法,我注意到它返回 2 个特定文档:

  • 文档 A 为 0.5(其字段中有 4 个标记)
  • 文档 B 的 0.70710677(其字段中有 2 个标记)

  • 它通过使用以下公式来做到这一点:
    state.getBoost() * ((float) (1.0 / Math.sqrt(numTerms)));
    

    boost 始终为 1

    之后,当我查询这些文档时,我看到在查询解释中我得到
  • 0.5 = fieldNorm(field=titre, doc=0)对于文档 A
  • 0.625 = fieldNorm(field=titre, doc=1)用于文档 B

  • 这已经很奇怪了(对我来说,我确定是我遗漏了什么)。为什么我得到的字段规范值与索引时计算的值不同?这是“查询规范化”的作用吗?如果是这样,它是如何工作的?

    然而,这或多或少是可以的,因为两个查询时 fieldNorm 给出的顺序与索引时计算的顺序相同(在这两种情况下,具有较短值的字段具有较高的 fieldNorm)

    然后,我创建了自己的 Similarity 类,在其中实现了 computeNorms 方法,如下所示:
    public float computeNorm(String pField, FieldInvertState state) {
        norm = (float) (state.getBoost() + (1.0d / Math.sqrt(state.getLength())));
        return norm;
    }
    

    在索引时,我现在得到:
  • 1.5 用于文档 A(其字段中有 4 个标记)
  • 1.7071068 用于文档 B(其字段中有 2 个标记)

  • 但是现在,当我查询这些文档时,我可以看到它们都具有与解释函数报告的相同的字段规范:
  • 1.5 = fieldNorm(field=titre, doc=0)对于文档 A
  • 1.5 = fieldNorm(field=titre, doc=1)用于文档 B

  • 对我来说,这现在真的很奇怪,如果我在索引时使用明显良好的相似性来计算 fieldNorm,这给了我与 token 数量成正比的适当值,后来在查询时,所有这些都丢失了,查询 sais 两个文档具有相同的字段规范?

    所以我的问题是:
  • 为什么Similarity 的computeNorm 方法报告的索引时间fieldNorm 与查询解释报告的不一样?
  • 为什么,对于在索引时获得的两个不同的 fieldNorm 值(通过相似性计算标准),我在查询时得到相同的 fieldNorm 值?

  • == 更新

    好的,我在 Lucene's docs 找到了一些东西这澄清了我的一些问题,但不是全部:

    然而,结果范数值在存储之前被编码为单个字节。在搜索时,从索引目录中读取规范字节值并解码回浮点规范值。这种编码/解码在减少索引大小的同时,伴随着精度损失的代价——不保证 decode(encode(x)) = x。例如,解码(编码(0.89))= 0.75。

    有多少精度损失?我们应该在不同的值之间设置一个最小的差距,以便即使在重新计算精度损失之后它们仍然保持不同?

    最佳答案

    encodeNormValue 的文档描述编码步骤(这是失去精度的地方),特别是值的最终表示:

    The encoding uses a three-bit mantissa, a five-bit exponent, and the zero-exponent point at 15, thus representing values from around 7x10^9 to 2x10^-9 with about one significant decimal digit of accuracy. Zero is also represented. Negative numbers are rounded up to zero. Values too large to represent are rounded down to the largest representable value. Positive values too small to represent are rounded up to the smallest positive representable value.



    最相关的部分是,尾数只有 3 位,这意味着精度大约是一位有效的十进制数字。

    关于基本原理的一个重要说明是在您的引用结束后的几句话,Lucene 文档说:

    The rationale supporting such lossy compression of norm values is that given the difficulty (and inaccuracy) of users to express their true information need by a query, only big differences matter.

    关于Lucene fieldNorm 相似度计算与查询时值的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15135872/

    相关文章:

    solr - 如何使用 Luke 检查 Solr 索引

    java - Solr范围不过滤

    java - 我如何阅读和打印 Lucene 索引 4.0

    mysql - 为什么优化器使用 'ALL' 类型而不是 'index' 类型?

    python - 如何在普罗米修斯中创建自定义指标?

    kubernetes - 查询kubernetes指标-服务器指标值

    java - Hibernate Search 空间构面查询首先运行 5 次,然后仅返回第 5 个结果

    solr - 将 Solr 重复值删除到多值字段中

    mysql - 当字段值不明确时如何优化 MySQL 查询

    metrics - 测量软件配置代码的工作量/指标