フレーズ一致Compatible with Milvus 2.5.17+

フレーズ一致では、クエリー用語を完全なフレーズとして含む文書を検索できます。デフォルトでは、単語は同じ順序で、互いに直接隣接していなければなりません。例えば、"robotics machine learning "というクエリは、" robotics"、 "machine""learning "という単語が、間に他の単語を挟まずに順番に現れる、"...typical robotics machine learning models... "のようなテキストにマッチします。

しかし、実世界のシナリオでは、厳密なフレーズ・マッチングは厳しすぎることがある。ロボット工学で広く採用されている...機械学習モデル...」のようなテキストにマッチさせたいと思うかもしれない。ここでは、同じキーワードが存在するが、並んだり、元の順序で並んでいるわけではない。これを処理するために、フレーズマッチはslop パラメータをサポートし、柔軟性を導入している。slop 。この値は、フレーズ内の用語間で何回の位置ずれを許容するかを定義する。例えば、slop 1を指定すると、"machine learning "のクエリは、"...machine deep learning... "のようなテキストにマッチします。

概要

Tantivyサーチエンジンライブラリを搭載したフレーズマッチは、ドキュメント内の単語の位置情報を分析することで機能する。下図はそのプロセスを示しています:

Phrase Match Workflow フレーズ一致のワークフロー

  1. 文書のトークン化Milvusに文書を挿入すると、テキストはアナライザーを使ってトークン(個々の単語または用語)に分割され、各トークンの位置情報が記録されます。例えば、doc_1は["machine" (pos=0), "learning" (pos=1), "boosts" (pos=2), "efficiency" (pos=3)]にトークン化されます。アナライザーの詳細については、アナライザーの概要を参照のこと。

  2. 転置インデックスの作成Milvusは転置インデックスを作成し、各トークンをそのトークンが出現する文書とそれらの文書におけるトークンの位置に対応付ける。

  3. フレーズマッチング: フレーズクエリが実行されると、Milvusは転置インデックス内の各トークンを検索し、それらが正しい順序で出現しているか、また近接して出現しているかをチェックします。slop パラメータは一致するトークン間の最大許容位置数を制御します:

    • slop = 0は、トークンが正確な順序で、かつ、すぐに隣接して(つまり、間に余分な単語が入らないように)出現しなければならないことを意味する。

      • この例では、doc_1"machine "pos=0"learning "pos=1)のみが正確にマッチする。
    • slop = 2は、一致するトークン間の柔軟性や並べ替えを2位置まで許容します。

      • これにより、順序を逆にしたり("learning machine")、トークン間にわずかなずれを持たせたりすることができる。

      • その結果、doc_1doc_2"learning"atpos=0"machine"atpos=1)、doc_3"learning"atpos=1"machine"atpos=2)はすべてマッチする。

フレーズ一致を有効にする

フレーズマッチはmilvusの文字列データ型であるVARCHAR フィールドタイプで機能します。フレーズ一致を有効にするには、enable_analyzerenable_match の両方のパラメータをTrue に設定して、テキスト一致と同様にコレクションスキーマを構成します。

enable_analyzerenable_match

特定のVARCHAR フィールドでフレーズ一致を有効にするには、フィールドスキーマを定義する際にenable_analyzerenable_match の両方のパラメータをTrue に設定します。この設定により、Milvusはテキストをトークン化し、効率的なフレーズマッチに必要な位置情報を持つ転置インデックスを作成するように指示します。

以下はフレーズ一致を有効にするスキーマ定義の例です:

from pymilvus import MilvusClient, DataType

# Create a schema for a new collection
schema = MilvusClient.create_schema(enable_dynamic_field=False)
schema.add_field(
    field_name="id",
    datatype=DataType.INT64,
    is_primary=True,
    auto_id=True
)
# Add a VARCHAR field configured for phrase matching
schema.add_field(
    field_name='text',                 # Name of the field
    datatype=DataType.VARCHAR,         # Field data type set as VARCHAR (string)
    max_length=1000,                   # Maximum length of the string
    enable_analyzer=True,              # Enables text analysis (tokenization)
    enable_match=True                  # Enables inverted indexing for phrase matching
)
schema.add_field(
    field_name="embeddings",
    datatype=DataType.FLOAT_VECTOR,
    dim=5
)

オプション:アナライザーの設定

フレーズ・マッチングの精度は、テキスト・データのトークン化に使用するアナライザーに大きく依存します。異なるアナライザーは異なる言語やテキスト形式に適しており、トークン化と位置の精度に影響を与えます。特定の使用ケースに適したアナライザを選択することで、フレーズ マッチングの結果を最適化できます。

デフォルトでは、Milvusは標準アナライザーを使用します。このアナライザーは、空白と句読点に基づいてテキストをトークン化し、40文字以上のトークンを削除し、テキストを小文字に変換します。デフォルトでは追加のパラメータは必要ありません。詳細については、Standard Analyzerを参照してください。

アプリケーションで特定のアナライザが必要な場合は、analyzer_params パラメータを使用して設定します。例えば、english アナライザを英語テキストのフレーズマッチ用に設定する方法を以下に示します:

# Define analyzer parameters for English-language tokenization
analyzer_params = {
    "type": "english"
}

# Add the VARCHAR field with the English analyzer enabled
schema.add_field(
    field_name='text',                 # Name of the field
    datatype=DataType.VARCHAR,         # Field data type set as VARCHAR
    max_length=1000,                   # Maximum length of the string
    enable_analyzer=True,              # Enables text analysis
    analyzer_params=analyzer_params,   # Specifies the analyzer configuration
    enable_match=True                  # Enables inverted indexing for phrase matching
)

Milvusは様々な言語や用途に合わせたアナライザをサポートしています。詳細については、Analyzer Overviewを参照してください。

フレーズ一致を使用する

コレクションスキーマでVARCHAR フィールドのマッチを有効にすると、PHRASE_MATCH 式を使用してフレーズマッチを実行できます。

PHRASE_MATCH 式は大文字と小文字を区別しません。PHRASE_MATCH またはphrase_match のいずれかを使用できます。

PHRASE_MATCH式の構文

PHRASE_MATCH 式を使用して、検索時にフィールド、フレーズ、およびオプションの柔軟性 (slop) を指定します。構文は以下のとおりです:

PHRASE_MATCH(field_name, phrase, slop)
  • field_name:フレーズ・マッチを実行するVARCHAR フィールドの名前。

  • phrase:検索する正確なフレーズ。

  • slop (オプション)マッチするトークンで許容される位置の最大数を指定する整数。

    • 0 (デフォルト):正確なフレーズのみにマッチします。例例:"machine learning "のフィルターは、"machine learning "には正確にマッチしますが、"machine boosts learning "や "learning machine "にはマッチしません

    • 1:1語追加したり、位置を少しずらすなど、細かいバリエーションを許可します。例例:"machine learning "のフィルターは、"machine boosts learning""machine "と "learning "の間にトークンが1つ)にはマッチするが、"learning machine"(用語が逆)にはマッチしない。

    • 2:用語の順序を逆にしたり、間に最大2つのトークンを入れるなど、より柔軟に対応できます。例例:"machine learning "のフィルターは、"learning machine"(語順が逆)または"machine quickly boosts learning""machine "と "learning "の間に2つのトークンがある)にマッチする。

データセットの例

次の5つのエンティティを含むtech_articlesというコレクションがあるとする:

doc_id

text

1

"機械学習が大規模データ分析の効率を高める"

2

"機械ベースのアプローチを学ぶことは、現代のAIの進歩に不可欠である" 2

3

"ディープラーニングのマシンアーキテクチャが計算負荷を最適化"

4

"機械は、継続的な学習のためにモデルの性能を迅速に向上させる"

5

"高度な機械アルゴリズムの学習がAIの能力を拡張する"

フレーズマッチによるクエリ

query() メソッドを使用する場合、PHRASE_MATCH はスカラーフィルターとして機能します。指定されたフレーズを含むドキュメントのみが(許容されるスループに従って)返される。

例: slop = 0 (完全一致)

この例では、"machine learning "というフレーズを正確に含む文書を、間に余計なトークンを入れずに返します。

# Match documents containing exactly "machine learning"
filter = "PHRASE_MATCH(text, 'machine learning')"

result = client.query(
    collection_name="tech_articles",
    filter=filter,
    output_fields=["id", "text"]
)

期待されるマッチ結果

doc_id

text

1

"機械学習は大規模データ分析の効率を高める"

ドキュメント1だけが、指定された順序で、追加のトークンなしで正確なフレーズ"machine learning "を含んでいます。

フレーズ一致検索

検索操作では、ベクトル類似度ランキングを適用する前に、PHRASE_MATCHを使用して文書をフィルタリングする。この2段階のアプローチは、まずテキストマッチによって候補を絞り込み、次にそれらの候補をベクトル埋め込みに基づいて再ランク付けする。

例: スロップ = 1

ここでは、slop = 1を許容する。このフィルターは、"learning machine "というフレーズを含む文書に、若干の柔軟性を持たせて適用される。

# Example: Filter documents containing "learning machine" with slop=1
filter_slop1 = "PHRASE_MATCH(text, 'learning machine', 1)"

result_slop1 = client.search(
    collection_name="tech_articles",
    anns_field="embeddings",
    data=[query_vector],
    filter=filter_slop1,
    search_params={"params": {"nprobe": 10}},
    limit=10,
    output_fields=["id", "text"]
)

マッチ結果

doc_id

text

2

"機械ベースのアプローチを学ぶことは、現代のAIの進歩に不可欠である"

3

"ディープラーニングマシンのアーキテクチャは計算負荷を最適化する"

5

"高度な機械アルゴリズムの学習がAIの能力を拡張する"

例: スロップ = 2

つまり、"machine ""learning "の間に最大2つの余分なトークン(または逆順の用語)が許容されます。

# Example: Filter documents containing "machine learning" with slop=2
filter_slop2 = "PHRASE_MATCH(text, 'machine learning', 2)"

result_slop2 = client.search(
    collection_name="tech_articles",
    anns_field="embeddings",             # Vector field name
    data=[query_vector],                 # Query vector
    filter=filter_slop2,                 # Filter expression
    search_params={"params": {"nprobe": 10}},
    limit=10,                            # Maximum results to return
    output_fields=["id", "text"]
)

マッチ結果

doc_id

text

1

"機械学習は大規模データ分析の効率を高める"

3

"ディープラーニングマシンアーキテクチャは計算負荷を最適化する"

例: スロップ = 3

この例では、slopを3にすることで、さらに柔軟性が増します。このフィルターでは、単語間のトークン位置を3つまで許容して、"machine learning "を検索します。

# Example: Filter documents containing "machine learning" with slop=3
filter_slop3 = "PHRASE_MATCH(text, 'machine learning', 3)"

result_slop2 = client.search(
    collection_name="tech_articles",
    anns_field="embeddings",             # Vector field name
    data=[query_vector],                 # Query vector
    filter=filter_slop3,                 # Filter expression
    search_params={"params": {"nprobe": 10}},
    limit=10,                            # Maximum results to return
    output_fields=["id", "text"]
)

マッチ結果

doc_id

text

1

"機械学習は大規模データ分析の効率を高める"

2

"機械ベースのアプローチを学ぶことは、現代のAIの進歩に不可欠である"

3

「計算負荷を最適化するディープラーニング・マシンアーキテクチャ

5

"高度な機械アルゴリズムの学習がAIの能力を拡張する"

考察

  • フィールドのフレーズ・マッチングを有効にすると、反転インデックスの作成がトリガーされ、ストレージ・リソースが消費されます。この機能を有効にするかどうかは、テキスト・サイズ、ユニーク・トークン、使用するアナライザーによって異なるため、ストレージへの影響を考慮してください。

  • スキーマでアナライザを定義すると、その設定はそのコレクションに対して永続的になります。別のアナライザの方がニーズに合っていると判断した場合は、既存のコレクションを削除して、希望するアナライザ設定で新しいコレクションを作成することを検討できます。

  • フレーズ一致のパフォーマンスは、テキストがどのようにトークン化されるかに依存します。コレクション全体にアナライザを適用する前に、run_analyzer メソッドを使用してトークン化出力を確認してください。詳細は、Analyzer Overviewを参照してください。

  • filter 式のエスケープ規則:

    • 式内の二重引用符または一重引用符で囲まれた文字は、文字列定数として解釈されます。文字列定数にエスケープ文字が含まれている場合、エスケープ文字をエスケープシーケンスで表す必要があります。例えば、\ を表すには\\ を、タブを表すには\\t を、改行を表すには\t を、\\n を使用する。

    • 'It\\'s milvus'文字列定数が一重引用符で囲まれている場合、定数内の一重引用符は\\' と表現し、二重引用符は" または\\" と表現する。

    • "He said \\"Hi\\""文字列定数が二重引用符で囲まれている場合、定数内の二重引用符は\\" 、一重引用符は' または\\' のように表す。