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

スパースベクトル

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

概要​

スパースベクトルは、ほとんどの要素がゼロで、ごく一部の次元だけが非ゼロ値を持つ特殊な高次元ベクトルです。以下の図に示すように、密ベクトルは通常、各位置に値を持つ連続配列として表現されます(例: [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_inverted_index",
index_type="SPARSE_INVERTED_INDEX",
metric_type="IP",
params={"inverted_index_algo": "DAAT_MAXSCORE"}, # or "DAAT_WAND" or "TAAT_NAIVE"
)

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

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

  • 全文検索: 全文検索の詳細なチュートリアル

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

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

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