前回はLlamaIndexのvector searchでFaissを使ってみました。
今回は、検索部分についてメジャーな改善手法であるHybrid SearchをLlamaIndexで試してみたいと思います。
Hybrid Search
最初にちょっとだけ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はこのあたりのドキュメントが参考になります。
使うときはこんな感じで複数の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の使い方はこの辺を使って上げるとできるようになります。
やってみる
概要はこんなもんなので、実際にやってみたいと思います。
コードはこんなもんです。
今回はとりあえず動かすだけです。 まあ精度評価は今度改めてやるので、今回は使い方まで。
参考文献
この記事を書くにあたって下記の文献を参考にさせていただきました。
- BM25 Retriever - LlamaIndex
- BM25 Retriever - LlamaIndex
- Building an Advanced Fusion Retriever from Scratch - LlamaIndex
- Building an Advanced Fusion Retriever from Scratch 解説
- ハイブリッド検索で必ずしも検索性能が上がるわけではない - Ahogrammer
- LlamaIndexでRAG Fusionを試す
感想
以上、今回はLlamaIndexでHybrid Searchをやってみました。 意外と簡単に書けるので、LlamaIndexをお使いの方は試してみてはいかがでしょうか。