我正在使用Lucene 7.6.0,并且已经用FeatureField
命名了一系列文档,这些文档名为“功能”,用于存储独立于查询的证据(例如“ indegree”,“ pagerank”)。如果我没记错的话,理论上是将它们存储为术语向量,其中“ indegree”和“ pagerank”存储为术语,其值存储为对应的术语频率。
我已经测试了一些将BM25与每个功能组合在一起的查询,并且与单独使用BM25相比,有些查询返回的排名不同,但是其他一些查询似乎没有效果。这可能只是一个巧合,这很好,但是我想检查这些值是否已正确索引。我该怎么做?
我尝试使用Luke检查索引,但是没有与“功能”字段相关的术语向量。 “功能”的活动标志仅是“ Idf”,但是老实说,我找不到一种访问每个文档频率的方法。为了检查该字段是否有任何价值,我能做的最好的事情是:
IndexReader reader = DirectoryReader.open(
FSDirectory.open(Paths.get("/tmp/lucene-index")));
reader.totalTermFreq(new Term("features", "indegree"));
这会打印数字33344,该数字与我索引的值(索引为10的单个文档)不匹配,但是我怀疑这可能会以某种方式被整理。
我知道该API仍处于试验阶段,但是我想知道是否有人可以为每个文档或以某种方式全局检索特征值(可能是匿名矢量,而没有指向相应文档的链接)
答案 0 :(得分:0)
我能够验证每个功能的排名是否与我拥有的数据的顺序匹配。我还相信我能够相当地反转所提供的相关性得分以获得原始特征值(我说“很合理”,因为我发现似乎有些四舍五入的错误;请告诉我这是否是错误)。我使用的代码如下:
IndexReader reader = DirectoryReader.open(
FSDirectory.open(Paths.get("/tmp/lucene-index")));
IndexSearcher searcher = new IndexSearcher(reader);
searcher.setSimilarity(new BM25Similarity(1.2f, 0.75f));
float w = 1.8f;
float k = 1f;
float a = 0.6f;
Query query = FeatureField.newSigmoidQuery("features", "indegree", w, k, a);
TopDocs hits = searcher.search(query, 5);
for (int i = 0; i < hits.scoreDocs.length; i++) {
Document doc = searcher.doc(hits.scoreDocs[i].doc);
float featureValue = (float) Math.pow(
(hits.scoreDocs[i].score / w * Math.pow(k, a))
/ (1 - hits.scoreDocs[i].score / w),
1 / a
);
System.out.println(featureValue + "\t" + doc.get("doc_id"));
}
reader.close();
featureValue
的等式只是根据相关性分数对S
求解的静态特征S
(在这种情况下为“度数”)的S形缩放。您可以在Lucene的JavaDoc中为FeatureField
引用的论文中找到原始方程:https://dl.acm.org/citation.cfm?doid=1076034.1076106
如果您发现此解决方案有任何错误,或者有更简便的方法来检查索引,请告诉我。