【问题标题】:How to use query terms tfidf as a factor in document similarity calculation in Lucene如何在 Lucene 中使用查询词 tfidf 作为文档相似度计算的一个因素
【发布时间】:2014-05-18 13:36:44
【问题描述】:

我正在尝试通过 Lucene 实现显式语义分析 (ESA)。

在匹配文档时如何将查询中的术语 TFIDF 考虑在内?

例如:

  • 查询:“a b c a d a”
  • Doc1:"a b a"
  • Doc2:"a b c"

查询应该比 2 更好地匹配 Doc1。

我希望它在不影响性能的情况下工作。

我通过查询提升来做到这一点。通过提升与其 TFIDF 相关的术语。

有没有更好的办法?

【问题讨论】:

    标签: lucene information-retrieval


    【解决方案1】:

    Lucene 已经支持 TF/IDF 评分,当然,默认情况下,所以我不太确定我理解你在寻找什么。

    这听起来有点像您想根据查询本身中的 TF/IDF 来权衡查询词。因此,让我们考虑其中的两个要素:

    • TF:Lucene 对每个查询词的得分求和。如果相同的查询词出现两次,在查询中(如field:(a a b)),加倍的词将获得与提升 2 相当的权重(但绝不等同于)。

    • IDF:idf 是指跨多文档语料库的数据。由于只有一个查询,因此不适用。或者,如果您想了解有关它的技术,所有术语的 idf 均为 1。

    因此,IDF 在这种情况下实际上没有意义,而 TF 已经为您完成了。所以,你真的不需要做任何事情。

    请记住,虽然还有其他得分元素! coord 因素在这里很重要。

    • a b a 匹配四个查询词(a b a a,但不匹配 c d
    • a b c 匹配五个查询词(a b a c a,但不匹配 d

    因此,该特定评分元素将对第二个文档评分更高。


    这里是文档a b aexplain(参见IndexSearcher.explain)输出:

    0.26880693 = (MATCH) product of:
      0.40321037 = (MATCH) sum of:
        0.10876686 = (MATCH) weight(text:a in 0) [DefaultSimilarity], result of:
          0.10876686 = score(doc=0,freq=2.0 = termFreq=2.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.42039964 = fieldWeight in 0, product of:
              1.4142135 = tf(freq=2.0), with freq of:
                2.0 = termFreq=2.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=0)
        0.07690979 = (MATCH) weight(text:b in 0) [DefaultSimilarity], result of:
          0.07690979 = score(doc=0,freq=1.0 = termFreq=1.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.29726744 = fieldWeight in 0, product of:
              1.0 = tf(freq=1.0), with freq of:
                1.0 = termFreq=1.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=0)
        0.10876686 = (MATCH) weight(text:a in 0) [DefaultSimilarity], result of:
          0.10876686 = score(doc=0,freq=2.0 = termFreq=2.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.42039964 = fieldWeight in 0, product of:
              1.4142135 = tf(freq=2.0), with freq of:
                2.0 = termFreq=2.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=0)
        0.10876686 = (MATCH) weight(text:a in 0) [DefaultSimilarity], result of:
          0.10876686 = score(doc=0,freq=2.0 = termFreq=2.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.42039964 = fieldWeight in 0, product of:
              1.4142135 = tf(freq=2.0), with freq of:
                2.0 = termFreq=2.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=0)
      0.6666667 = coord(4/6)
    

    对于文档a b c

    0.43768594 = (MATCH) product of:
      0.52522314 = (MATCH) sum of:
        0.07690979 = (MATCH) weight(text:a in 1) [DefaultSimilarity], result of:
          0.07690979 = score(doc=1,freq=1.0 = termFreq=1.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.29726744 = fieldWeight in 1, product of:
              1.0 = tf(freq=1.0), with freq of:
                1.0 = termFreq=1.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=1)
        0.07690979 = (MATCH) weight(text:b in 1) [DefaultSimilarity], result of:
          0.07690979 = score(doc=1,freq=1.0 = termFreq=1.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.29726744 = fieldWeight in 1, product of:
              1.0 = tf(freq=1.0), with freq of:
                1.0 = termFreq=1.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=1)
        0.07690979 = (MATCH) weight(text:a in 1) [DefaultSimilarity], result of:
          0.07690979 = score(doc=1,freq=1.0 = termFreq=1.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.29726744 = fieldWeight in 1, product of:
              1.0 = tf(freq=1.0), with freq of:
                1.0 = termFreq=1.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=1)
        0.217584 = (MATCH) weight(text:c in 1) [DefaultSimilarity], result of:
          0.217584 = score(doc=1,freq=1.0 = termFreq=1.0
    ), product of:
            0.435168 = queryWeight, product of:
              1.0 = idf(docFreq=1, maxDocs=2)
              0.435168 = queryNorm
            0.5 = fieldWeight in 1, product of:
              1.0 = tf(freq=1.0), with freq of:
                1.0 = termFreq=1.0
              1.0 = idf(docFreq=1, maxDocs=2)
              0.5 = fieldNorm(doc=1)
        0.07690979 = (MATCH) weight(text:a in 1) [DefaultSimilarity], result of:
          0.07690979 = score(doc=1,freq=1.0 = termFreq=1.0
    ), product of:
            0.25872254 = queryWeight, product of:
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.435168 = queryNorm
            0.29726744 = fieldWeight in 1, product of:
              1.0 = tf(freq=1.0), with freq of:
                1.0 = termFreq=1.0
              0.5945349 = idf(docFreq=2, maxDocs=2)
              0.5 = fieldNorm(doc=1)
      0.8333333 = coord(5/6)
    

    请注意,根据需要,与术语 a 的匹配项在第一个文档中获得更高的权重,您还会看到每个独立的 a 单独评估并添加到分数中。

    但是,还要注意坐标的差异,以及第二个文档中术语“c”的 idf 上的差异。这些分数影响只是消除了通过添加相同术语的倍数所获得的提升。如果您在查询中添加足够多的as,它们最终会交换位置。 c 上的匹配只是被评估为更重要的结果。

    【讨论】:

    • Lucene 默认支持 TF/IDF 评分,但仅针对已编入索引的文档。您正确理解我想根据它们的 TF/IDF 来权衡查询词。 IDF 取自索引文档,而 TF 取自查询本身。
    • 这里的坐标系数有什么不同?我希望考虑到 aba 对 a 有更高的 TF 并且查询对 a 也有更高的 TF。
    • IDF 已经被考虑在内,并且实际上与您要求的结果相反。由于 c 仅出现在 1 个文档中,而不是两个文档中,因此它的匹配项会获得更高的分数。正如我所解释的,仅仅凭借布尔查询如何接收附加分数。更多的术语匹配会获得更高的分数,因此您的查询 TF 也已经得到处理。 coord 与您期望的结果相反。更多的查询词匹配 = 更高的分数。 doc1 上的坐标是 4/6。 doc2 的坐标是 5/6。在 idf 和 coord 之间,c 上的匹配只是对分数的影响更大。
    • 我在答案中添加了一些explain 输出来证明这一点。查看编辑。
    • 非常感谢您的回答!正如您所说,Coord 是这里的关键,它使我的结果与我的预期不一致。在默认相似度中覆盖坐标解决了这个问题。
    猜你喜欢
    • 2017-10-24
    • 2012-05-25
    • 1970-01-01
    • 2018-10-26
    • 2011-03-27
    • 2011-11-05
    • 2017-04-19
    • 2012-05-08
    • 2019-10-23
    相关资源
    最近更新 更多