メインコンテンツまでスキップ

スパースベクトル

スパースベクトルは、情報検索や自然言語処理において、表層的な用語一致を捉えるための重要な手法です。密ベクトルは意味理解に優れていますが、スパースベクトルは、特に特殊な用語やテキスト識別子を検索する際に、より予測可能な一致結果を提供することがよくあります。

概要​

スパースベクトルは、ほとんどの要素がゼロで、一部の次元のみが非ゼロ値を持つ特殊な高次元ベクトルです。以下の図に示すように、密ベクトルは通常、各位置が値を持つ連続的な配列として表現されます(例: [0.3, 0.8, 0.2, 0.3, 0.1])。一方、スパースベクトルは非ゼロ要素とその次元のインデックスのみを格納し、多くの場合 { index: value} のキーと値のペアとして表現されます(例: [{2: 0.2}, ..., {9997: 0.5}, {9999: 0.7}])。

VPhswBhHmhJrh3byaVnc3onYnPc

トークン化とスコアリングにより、ドキュメントは bag-of-words ベクトルとして表現でき、各次元は語彙内の特定の単語に対応します。ドキュメントに含まれる単語のみが非ゼロ値を持ち、スパースベクトル表現が生成されます。スパースベクトルは、次の2つのアプローチで生成できます。

  • 従来の統計手法は、TF-IDF(Term Frequency-Inverse Document Frequency)や BM25(Best Matching 25)などの手法で、コーパス全体における単語の頻度と重要度に基づいて単語に重みを割り当てます。これらの手法は、トークンを表す各次元のスコアとして単純な統計量を計算します。Zilliz Cloud は、BM25 方式によるビルトインの全文検索を提供しており、テキストを自動的にスパースベクトルに変換するため、手動での前処理が不要になります。このアプローチは、精度と完全一致が重要となるキーワードベースの検索に最適です。詳細については、全文検索 を参照してください。

  • ニューラルスパース埋め込みモデルは、大規模なデータセットでトレーニングすることによりスパース表現を生成する学習ベースの手法です。これらは通常、Transformer アーキテクチャを採用した深層学習モデルであり、意味的なコンテキストに基づいて用語を拡張し重み付けできます。Zilliz Cloud は、SPLADE などのモデルによって外部で生成されたスパース埋め込みもサポートしています。詳細については、Embeddings を参照してください。

スパースベクトルと元のテキストは、効率的な取得のために Zilliz Cloud に保存できます。以下の図は、全体的なプロセスを示しています。

A7FvwnB5bhpBlKbgrzYcQijbnxg

Notes

スパースベクトルに加えて、Zilliz Cloud は密ベクトルとバイナリベクトルもサポートしています。密ベクトルは深い意味的関係を捉えるのに最適であり、バイナリベクトルは高速な類似度比較やコンテンツの重複排除といったシナリオに優れています。詳細については、密ベクトル と バイナリベクトル を参照してください。

データ形式​

以降のセクションでは、SPLADE のような学習済みスパース埋め込みモデルのベクトルを保存する方法を説明します。密ベクトルベースのセマンティック検索を補完するものをお探しの場合は、簡便さの観点から SPLADE よりも 全文検索 と BM25 の組み合わせをおすすめします。品質評価を実施したうえで SPLADE を使用することを決定した場合は、SPLADE でスパースベクトルを生成する方法について Embeddings を参照してください。

Zilliz Cloud は、次の形式のスパースベクトル入力をサポートしています。

  • 辞書のリスト(形式は {dimension_index: value, ...})

    python
    # Represent each sparse vector using a dictionary
    sparse_vectors = [{27: 0.5, 100: 0.3, 5369: 0.6} , {100: 0.1, 3: 0.8}]
  • スパース行列(scipy.sparse クラスを使用)

    python
    from scipy.sparse import csr_matrix

    # First vector: indices [27, 100, 5369] with values [0.5, 0.3, 0.6]
    # Second vector: indices [3, 100] with values [0.8, 0.1]
    indices = [[27, 100, 5369], [3, 100]]
    values = [[0.5, 0.3, 0.6], [0.8, 0.1]]
    sparse_vectors = [csr_matrix((vals, ([0]*len(idx), idx)), shape=(1, 5369+1)) for idx, vals in zip(indices, values)]
  • タプルの反復可能オブジェクトのリスト(例: [(dimension_index, value)])

    python
    # Represent each sparse vector using a list of iterables (e.g. tuples)
    sparse_vector = [
    [(27, 0.5), (100, 0.3), (5369, 0.6)],
    [(100, 0.1), (3, 0.8)]
    ]

コレクションスキーマを定義する​

コレクションを作成する前に、コレクションスキーマを指定する必要があります。スキーマではフィールドを定義し、オプションでテキストフィールドを対応するスパースベクトル表現に変換する関数を指定します。

フィールドを追加する​

Zilliz Cloud クラスターでスパースベクトルを使用するには、以下のフィールドを含むスキーマを持つコレクションを作成する必要があります。

  • スパースベクトルを格納するために予約された SPARSE_FLOAT_VECTOR フィールドで、VARCHAR フィールドから自動生成されるか、入力データ内で直接指定されます。

  • 通常、スパースベクトルが表す生のテキストもコレクションに格納されます。生のテキストの格納には VARCHAR フィールドを使用できます。

python
from pymilvus import MilvusClient, DataType

client = MilvusClient(uri="YOUR_CLUSTER_ENDPOINT")

schema = client.create_schema(
auto_id=True,
enable_dynamic_fields=True,
)

schema.add_field(field_name="pk", datatype=DataType.VARCHAR, is_primary=True, max_length=100)
schema.add_field(field_name="sparse_vector", datatype=DataType.SPARSE_FLOAT_VECTOR)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=65535, enable_analyzer=True)

この例では、3つのフィールドを追加します。

  • pk: このフィールドは、VARCHAR データ型を使用して主キーを格納します。主キーは最大長 100 バイトで自動生成されます。

  • sparse_vector: このフィールドは、SPARSE_FLOAT_VECTOR データ型を使用してスパースベクトルを格納します。

  • text: このフィールドは、VARCHAR データ型を使用してテキスト文字列を格納します。最大長は 65535 バイトです。

Notes

データ挿入時に、指定されたテキストフィールドからスパースベクトル埋め込みを Zilliz Cloud が生成できるようにするには、関数を含む追加の手順を実行する必要があります。詳細については、全文検索 を参照してください。

インデックスパラメーターを設定する​

スパースベクトルのインデックスを作成するプロセスは、密ベクトル のプロセスと似ていますが、指定するインデックスタイプ(index_type)、距離メトリック(metric_type)、インデックスパラメーター(params)が異なります。

python
index_params = client.prepare_index_params()
index_params.add_index(
field_name="sparse_vector",
index_name="sparse_auto_index",
index_type="AUTOINDEX",
metric_type="IP"
)

この例では、メトリックに IP を指定した SPARSE_INVERTED_INDEX インデックスタイプを使用します。詳細については、以下のリソースを参照してください。

  • メトリクスタイプ: さまざまなフィールドタイプでサポートされるメトリクスタイプ

  • 全文検索: 全文検索に関する詳細なチュートリアル

コレクションを作成する​

スパースベクトルとインデックスの設定が完了したら、スパースベクトルを含むコレクションを作成できます。以下の例では、create_collection メソッドを使用して my_collection という名前のコレクションを作成します。

python
client.create_collection(
collection_name="my_collection",
schema=schema,
index_params=index_params
)

データを挿入する​

コレクション作成時に定義されたすべてのフィールドのデータを指定する必要があります。ただし、自動生成されるフィールド(auto_id が有効な主キーなど)は除きます。ビルトインの BM25 関数を使用してスパースベクトルを自動生成する場合は、データを挿入する際にスパースベクトルフィールドも省略する必要があります。

python
data = [
{
"text": "information retrieval is a field of study.",
"sparse_vector": {1: 0.5, 100: 0.3, 500: 0.8}
},
{
"text": "information retrieval focuses on finding relevant information in large datasets.",
"sparse_vector": {10: 0.1, 200: 0.7, 1000: 0.9}
}
]

client.insert(
collection_name="my_collection",
data=data
)

スパースベクトルを使用して類似検索を実行するには、クエリデータと検索パラメーターの両方を準備します。

python
# Prepare search parameters
search_params = {
"params": {"drop_ratio_search": 0.2}, # A tunable drop ratio parameter with a valid range between 0 and 1
}

# Query with sparse vector
query_data = [{1: 0.2, 50: 0.4, 1000: 0.7}]

次に、search メソッドを使用して類似検索を実行します。

python
res = client.search(
collection_name="my_collection",
data=query_data,
limit=3,
output_fields=["pk"],
search_params=search_params,
consistency_level="Strong"
)

print(res)

# Output
# data: ["[{'id': '453718927992172266', 'distance': 0.6299999952316284, 'entity': {'pk': '453718927992172266'}}, {'id': '453718927992172265', 'distance': 0.10000000149011612, 'entity': {'pk': '453718927992172265'}}]"]

類似検索パラメーターの詳細については、基本的なベクトル検索 を参照してください。