Apache Luceneにおける検索結果の関連度スコアリングとカスタムランキング手法

Apache Luceneの検索エンジンでは、クエリとドキュメントの関連性を数値化するスコアリングメカニズムが採用されています。このスコアに基づき、検索結果が自動的にソートされます。

スコアリングの基本原理

LuceneはTF-IDFアルゴリズムを基盤として関連度を算出します。重要な要素は以下の2点です:

  • 出現頻度(Term Frequency):特定の用語がドキュメント内で現れる回数。頻度が高いほどそのドキュメントとの関連性が高くなります。
  • 逆文書頻度(Inverse Document Frequency):用語が全ドキュメント中でどれだけ稀に出現するか。一般的な単語(例:冠詞)はスコアに影響を与えにくくなります。

スコア計算は検索実行時に動的に行われ、各用語の重み付けを基にドキュメント全体の関連度スコアを導出します。

カスタムランキングの実装方法

特定ドキュメントの優先度を調整する場合、フィールドレベルでブースト値を設定します。デフォルト値は1.0ですが、重要なコンテンツには100.0などの高値を設定可能です。

public void 商品ドキュメントの優先度調整() throws IOException {
    try (Directory indexDir = NIOFSDirectory.open(Paths.get("/var/lucene/index"));
         IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(new SmartChineseAnalyzer()))) {
        
        Document targetDoc = new Document();
        targetDoc.add(new StringField("商品ID", "SP-2024", Field.Store.YES));
        
        // 特定商品のタイトルに優先度設定
        TextField titleField = new TextField("商品名", "検索最適化ガイド", Field.Store.YES);
        titleField.setBoost(商品ID.equals("SP-2024") ? 150.0f : 1.0f);
        targetDoc.add(titleField);
        
        // 価格と画像情報の追加
        targetDoc.add(new FloatPoint("価格", 3980.0f));
        targetDoc.add(new StoredField("サムネイル", "search_guide.jpg"));
        
        // 既存ドキュメントの置換処理
        indexWriter.updateDocuments(new Term("商品ID", "SP-2024"), List.of(targetDoc));
    }
}

インデックス作成時にブースト値を動的に設定する場合、以下のように条件分岐を実装します:

// 商品データをドキュメントに変換する処理
TextField createTitleField(Product item) {
    TextField field = new TextField("商品名", item.getName(), Field.Store.YES);
    if (item.isPromoted() && item.getCategory() == Category.SEARCH_ENGINE) {
        field.setBoost(120.0f); // 広告契約商品に高ブースト
    }
    return field;
}

この手法により、検索結果の順序をビジネス要件に応じて柔軟に制御できます。ブースト値は1.0未満に設定することで相対的な重要度を下げることも可能です。

タグ: Apache-Lucene 検索エンジン リランキング Java-API

5月20日 06:26 投稿