2016-12-11 14 views
0

私は最近傍探索問題を解決しようとしている。 ここに私のコードです:、私は価値のヒットに見ると、私は私の知る限りでは1Luceneスコアリング:スコアと同じコサイン類似度を得る

、より多くの得点を参照してください

// 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 

Luceneのスコア式は次のとおりです。

score(q,d) = coord-factor(q,d) · query-boost(q) · cosSim(q,d) · doc-len-norm(d) · doc-boost(d) 

しかし、私は、coord-factor、doc-len-normなどの代わりに、クエリとドキュメントの間の範囲[0,1]のコサイン類似度のみを取得したいと考えています。 これを実現する方法はありますか?あなたはこの公式documentation通過した場合は

+0

注意すべき点:その類似式はもはやデフォルトではありません。 6.0以降、Luceneはデフォルトで[BM25](https://en.wikipedia.org/wiki/Okapi_BM25)の実装を使用しています。古いデフォルトは引き続き使用できます。[ClassicSimilarity](http://lucene.apache.org/core/6_2_1/core/org/apache/lucene/search/similarities/ClassicSimilarity.html)を参照してください。 – femtoRgon

答えて

1

、あなたはscore式の用語の残りの部分は重要であり、スコアリングプロセスをより論理的で一貫した作ることを理解するであろう。

しかし、Cosine Similaityのみを使用して得点処理を行いたい場合は、カスタム類似性クラスを作成することができます。私はclass assignmentの文書検索にさまざまなタイプの類似メソッドを使用しました。つまり、あなた自身の類似方法を書いて、それをLuceneのindex searcherに割り当てることができます。私はここであなたが望むものを達成するために変更する例を挙げています。

カスタムクラスを作成します(クラス内の1つのメソッドをオーバーライドするだけです)。

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内積を使用しています。式は

enter image description here

二つの事はここで言及する必要がある、あるある:索引の合計数のドキュメントを返します

  • stats.getNumberOfDocuments()。
  • stats.getDocFreq()は、クエリとドキュメントの両方に出現した用語のドキュメント頻度を返します。

Luceneは、一致した各用語の関連性スコアを計算するために実装したscore()メソッドを呼び出すようになりました。クエリとドキュメントの両方に現れる用語。

これは私が知っているあなたの質問への直接的な答えではありませんが、あなたが望むとにかく上記の方法を使用することができます。私は宿題に6種類のスコアリング手法を実装しました。それがあなたにも役立つことを願っています。

関連する問題