2012-01-13 7 views
1

luceneの2つのドキュメント間の類似性を見つける組み込みアルゴリズムはありますか? デフォルトの類似性クラスを調べると、クエリとドキュメントを比較した結果として得点が与えられます。2つのドキュメント間の類似性を見つける

私はすでに雪だるまアナライザを使用して私のドキュメントをインデックス化しました、次のステップは、2つのドキュメント間の類似性を見つけることです。

誰かが解決策を提案できますか?

+0

http://stackoverflow.com/questions/1844194/get-cosine-similarity-between-two-documents-in-lucene – Mikos

答えて

0

組み込みのアルゴリズムがないようです。

a)いずれかのドキュメントでMoreLikeThisクエリを実行します。結果を繰り返し、文書IDとスコアを確認してください。きれいではないかもしれませんが、返されたものの中にたくさんのドキュメントを戻す必要があるかもしれません。

b)コサイン類似度:ココインの類似性は、2つのドキュメントでどのように計算できるかを説明するMikosのコメントに記載されています。

c)独自のLucene類似度スコアを計算します。 Luceneスコアは、Cosine類似度(http://lucene.apache.org/core/4_2_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html)にいくつかの要因を追加します。

あなたは順番に、あなたの二つの文書の最初のためTermVectorを使用して長期的な統計情報を取得することができます

AtomicReaderContext arc = IndexReader.leaves().get(0); 
SimWeight stats = ds.computeWeight(1, collectionStats, termStats); 
stats.normalize(1, 1); 

を通じて例えばパラメータを取得することができます

DefaultSimilarity ds = new DefaultSimilarity(); 
SimScorer scorer = ds.simScorer(stats , arc); 
scorer.score(otherDocId, freq); 

を使用することができ、かつコレクションの統計情報のIndexReader。 freqパラメータを取得するには、あなたが最初のドキュメントのドキュメントIDを見つけるまで、ドキュメントを反復処理、

DocsEnum docsEnum = MultiFields.getTermDocsEnum(reader, null, field, term); 

を使用して、あなたが「scorer.score」を呼び出す必要が

freq = docsEnum.freq(); 

注を行います最初の文書で各用語(または考慮する各用語)を入力し、結果を合計します。 「queryNorm」と「COORD」パラメータに掛ける最後に

、あなたが

//sumWeights was computed while iterating over the first termvector 
//in the main loop by summing up "stats.getValueForNormalization();" 
float queryNorm = ds.queryNorm(sumWeights); 
//thisTV and otherTV are termvectors for the two documents. 
//overlap can be easily calculated 
float coord = ds.coord(overlap, (int) Math.min(thisTV.size(), otherTV.size())); 
return coord * queryNorm * score; 

を使用することができますので、これは動作するはずの方法です。それはエレガントではなく、用語の頻度を得るのが難しいため(各用語に対してDocsEnumを繰り返します)、あまり効率的でもありません。私はまだこれが何かを助けることを願っています:)

関連する問題