Re:ゼロから始めるML生活

どちらかといえばエミリア派です

LlamaIndexでHybrid Searchを試す

前回はLlamaIndexのvector searchでFaissを使ってみました。

今回は、検索部分についてメジャーな改善手法であるHybrid SearchをLlamaIndexで試してみたいと思います。

最初にちょっとだけHybrid Searchについて紹介しておきます。 全文検索やベクトル検索など、検索手法にも色々あります。

これら異なる手法を組み合わせることで検索精度を上げる方法がHybrid Searchと呼ばれたりします。

Reciprocal Rank Fusion

複数の検索手法を組み合わせるのには、RRFというものが使われることが多いようです。

Reciprocal Rank Fusion (RRF) は、以前にランク付けされた複数の結果の検索スコアを評価して、統合された結果セットを生成するアルゴリズムです。 ハイブリッド検索のスコアリング (RRF) - Azure AI Search | Microsoft Learn

Hybrid Searchでは、複数の検索アルゴリズムを組み合わせて最終的な検索結果を応答します。 このときにそれぞれの検索における順位の逆数(にハイパラkを加えたもの)の和を計算します。

rrf = 1/(rank_by_algo_a + k) + 1/(rank_by_algo_b + k)

このようにして最終的なスコアを計算されるのが割と一般的なようです。

QueryFusionRetriever

こうしたHybrid Searchを実現する機能もLlamaIndexで提供されていたりします。 QueryFusionRetrieverというのを使うとできたりします。

QueryFusionRetrieverはこのあたりのドキュメントが参考になります。

docs.llamaindex.ai

使うときはこんな感じで複数のretrieverを突っ込んであげれば使えるようです。

import nest_asyncio

nest_asyncio.apply()

from llama_index.core.retrievers import QueryFusionRetriever

retriever = QueryFusionRetriever(
    [
        index.as_retriever(similarity_top_k=2),
        BM25Retriever.from_defaults(
            docstore=index.docstore, similarity_top_k=2
        ),
    ],
    num_queries=1,
    use_async=True,
)

ただし、BM25を使う際には日本語はtokenizerを日本語のものを使ってあげないと変な検索をされるので注意が必要です。 日本語tokenizerの使い方はこの辺を使って上げるとできるようになります。

zenn.dev

やってみる

概要はこんなもんなので、実際にやってみたいと思います。

コードはこんなもんです。

今回はとりあえず動かすだけです。 まあ精度評価は今度改めてやるので、今回は使い方まで。

参考文献

この記事を書くにあたって下記の文献を参考にさせていただきました。

感想

以上、今回はLlamaIndexでHybrid Searchをやってみました。 意外と簡単に書けるので、LlamaIndexをお使いの方は試してみてはいかがでしょうか。