Lucene评分机制

Lucene评分机制,lucene,Lucene,我有3个产品名称,它们是 Bounty Select-A-Size白色纸巾12百万卷 Bounty精选A号纸巾(12卷) Bounty Select-A-Size纸巾白色12百万卷 正如你所看到的,第一个和第三个词是相同的,除了单词“White”的位置。第二个术语缺少“白色”和“巨型”两个词 现在,当我运行以下代码时: publicstaticvoidmain(字符串[]args)抛出IOException、ParseException{ StandardAnalyzer=新的StandardA

我有3个产品名称,它们是

  • Bounty Select-A-Size白色纸巾12百万卷
  • Bounty精选A号纸巾(12卷)
  • Bounty Select-A-Size纸巾白色12百万卷
  • 正如你所看到的,第一个和第三个词是相同的,除了单词“White”的位置。第二个术语缺少“白色”和“巨型”两个词

    现在,当我运行以下代码时:

    publicstaticvoidmain(字符串[]args)抛出IOException、ParseException{
    StandardAnalyzer=新的StandardAnalyzer();
    //1.创建索引
    目录索引=新的RAMDirectory();
    IndexWriterConfig配置=新的IndexWriterConfig(分析器);
    IndexWriter w=新的IndexWriter(索引,配置);
    addDoc(w,“赏金精选A号白色纸巾12百万卷”);
    addDoc(w,“赏金精选A号纸巾(12卷)”;
    addDoc(w,“赏金精选A号纸巾白色12百万卷”);
    w、 close();
    //2.查询
    String querystr=“Bounty Select-A-Size白色纸巾12百万卷”;
    Query q=新的QueryParser(“title”,analyzer).parse(querystr);
    //3.搜索
    IndexReader=DirectoryReader.open(索引);
    IndexSearcher search=新的IndexSearcher(阅读器);
    ScoreDoc[]hits=searcher.search(q,4).scoreDocs;
    //4.显示结果
    System.out.println(“Found”+hits.length+“hits.”);
    
    对于(inti=0;i,这是完全正常的,并且根本不表示代码中存在错误

    当索引内容更改时,分数可能会更改,即使这些更改似乎与您的特定查询没有多大关系。分数实际上只在特定搜索执行的上下文中有效,因此它们的绝对值实际上并不重要,但相对于q的其他结果,这些值是有意义的在两个结果集中,前两个得分相等,而另一个得分明显较低

    这里更改的主要原因是评分因素。这是为了对整个索引中出现频率较低的术语进行更重的权衡,其思想是像“The”这样的常见术语作为搜索结果不如像“geronimo”这样的不常见术语有趣

    在您的例子中,您的最佳结果和第三个结果之间的比率已经缩小了一点,因为语料库的其余部分都可用,所以“白色”和“巨型”似乎比查询中的其他一些词更常见(因此,不太有趣)


    另一个注意事项:您可以使用Lucene的方法来获取有关文档为什么会这样评分的详细信息:

    System.out.println(searcher.explain(查询,docNumber.toString());
    
    一般来说,Lucene在不同查询(或在不同数据集上的同一查询)中的得分是不可比较的。如果你接受这一事实,你和Lucene将成为好朋友。重要的是,在这两种情况下,两个“同等”条目并列第一,不太正确的条目并列第三(大约占获胜分数的60-70%)。一条关于我答案的评论指出,我误读了你第二个结果集中的结果顺序。我猜测在键入问题时输入的结果不正确,结果2和3应该交换。我的假设正确吗?@femtoRgon感谢你与Codo的讨论,我确实发现了我代码中的错误。你是对的,结果2和3应该互换,这不是我问题中的错误,相反,我的代码中的错误导致了这种情况的发生……我学到的是:我问题中的情况永远不会发生,如果两个字符串彼此突变(相同的元素,不同的位置),它们应该总是有相同的分数(td idf是每个元素分数的总和,相同的元素,相同的分数)。但是当使用不同的数据集时,分数可能会改变。非常感谢!@user2628641
    如果两个字符串是彼此的突变(相同的元素,不同的位置),它们应该总是具有相同的分数
    ,除非您使用近似搜索,请参见示例。@biziclop问题:如果我不添加近似约束,只需查询“白纸毛巾”,那么,据我所知,Lucene将查找所有包含“白”或“纸”或“毛巾”的术语,并给出td idf分数。因此,我不认为我的陈述仅适用于近距离搜索。在我的示例中,在修复错误后,术语1和3的分数相同,即使它们的距离为4。如果我的理解有误,请更正我。谢谢!您的回答没有解释为什么两个文档使用相同的单词(顺序不同)有一个不同的分数。这让我很惊讶,看起来像一个bug。你的5000个文档中有什么样的数据,其他文档类似吗?这里看起来“白色”比语料库中的“纸”更独特(“纸”几乎是所有文档的一部分”),这就是为什么IDF对“纸”的分数正在使您的第三个文档的分数降低。但请选中“searcher.explain(查询,文档编号)”对每个匹配文档进行确认。@Codo-这看起来很奇怪,是的,但这并不是这个问题所提出的情况。如果你遇到这种行为并且发现很难解释,请问你自己的问题。@femtoRgon你确定吗?这个问题不是很具体。但是,正如他/她明确提到的那样h相同的单词顺序不同,这可能是他/她在寻找解释的原因。@Codo-只是看得更仔细了,你的权利,第二个结果集确实是这样。但是,我强烈怀疑,这是在键入问题时犯的错误。我已经对问题进行了评论,要求澄清。
     1. Bounty Select-A-Size White Paper Towels 12 Mega Rolls    score 0.7363191
     2. Bounty Select-A-Size Paper Towels White 12 Mega Rolls    score 0.7363191
     3. Bounty Select-A-Size Paper Towels (12 rolls)     score 0.42395753
    
     1. Bounty Select-A-Size White Paper Towels 12 Mega Rolls             4.1677103
     2. Bounty Select-A-Size Paper Towels (12 rolls)                     4.1677103
     3. Bounty Select-A-Size Paper Towels White 12 Mega Rolls            2.874553