首页 > 解决方案 > 调整 Lucene 评分

问题描述

我在这里查看了其他 Lucene 评分问题,但似乎没有一个能涵盖我的问题。

我正在索引一些大型 Word 文件。这些文件中的行被拆分,文件中的每 10 行被制成一个 Lucene Document(实际上它们是重叠的 10-line Documents,但这不相关)。

例如,当我搜索“泡沫绽放”时......我发现,令我有点惊讶的是,如果这些词中的一个在给定中出现两次,Document则它几乎被视为“与”同时找到两个搜索一样好术语词(即“泡沫”和“绽放”)在同一个Document

此外Document,包含 3 个单词“bubble”实例的(一组 10 行)将列在Document包含 1 x“bubble”和 1 x“bloom”的之前。一个带有 2 x“气泡”的单词似乎Document与两个单词的单词相等。

注意String像这样,“泡沫绽放”似乎会被 a 变成BooleanQuery带有两个子句的 a QueryParser.parse()

有没有办法调整事情,以便在一个词中找到两个词(搜索词)这一事实的Document排名Document高于找到其中一个词的 2 或 3 个实例,但另一个词的实例为零?

PS顺便说一句,我刚刚做了一个搜索,其中搜索字符串是“+bubble +bloom”......显然这不包括Document缺少一个单词的任何地方。但我认为这是一种解决方法。我希望没有“+”(用于“要求”)的默认功能来对所有术语都存在更高的事实进行评分。

标签: javalucenescoring

解决方案


很明显,TF-IDF 或 BM25 评分非常依赖于索引中术语的分布,因为例如我能够让包含“bubblebloom”的文档高于任何文档,但这很可能仅我的测试分布

有不同的方法可以以标准方式实现这一目标。最简单的方法之一是使用ConstantScoreQuery,它总是会给你一个或多个匹配项的分数 1.0(或任何其他任意数字)。结合使用求和的BooleanQuery,您可以轻松地根据文档中的术语数对文档进行评分。

例如

Query query = new BooleanQuery.Builder()
            .add(new ConstantScoreQuery(new TermQuery(new Term("text", "bloom"))), BooleanClause.Occur.SHOULD)
            .add(new ConstantScoreQuery(new TermQuery(new Term("text", "bubble"))), BooleanClause.Occur.SHOULD)
            .build();

这仍然是 OR 查询,因此您与其中任何一个都有匹配项。这一个明显的问题是气泡绽放的匹配是相等的。这可能也有一些警告。

完整代码的链接在那里


推荐阅读