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

スパースベクトル

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

概要​

スパースベクトルは、ほとんどの要素がゼロで、非ゼロの値を持つ次元がごくわずかしかない特殊な高次元ベクトルです。以下の図に示すように、密ベクトルは通常、各位置に値を持つ連続配列として表現されます(例: [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 を使用することに決めた場合は、Embeddings を参照して、SPLADE でスパースベクトルを生成する方法を確認してください。

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"
)

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

コレクションの作成​

スパースベクトルとインデックスの設定が完了したら、スパースベクトルを含むコレクションを作成できます。以下の例では、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'}}]"]

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