46.5kデモを予約するログイン無料で始める

Milvusハイブリッド検索を始める

Apr 30, 20243 min read

Milvus 2.4](https://milvus.io/blog/milvus-2-4-nvidia-cagra-gpu-index-multivector-search-sparse-vector-support.md)のリリースに伴い、マルチベクトル検索とハイブリッド検索(マルチベクトル検索)の機能を導入しました。この新機能は、ユーザーがハイブリッド検索を行い、複数のベクトルフィールドに同時にクエリを実行し、結果を再ランキング戦略で統合することで、データの検索・分析方法を強化するものである。

ハイブリッド検索は、しばしばマルチ・ベクトル検索と呼ばれ、同一データセット内の様々なベクトル・フィールドを横断して検索を行うプロセスである。これらのベクトルは、データの異なる面を表したり、多様な埋め込みモデルを利用したり、異なるデータ処理方法を採用したり、再ランカーを使って結果を組み合わせたりすることができる。

このチュートリアルでは、Milvus 2.4のハイブリッド検索機能を活用して検索を強化する方法を学びます。このチュートリアルでは

  • スパース埋め込み](https://zilliz.com/learn/enhancing-information-retrieval-learned-sparse-embeddings)の作成

  • 密な埋め込み

  • Milvusでインデックスを作成する

  • 同じコレクションを使って多ベクトル検索を行う

このチュートリアルでは、Amazonの包括的な商品検索データセットであるeSciデータセットを利用します。また、pymilvus[models]ライブラリ経由でBGE-M3モデルを使用します。これにより、Milvus内で直接埋め込みを簡単に生成することができます。

ハイブリッド検索入門

ハイブリッド検索は、検索結果を向上させるために、スパース検索手法とデンス検索手法の長所を組み合わせた強力な手法である。伝統的なスパース検索手法は、特定のシナリオでは効果的ですが、しばしば表現力の制限や柔軟性の欠如に悩まされます。ハイブリッド検索は、スパース検索手法とデンス検索手法を融合させることでこれらの制限に対処し、より正確で効率的な検索結果を可能にする。

スパースと密なベクトルの相補的な強みを活用することで、ハイブリッド検索は完全一致とデータの意味的ニュアンスの両方を捉えることができる。その結果、より包括的で正確な検索体験が得られる。テキスト、画像、その他どのようなタイプのデータを扱っていても、ハイブリッド検索は検索結果の関連性と質を大幅に向上させることができます。

ベクター検索を理解する

ベクトル検索とは、ベクトルを使ってデータを表現する検索の一種です。ベクトルはデータポイントの本質をとらえる数学的表現であり、データポイント間の類似性の計算を可能にする。ベクトル検索では、データと検索クエリの両方がベクトルに変換される。そして、クエリーベクトルとデータベクトル間の類似性が計算され、最も類似したデータポイントが検索結果として返される。

このアプローチは、関連情報を効率的かつスケーラブルに検索できるため、大規模なデータセットの検索に特に有効である。ベクトル検索は、画像検索やテキスト検索を含む様々なドメインに適用することができ、意味的に類似したアイテムを見つけることに優れている。ベクトルの力を活用することで、より正確で意味のある検索結果を得ることができます。

必要なライブラリのインストールとインポート、インデックスの作成

pip install pymilvus[model] datasets
import pandas as pd
from datasets import load_dataset

from pymilvus import (
    フィールドスキーマ
    コレクションスキーマ
    DataType、
    コレクション
    AnnSearchRequest、
    RRFRanker、
    コネクション、
)

from pymilvus.model.hybrid import BGEM3EmbeddingFunction

データセットを準備する

ESCIデータセットは、クエリと商品のsemanticマッチングのために設計されています。このセクションでは、ESCIデータセットを準備します。データのサブセットを選択し、クリーンで処理の準備が整っていることを確認することに焦点を当てます。

サブセットのダウンロードと選択

dataset = load_dataset("tasksource/esci", split="train")

データセット = dataset.select(range(500))
dataset = dataset.filter(lambda x: x["product_locale"] == "us")
データセット

データをきれいにする

データセットのクリーニングは、重複や情報の欠落による悪い検索結果を避けるために非常に重要である。

source_df = dataset.to_pandas()

df = source_df.drop_duplicates()
    subset=["product_text", "product_title", "product_bullet_point", "product_brand"]].
)
# 欠損値のある行を削除する
df = df.dropna(
    subset=["product_text", "product_title", "product_bullet_point", "product_brand"].
)
df.head()

データの内容を簡単に見てみよう:

    example_id query query_id product_id product_locale esci_label small_version large_version product_title product_description product_bullet_point product_brand product_color product_text
0 0 revent 80 cfm 0 B000MOO21W us Irrelevant 0 1 パナソニックFV-20VQ3 WhisperCeiling 190 CFM Ceil...   なし WhisperCeilingファンは、完全に密閉された...   パナソニックホワイト パナソニックFV-20VQ3 WhisperCeiling 190 CFM 天井扇...
2 1 revent 80 cfm 0 B07X3Y6B1V us Exact 0 1 Homewerks 7141-80 浴室用ファン一体型LED...   なし 卓越した性能: このHomewerkの浴室扇風機は、LEDを内蔵しています。   Homewerks 80 CFM Homewerks 7141-80 浴室ファン一体型 LED ...
3 2 revent 80 cfm 0 B07WDM7MQQ us Exact 0 1 Homewerks 7140-80 浴室用ファン 天井取付型 E...   なし 卓越した性能: このHomewerkの浴室扇風機は、浴槽に直接取り付けることができます。   ホームワークス ホワイト ホームワークス 7140-80 浴室ファン 天井取付型 E...
4 3 revent 80 cfm 0 B07RH6Z8KW us Exact 0 1 Delta Electronics RAD80L BreezRadiance 80 CFM ... この中古または再生品は...   1.5sonesの静かな動作内蔵サーモ...   デルタ電子(アメリカ)株式会社   ホワイト デルタエレクトロニクス RAD80L BreezRadiance 80 CFM ...
5 4 revent 80 cfm 0 B07QJ7WYFQ us Exact 0 1 パナソニックFV-08VRE2換気扇レセ...   パナソニック FV-08VRE2 扇風機と照明の組み合わせのためのデザインソリューション...   パナソニック ホワイト パナソニック FV-08VRE2 換気扇 レク...

データセットの準備とクリーニングが完了したので、ハイブリッド検索のためにベクトル埋め込みとMilvusでのインデックスを生成することができる。

BGE-M3によるベクトル埋め込み生成

データがきれいになり準備ができたら、次のステップはベクトル埋め込みを生成することです。BGE-M3](https://zilliz.com/learn/Exploring-BGE-M3-the-future-of-information-retrieval-with-milvus)の埋め込みモデルを使って、生のテキストデータをMilvusのベクトルデータベースが効果的にインデックス化・検索できる数値ベクトルに変換します。

テキストデータのマージ

まず、各商品に関連する異なるテキストフィールドを連結し、統一されたテキストベクトル表現を形成します。これにより、製品に関するすべての関連情報を1つのベクトルにまとめることができます:

df["merged_text"] = df["product_title"] + "\n" + df["product_text"] + "\n" + df["product_bullet_point"].
docs = df["merged_text"].to_list()

エンベッディングの生成

ef = BGEM3EmbeddingFunction(use_fp16=False, device="cpu")
dense_dim = ef.dim["dense"].
docs_embeddings = ef(docs)
query = "パナソニック製品の例はありますか?"
query_embeddings = ef([query])

Milvusコレクションのセットアップ

エンベッディングを生成したら、次はスパースと密なベクトルの両方を扱えるコレクションを作成して、これらのベクトルをMilvusに格納します。

Milvusへの接続

Milvus](https://zilliz.com/blog/getting-started-with-a-milvus-connection)サーバへの[接続]を確立することから始めます:

from pymilvus import connections
connections.connect()

コレクションスキーマの定義

fields = [
    # 自動生成されたidを主キーとして使用する
    フィールドスキーマ(
        name="pk", dtype=DataType.VARCHAR, is_primary=True, auto_id=True, max_length=100
    ),
    FieldSchema(name="text",dtype=DataType.VARCHAR,max_length=8192)、
    FieldSchema(name="sparse_vector", dtype=DataType.SPARSE_FLOAT_VECTOR)、
    FieldSchema(name="dense_vector", dtype=DataType.FLOAT_VECTOR, dim=dense_dim)、
]
schema = CollectionSchema(fields, "")
col = Collection("sparse_dense_demo", schema)

ベクトルのインデックスを作成する

sparse_index = {"index_type":"SPARSE_INVERTED_INDEX", "metric_type":"IP"}.
dense_index = {"index_type":"FLAT", "metric_type":"COSINE"}。
col.create_index("sparse_vector", sparse_index)
col.create_index("dense_vector", dense_index)

データをコレクションに挿入する

エンティティ = [
    docs、
    docs_embeddings["sparse"]、
    docs_embeddings["dense"]、
]
col.insert(entities)

ハイブリッド検索の実行

Milvusコレクション](https://zilliz.com/blog/getting-started-with-a-milvus-connection)に必要なデータとインデックスを準備したら、ハイブリッド検索を実行することができます。このステップでは、スパースと密なベクトルの両方を使用してコレクションにクエリを実行し、リランカーを使用して結果を絞り込みます。

def query_hybrid_search(query: str):
    query_embeddings = ef([query])

    sparse_req = AnnSearchRequest(
        query_embeddings["sparse"], "sparse_vector", {"metric_type":"IP"}, limit=2
    )
    dense_req = AnnSearchRequest(
        query_embeddings["dense"], "dense_vector", {"metric_type":"COSINE"}, limit=2
    )

    res = col.hybrid_search(
        [sparse_req, dense_req], rerank=RRFRanker(), limit=2, output_fields=["text"] )
    )

    return res

この関数は、入力クエリに対する埋め込みを生成する。次に、疎なベクトルと密なベクトルに対して 2 つの AnnSearchRequest オブジェクトを作成し、使用する 類似度メトリック の種類を指定します(内積は IP、余弦類似度 は COSINE)。hybrid_search`** メソッドは、RRFRanker を使用して両方のベクトルからの結果を結合し、結合された結果を再ランク付けして、最も関連性の高いマッチを優先します。

ベクトル検索の例

この関数の動作を見るために、実用的なクエリーでハイブリッド検索を実行してみましょう:

query_hybrid_search("Homewerksの製品をお持ちですか?")[0].

出力

['id:449353344520491318, distance:0.032786883413791656, entity:{'text':「Homewerks 7141-80 Bathroom Fan Integrated LED Light Ceiling Mount Exhaust Ventilation, 1.1 Sones, 80 CFMnHomewerks 7141-80 Bathroom Fan Integrated LED Light Ceiling Mount Exhaust Ventilation, 1.1 Sones, 80 CFMnHomewerks 7141-80 Bathroom Fan Integrated LED Light Ceiling Mount Exhaust Ventilation, 1.1 Sones, 80 CFMnHomewerks 7141-80 CFMnHomewerks 7141-80 Bathroom Fan Integrated LED Light Ceiling Mount Exhaust Ventilation, 1.1 Sones, 80 CFMnHomewerks 7141-80 CFMこの換気扇は80CFMで1.1sonesなので、80平方フィートまでの空間を管理でき、とても静かです。ホームワークの浴室換気扇は、強力な換気機能でこのような臭いを取り除きます。]

ハイブリッド検索 vs 単純なベクトル類似度検索

疎な埋め込みと密な埋め込みを混在させずに、密な埋め込みだけを使うと、キーワードの完全一致やカテゴリデータの区別に依存するクエリで問題が発生する可能性がある。疎な埋め込みはうまく処理できる。

例えば、"送料込み "のような非常に特定の属性を探している場合。密なエンベッディングでは、商品のタイプやブランドのような、メインキーワードに関連する幅広いものを検索してしまうかもしれません。

ハイブリッドベクター検索エンジンを使った場合と、密な埋め込みを使った単純なベクトル検索だけを使った場合を比較してみよう:


    def query_dense_search(query: str):
        query_embeddings = ef([query])
        search_param = {
            "data": query_embeddings["dense"]、
            "anns_field":"dense_vector"、
            「param":param": { "metric_type":"cosine"}、
            "limit":2,
            "output_fields":[text"]、
        }
        res_dense = col.search(**search_param)
        return res_dense

> query_dense_search("送料込み")

[

    {

        "id":"449353344520491390",

        "距離":0.5341320037841797,

        "entity":{

            "text":"BAZIC Self Seal White Envelope 3 5/8" x 6 1/2" #6, No Window Mailing Envelopes, Peel & Seal Mailer for Business Invoice Check (100/Pack), 1-PacknBAZIC Self Seal White Envelope 3 5/8" x 6 1/2" #6, No Window Mailing Envelopes、ピール&シールメーラービジネスインボイスチェック用(100/パック)、1-PacknBAZIC製品n#6 3/4(100カウント)n<p><strong>BAZICへ戻る</strong></p> <p>私たちの目標は、手頃なコストで長持ちする消耗品をお客様に提供することです。1998年以来、私たちはこの約束を守り続け、これからも毎年改善を続けていきます。</p> <p><strong>COMMITTED TO VALUES</strong></p> <p>私たちは、低コストで強力な製品設計による卓越性の原則に導かれた、価値主導型の企業です。これらの価値観へのコミットメントは、現行製品の改良と、消費者のためのエキサイティングな新製品の開発への献身に反映されています。私たちは、想像力、情熱、リーダーシップによって成長します。</p> <p><strong>SUCCESS BASED ON SATISFACTION</strong></p> <p>本社は米国カリフォルニア州ロサンゼルスにあります。</p> <p><strong>SUCCESS BASED ON SATISFACTION</strong></p> <p>本社は米国カリフォルニア州ロサンゼルスにあります。私たちの成功は、消費者一人ひとりの充足感から生まれます。</p> <p>私たちは、人々が他の人に薦めたくなるような製品を作っています。3.5/8インチ x 6.1/2インチサイズのセルフシール封筒です。記録的な速さで郵便物を仕上げることができます。はがして封をするだけで、なめたり湿らせたりすることなく、強力なシールが持続します。当社のセルフシール・デザインは素早く簡単で、テープやスティックのり不要の密封性が保証されています。印刷、ラベリング、または手書きによる宛名書きが簡単にできる、窓のないフロントパネルで製造された封筒は、迅速で大量のビジネスmailings.nWHITE 20LB STOCKに最適です。日常的なビジネスユースに最適な標準的な白封筒は、重厚で耐久性のある20ポンド紙で作られており、輸送中に重量のあるファイルをしっかりと保持します。請求書、手紙、小切手、ギフトカードなどを簡単に入れることができます。これらの封筒は、あなたがそれらを必要とする事実上何にでも使用することができます!"

        }

    },

ハイブリッド検索でも同じ


> query_hybrid_search("送料込み")

[

    {

        "id":"449353344520491358",

        "距離":0.016393441706895828,

        "entity":{

            "text":"ASURION 4 Year Home Improvement Protection Plan $20-29.99nASURION 4 Year Home Improvement Protection Plan $20-29.99nASURIONnNonenアシュリオンは、お客様のニーズに合った製品保護プランを探す手間を省きます。製品の故障は、しばしば最も不都合な時に起こります。アシュリオンのプロテクション・プランほど、お客様の製品を保護できるプランは他にないからです。簡単に言えば、アシュリオンのプロテクションプランは、迅速で簡単なクレーム処理で、最も必要なときに製品をカバーします。信頼できる会社からプロテクションプランを購入しましょう。今すぐアシュリオンのプロテクションプランをカートに追加してください!このプランに関する詳細な条件については、以下の「ユーザーガイド[pdf]」をご覧ください。

        }

    }

]

ここでは、ハイブリッド検索が "配送 "が含まれる商品を見つけることができるのに対し、密なエンベッディングは何かを配送できる結果をより求めていることがわかる。

結論

このチュートリアルでは、Milvus 2.4の新しい機能であるハイブリッド検索について説明しました。

Milvus](https://github.com/milvus-io/milvus)やGithubにあるコードを自由にチェックし、Discordに参加してコミュニティと経験を共有してください。

ハイブリッド検索の実施

ハイブリッド検索を行うには、検索結果を改善するためにスパース検索とデンス検索を組み合わせる必要がある。このプロセスには通常以下のステップが含まれる:

1.**データの準備データをベクトルに変換して準備する。これは、テキストデータであれば単語埋め込み、画像データであればimage embeddingsなど、様々な手法を用いて行うことができる。生データを数値ベクトルに変換することで、効率的な索引付けと検索が可能になる。

2.**インデックスの作成データベクトルに対してインデックスを作成する。インデックスとはデータの高速検索を可能にするデータ構造です。Milvusでは、疎なベクトルにも密なベクトルにもインデックスを作成することができ、検索クエリを迅速かつ正確に処理することができます。

3.ハイブリッド検索:スパース検索と高密度検索を組み合わせて、ハイブリッド検索を実行します。相互ランク融合などのテクニックを使用して、両方の検索方法からの結果をマージし、精度とリコールのバランスが取れた最終的なランキングを作成することができる。このステップは、スパース・ベクトルとデンス・ベクトルの両方の長所を活用するために非常に重要です。

4.**結果の取得最終的なランキングに基づいて検索結果を取得する。検索結果は、属性フィルタリングのような様々なテクニックを使って、さらにフィルタリングされ、洗練される。これにより、最も関連性が高く、質の高い結果がユーザーに提示される。

ハイブリッド検索は、検索結果の改善、効率の向上、柔軟性など、いくつかの利点を提供する。画像検索やテキスト検索など様々な用途に使用でき、相互ランク融合やベクトルベースの手法など様々な手法を用いて実装することができる。ハイブリッド検索を行うことで、アプリケーションの特定のニーズに合わせた、より包括的で正確な検索体験を実現することができます。

Updated on Apr 24, 2026