11institutetext:NLP&IR Group,Universidad Nacional de Educación a Distancia,西班牙 22institutetext:美国北卡罗来纳大学教堂山分校
33institutetext:Answers Corporation,耶路撒冷 91481,以色列

33email: joaquin.perez@lsi.uned.es, jaguera@email.unc.edu, vfresno@lsi.uned.es, yuvalf@answers.com

将概率模型 BM25/BM25F 集成到 Lucene 中。

Joaquín Pérez-Iglesias 11    José R. Pérez-Agüera 22    Víctor Fresno and
Yuval Z. Feinstein
1133
摘要

本文档描述了使用 Lucene Java 框架的 BM25 和 BM25F 实现。 这里描述的实现可以从[Pérez-Iglesias 08a]下载。 这两种模型都因其性能在 TREC 中脱颖而出,并被认为是 IR 社区中最先进的模型。 BM25适用于纯文本文档的检索,即不包含字段的文档,而BM25F适用于有结构的文档。

介绍

Apache Lucene 是一个完全用 Java 编写的高性能、功能齐全的文本搜索引擎库。 该技术几乎适用于任何需要全文搜索的应用程序。 Lucene 具有可扩展性并提供高性能索引,已成为学术界和工业界最常用的搜索引擎库之一[Lucene 09]

Lucene 排名功能是任何搜索引擎的核心,用于确定文档与给定查询的相关程度,它建立在向量空间模型 (VSM) 和信息检索的布尔模型的组合之上。 Lucene 方法背后的主要思想是,查询术语在文档中出现的次数相对于该术语在整个集合中出现的次数越多,该文档与查询的相关性就越高[Lucene 09]. Lucene 还使用布尔模型,首先根据查询规范中布尔逻辑的使用来缩小需要评分的文档范围。

本文详细描述了 BM25 概率模型的实现及其对半结构化 IR 的扩展 BM25F。

Lucene 被 IR 社区广泛使用的主要限制之一是缺乏不同的检索模型实现。 我们这项工作的目标是为 IR 社区提供一个更先进的排名模型,可以与其他 IR 软件(如 Terrier、Lemur、CLAIRlib 或 Xapian)进行比较。

1 动机

Lucene 之前存在替代信息检索模型的实现。 其中最具代表性的案例是语言模型实现111http://ilps.science.uva.nl/resources/lm-lucene,来自阿姆斯特丹智能系统实验室。 [Doron 07] 中描述了另一个例子,其中 Lucene 与 Juru 系统进行了比较。 在这种情况下,Lucene 文档长度规范化被更改,以提高 Lucene 排名功能的性能。

BM25 已被 IR 研究人员和工程师广泛使用来提高搜索引擎的相关性,因此从我们的角度来看,Lucene 的 BM25/BM25F 实现对于使 Lucene 在 IR 社区中更受欢迎是必要的。

包含的型号

开发的模型基于[Robertson 07] 中的信息。 更具体地说,实现的排名功能如下:

BM25

R(q,d)=tqoccurstdk1((1b)+bldavld)+occurstd

其中occurstddt的词频; ld是文档d长度; avld 是沿着集合的文档平均长度; k1 是一个自由参数,通常选择为 2 和 b[0,1](通常为 0.75)。 将0分配给b相当于避免了标准化过程,因此文档长度不会影响最终分数。 如果b取1,我们将进行全长标准化。

经典的逆文档频率计算如下:

idf(t)=logNdf(t)+0.5df(t)+0.5

其中 N 是集合中的文档数,df 是出现术语 t 的文档数。

此公式的不同版本,可以在 Wikipedia222http://en.wikipedia.org/wiki/Probabilistic_relevance_model_(BM25),将获得的bm25权重乘以常数(k1+1),以便用a标准化项的权重平均长度文档中出现的频率等于 1。

BM25F

首先,我们获得一个术语在所有字段上的累积权重,如下所示:

weight(t,d)=c in doccurst,cdboostc((1bc)+bclcavlc)

其中 lc 是字段长度; avlc是字段c的平均长度; bc是与字段长度相关的常数,类似于BM25中的b,boostc是应用于字段c的增强因子。

接下来,应用非线性饱和度weightk1+weight,以减少术语频率对最终分数的影响。

R(q,d)=t in qidf(t)weight(t,d)k1+weight(t,d) (1)

idf(t) 的计算方式与 BM25 情况相同

idf(t)=logNdf(t)+0.5df(t)+0.5 (2)

其中 N 是集合中的文档数,df 是出现术语 t 的文档数。

执行

此实现的主要目标是将新的排名模型集成到 Lucene 搜索功能中。 为了实现这一目标,开发了新的查询、权重和多个评分器。 主要功能是在Scorer级别实现的,因为Query和Weight的主要职责是为Scorers准备必要的参数,并在调用搜索方法时创建Scorers实例。 有关 Query-Weight-Scorer 模型的更多信息,请参阅

询问

查询的执行可以分为两部分:布尔过滤和文档排名。 布尔过滤由记分器ShouldBooleanScorer、MustBooleanScorer 和NotBooleanScorer 根据所应用的逻辑运算符进行,而排名功能则在BM25TermScorer 和BM25FTermScorer 的评分方法中实现。

BM25BooleanScorer 将根据调用的构造函数创建 BM25TermScorer 或 BM25FTermScorer 实例,如下所示:

  • 使用BM25排名功能

    public BM25BooleanQuery(String query, String field, Analyzer analyzer)
    Ψthrows ParseException, IOException
    
  • 使用BM25F排名功能

    public BM25BooleanQuery(String query, String[] fields, Analyzer analyzer)
    Ψthrows ParseException,IOException
    

BM25BooleanScorer 将忽略与 Lucene QueryParser 处理的字段相关的任何信息,因此将仅使用在构造函数中作为参数传递的字段执行搜索。 除了仅支持布尔查询之外,任何其他查询类型都将被拆分为术语并作为布尔查询执行。

应该注意的是,两个排名函数都不使用查询权重,因此所有计算都可以在评分器级别完成。

评分

  • 除了无法直接从提供的 API 获得的文档平均长度之外,几乎所有计算 BM25 相关性所需的信息都可以通过 Lucene Expert API(termdocs、numdocs、docfreq...)获得。 该值可以在索引时获取,实现计算和存储文档字段长度的特定相似度。 如下

    public class CollectionSimilarityIndexer extends DefaultSimilarity {
    
      private static Map< String,Long> length = new HashMap<String, Long>();
    
      @Override
      public float lengthNorm(String fieldName, int numTokens) {
        Long aux = CollectionSimilarityIndexer.length.get(fieldName);
        if (aux==null)
          aux = new Long(0);
        aux+=numTokens;
        CollectionSimilarityIndexer.length.put(fieldName,aux);
        return super.lengthNorm(fieldName, numTokens);
      }
      public static long getLength(String field){
        return CollectionSimilarityIndexer.length.get(field);
      }
    }
    

    在索引过程之后,我们可以检索特定字段的长度,然后可以除以集合 numdocs 并将计算值保存到文件中。 打开搜索器时可以读取该值。 在提供的实现中,BM25Parameters 中提供了方法 load(String filePath),以便加载平均长度,有关文件格式的更多详细信息可以在 [Pérez-Iglesias 08b] 的 javadoc 文档中找到。

  • 具体的 BM25 参数在 BM25Parameters 类中固定,默认设置为 k1=2b=0.75 BM25F 的情况更复杂,因为它需要更具体的参数,主要是一个字符串数组,其中包含应搜索术语的字段。 所有参数均可在 BM25FParameters 中找到,应用相同的 k1 b 相关的每个字段设置为 0.75,但建议使用更好的参数(作为浮点数组提供),这些参数可以在初始化查询时设置。 每个字段的固定提升以类似的方式进行,这些字段已初始化为值 1,但可以使用浮点数组提供。 所有基于 BM25F 的数组参数如 boostfieldbfield 必须按顺序提供,这意味着对于字段 i 到字段数组中,boost 和该字段的 b 参数将位于两个数组中的 i 位置。

  • 在这两个模型中,IDF 均在 BM25Similarity 中计算,并且必须使用 docFreqnumdocs 在文档级别进行计算。 Lucene 在字段级别返回 docFreq,即出现术语 t 的字段(文档内)的数量。 此功能对于 BM25 来说不是问题,因为搜索仅在字段中完成。 对于 BM25F 情况,这是一个严重的问题,因为无法在文档级别计算 IDF,除非对包含所有术语的新字段进行索引。 提供的实现(作为启发式)计算具有最长平均长度的字段中的 docFreq

如何使用它

所提供的实现可以以与使用 Lucene 执行搜索类似的方式使用,但必须在执行查询之前设置 BM25Parameters 或 BM25FParameters,必须这样做才能设置平均长度,其他参数可以省略,因为它们已设置为默认值。

BM25 和 BM25F 耙动功能的示例如下:

BM25

ΨIndexSearcher searcher = new IndexSearcher("IndexPath");

Ψ//Load average length
ΨBM25Parameters.load(avgLengthPath);
ΨBM25BooleanQuery query = new BM25BooleanQuery("This is my Query",
ΨΨ"Search-Field",
ΨΨnew StandardAnalyzer());
Ψ
ΨTopDocs top = searcher.search(query, null, 10);
ΨScoreDoc[] docs = top.scoreDocs;
Ψ
Ψ//Print results
Ψfor (int i = 0; i $<$ top.scoreDocs.length; i++) {
Ψ      System.out.println(docs[i].doc + ":"+docs[i].score);
Ψ}Ψ

BM25F

ΨString[] fields ={"FIELD1","FIELD2"};
ΨIndexSearcher searcher = new IndexSearcher("IndexPath");

Ψ//Set explicit average Length for each field
ΨBM25FParameters.setAverageLength("FIELD1", 123.5f);
ΨBM25FParameters.setAverageLength("FIELD2", 42.2f);
Ψ
Ψ//Set explicit k1 parameter
ΨBM25FParameters.setK1(1.2f);
Ψ
Ψ//Using boost and b defaults parameters
ΨBM25BooleanQuery queryF = new BM25BooleanQuery("This is my query",
ΨΨfields, new StandardAnalyzer());
Ψ
Ψ//Retrieving NOT normalized scorer values
ΨTopDocs top = searcher.search(queryF, null, 10);
ΨScoreDoc[] docs = top.scoreDocs;
Ψ
Ψ//Print results
Ψfor (int i = 0; i $<$ top.scoreDocs.length; i++) {
Ψ      System.out.println(docs[i].doc + ":"+docs[i].score);
Ψ}

致谢

作者要感谢雨果·萨拉戈萨 (Hugo Zaragoza) 的审阅和评论。

参考