我正在尝试解决最近邻搜索问题。 这是我的代码:
// Indexing
val analyzer = new StandardAnalyzer()
val directory = new RAMDirectory()
val config = new IndexWriterConfig(analyzer)
val iwriter = new IndexWriter(directory, config)
val queryField = "fieldname"
stringData.foreach { str =>
val doc = new Document()
doc.add(new TextField(queryField, str, Field.Store.YES))
iwriter.addDocument(doc)
}
iwriter.close()
// Searching
val ireader = DirectoryReader.open(directory)
val isearcher = new IndexSearcher(ireader)
val parser = new QueryParser(queryField, analyzer)
val query = parser.parse("Some text for testing")
val hits = isearcher.search(query, 10).scoreDocs
当我看到价值点击时,我看到得分超过1。
据我所知,lucene评分公式为:
score(q,d) = coord-factor(q,d) · query-boost(q) · cosSim(q,d) · doc-len-norm(d) · doc-boost(d)
但我想在查询和文档之间只获得范围[0,1]中的余弦相似性,而不是coord-factor,doc-len-norm等等。 有什么方法可以实现它?
答案 0 :(得分:1)
如果您已经阅读了这个官方documentation,您会意识到score
表达式中的其余条款非常重要,这使得评分过程更加合理和连贯。
但是如果你想仅使用Cosine Similaity实现评分过程,那么你可以编写自定义相似度类。我在class assignment中使用了不同类型的相似性方法进行文档检索。因此,简而言之,您可以编写自己的相似性方法并将其分配给Lucene的index searcher
。我在这里给出一个例子,你可以修改它来完成你想要的东西。
编写自定义类(您只需要覆盖类中的一个方法)。
import org.apache.lucene.search.similarities.BasicStats;
import org.apache.lucene.search.similarities.SimilarityBase;
public class MySimilarity extends SimilarityBase {
@Override
protected float score(BasicStats stats, float termFreq, float docLength) {
double tf = 1 + (Math.log(termFreq) / Math.log(2));
double idf = Math.log((stats.getNumberOfDocuments() + 1) / stats.getDocFreq()) / Math.log(2);
float dotProduct = (float) (tf * idf);
return dotProduct;
}
}
然后将实施的方法分配给index searcher
进行相关性计算,如下所示。
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(indexPath)));
IndexSearcher indexSearcher = new IndexSearcher(reader);
indexSearcher.setSimilarity(new MySimilarity());
在这里,我使用tf-idf dot产品来计算查询和文档之间的相似性。公式是,
这里需要提到的两件事是:
Lucene现在将调用您已实施的score()
方法来计算每个匹配项的相关性得分;在查询和文档中出现的术语。
这不是我所知道的问题的直接答案,但您可以使用我上面提到的方法。我在家庭作业中实施了6种不同的评分技巧。我希望它也能帮到你。