Traffine I/O

日本語

2023-06-11

Pinecone Sparse-Denseベクトル

Pinecone Sparse-Denseベクトル

Pineconeは、高次元のベクトルデータを扱うことに特化したベクトルデータベースであり、高度な検索機能を提供することを目的としています。Pineconeの特徴的な機能の1つは、Sparse-Denseベクトルのサポートです。これにより、キーワード検索とセマンティックサーチを組み合わせたハイブリッドなアプローチが可能となります。

セマンティックサーチとキーワード検索にはそれぞれ異なる強みがあります。セマンティックサーチはDenseベクトルを使用し、正確なキーワードの一致がなくても類似の結果を返すことが得意です。キーワード検索はSparseベクトルを使用し、正確なキーワードの一致がある場合に関連性の高い結果を提供します。PineconeのSparse-Denseベクトル機能は、両方のアプローチの強みを活用し、ドメイン外のクエリに対しても検索結果の関連性を向上させます。

PineconeにおけるSparseベクトルとDenseベクトルの比較

PineconeはDenseベクトルの使用をサポートしており、Denseベクトルは意味のある表現を数値で表したものです。Denseベクトルはセマンティックサーチを可能にし、特定の距離尺度に基づいてもっとも類似した結果を返すことができます。Denseベクトルは通常、SBERT(Sentence-BERT)などの埋め込みモデルによって生成され、テキストデータの意味のある表現を作成します。

Denseベクトルとは対照的に、Sparseベクトルは非ゼロの値がごく一部の高次元データ構造です。キーワード検索の文脈では、各Sparseベクトルはドキュメントを表し、次元は辞書の単語を表し、非ゼロの値はそのドキュメント内のそれらの単語の重要性を表します。

BM25などのキーワード検索アルゴリズムは、Sparseベクトルを利用してテキストドキュメントの関連性を計算します。これらのアルゴリズムは、キーワードの一致数、出現頻度、その他の要素を評価して関連する検索結果を提供します。

DenseベクトルとSparseベクトルの強みを組み合わせることで、Pineconeは多様な検索シナリオに対応する堅牢で柔軟なベクトルデータベースを提供し、検索結果の精度と再現率を向上させます。

Sparse-Denseベクトルの作成と使用の手順

PineconeでSparse-Denseベクトルを使用する場合の一般的なワークフローは次のとおりです。

  1. 外部の埋め込みモデルを使用してDenseベクトルを作成。これには通常、SBERTなどのモデルを使用して生データ(テキストなど)を数値表現に変換する前処理のステップが含まれます。

  2. 外部モデルを使用してSparseベクトルを作成。これらの表現には通常、TF-IDFなどのキーワードの頻度を測定する方法が組み込まれ、各次元が特定の単語または特徴に対応する高次元の表現が作成されます。

  3. Sparse-Denseベクトルをサポートするインデックス(dotproductメトリックを使用したs1またはp1)を作成。このインデックスにはベクトルが保存され、効率的な類似検索が可能になります。

  4. DenseベクトルとSparseベクトルをインデックスに挿入または更新。これには、ベクトルをインデックスに追加し、クエリで使用できるようにする作業が含まれます。

  5. Sparse-Denseベクトルを使用してインデックスを検索。クエリにはSparseベクトルとDenseベクトルの両方の値が含まれます。

  6. PineconeはSparse-Denseベクトルを返却。クエリの結果は、クエリベクトルとの類似性に基づいてインデックス内のベクトルのランキング付けされたリストとなります。

Sparseベクトルの埋め込みの作成

Sparseベクトルの埋め込みを作成する際には、Pineconeのインデックスはドキュメントではなく、Sparseベクトルを受け入れるため、ユーザーはドキュメントを表すSparseベクトルの生成する必要があります。

Sparseベクトルを使用したドキュメントの表現

キーワードを意識したセマンティックサーチを効果的に実装するためには、各ドキュメントをベクトルとして表現する必要があります。ベクトル化のプロセスでは、通常、ドキュメントからキーワードやその他の特徴を抽出し、それらの重要性を量化し、各次元が特定の特徴に対応する高次元のベクトルにエンコードします。

PineconeでのSparseベクトルサイズのサポート

Pineconeは、非ゼロの値が最大で1000個のSparseベクトル値をサポートしています。この容量により、多数の異なる特徴やキーワードが含まれるドキュメントを効果的に表現する柔軟性が提供されます。

ベクトル内のSparse値とDense値

Pineconeでベクトルを作成する際には、ベクトルはDense値と、オプショナルのSparse値で構成されます。Dense値はコンテンツの意味を表し、Sparse値は特定のキーワード情報を表します。ただし、PineconeではSparse値のみのベクトルはサポートしていません。

Sparse-Denseクエリ

PineconeでSparse-Denseベクトルを使用してクエリを実行するには、Sparse部分とDense部分を含むクエリベクトルを提供する必要があります。Pineconeはこれらのクエリを処理する際に、ベクトル全体の内積を考慮し、ベクトルのスコアはDense部分とクエリのSparse部分の内積の合計で計算されます。

PineconeでのSparse値の表現

Pineconeでは、Sparse値は次の2つの配列の辞書として表されます。

  • indices: ベクトル内の非ゼロ値の位置
  • values: 非ゼロ値自体

これらの値は、ベクトルパラメータ内にアップサートするためのSparse-Denseベクトルに挿入することができます。

Sparse値とDense値を持つベクトルのアップサート

Pineconeは、Sparse値とDense値の両方を含むベクトルをアップサートするための簡単な方法を提供します。典型的なPythonの例では、Pineconeのインデックスのupsertメソッドを使用して、指定したidvaluessparse_valuesを持つベクトルを既存のインデックスに追加することができます。

python
index = pinecone.Index('example-index')

upsert_response = index.upsert(
    vectors=[
    {'id': 'vec1',
        'values': [0.1, 0.2, 0.3],
        'metadata': {'genre': 'drama'},
        'sparse_values': {
        'indices': [10, 45, 16],
        'values': [0.5, 0.5, 0.2]
    }},
    {'id': 'vec2',
        'values': [0.2, 0.3, 0.4],
        'metadata': {'genre': 'action'},
        'sparse_values': {
        'indices': [15, 40, 11],
        'values': [0.4, 0.5, 0.2]
    }}
    ],
    namespace='example-namespace'
)

Sparse-Denseベクトルを使用したインデックスのクエリ

Sparse-Denseベクトルを使用してPineconeのインデックスをクエリすることも同様に簡単です。クエリの一部として、DenseベクトルとSparseベクトルを提供し、Pineconeはクエリベクトルに基づいてインデックス内のクエリベクトルともっとも類似したベクトルを返します。以下の例は、Sparse-Denseベクトルを使用してインデックスをクエリする方法を示しています。

python
query_response = index.query(
    namespace="example-namespace",
    top_k=10,
    vector=[0.1, 0.2, 0.3], # dense vector
    sparse_vector={ # sparse vector
        'indices': [10, 45, 16],
        'values': [0.5, 0.5, 0.2]
    }
)

Sparse-Denseの重み付け

Pineconeのインデックスは、Sparse-Denseベクトルを統一されたエンティティとして扱い、クエリのDense部分とSparse部分の影響力を明示的に変えるメカニズムを提供していません。Pineconeは、ベクトルの座標内の密度やスパーシティについて中立的な立場を取ります。ただし、次の関数のような変換を使用することで、線形の重み付けスキームを適用することができます。

次の例では、alphaパラメータを使用してベクトルの値を変更しています。

python
def hybrid_score_norm(dense, sparse, alpha: float):
"""Hybrid score using a convex combination

    alpha * dense + (1 - alpha) * sparse

    Args:
        dense: Array of floats representing
        sparse: a dict of `indices` and `values`
        alpha: scale between 0 and 1
    """
    if alpha < 0 or alpha > 1:
        raise ValueError("Alpha must be between 0 and 1")
    hs = {
        'indices': sparse['indices'],
        'values':  [v * (1 - alpha) for v in sparse['values']]
    }
    return [v * alpha for v in dense], hs

次の例では、変換関数を使用してベクトルに変換を適用し、この変換されたベクトルを使用してPineconeインデックスのクエリを行います。

python
sparse_vector = {
    'indices': [10, 45, 16],
    'values': [0.5, 0.5, 0.2]
}
dense_vector = [0.1, 0.2, 0.3]

hdense, hsparse = hybrid_score_norm(dense_vector, sparse_vector, alpha=0.75)

query_response = index.query(
    namespace="example-namespace",
    top_k=10,
    vector=hdense,
    sparse_vector=hsparse
)

参考

https://docs.pinecone.io/docs/hybrid-search

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!