1
0

ベクトルDBサービスPineconeを試す

Last updated at Posted at 2024-02-06

目次

  • ベクトル埋め込みとは
  • 使い方
  • 感想
  • 参考

ベクトル埋め込みとは

文章や画像のデータを数ベクトル化すること。ベクトル同士を用いて類似性を図れるようになるため、セマンティック検索やレコメンドに応用されています。ベクトルなので専用のDBが必要ですが、Pineconeはそれが可能なサービスの一種です。ここではその使い方を紹介します。

使い方

登録

Pineconeからサインアップしてください。メールアドレスだけで簡単に使えるようになります。コンソール画面からAPIキーを確認できたらOKです。
image.png

  • Starter planでもAPIキーを複数保有できますが、インデックスは1つしか作成できません

インデックスを作成

今回はローカルから操作したいので、まずはpinecone-clientをインストールします。

pip install pinecone-client

完了したら上で確認したAPIキーを使ってPineconeを初期化します。

from pinecone import Pinecone, PodSpec
pc = Pinecone(api_key='<APIキー>')
  • PodSpec:インデックスを設定する際に必要

ここまでできたら次でインデックスを作成します。

pc.create_index(
    name="command-test-cosine", 
    dimension=3, 
    metric="cosine",
    spec=PodSpec(
        environment='gcp-starter', 
        pod_type='starter'
    )
)
  • name:インデックスの名前
  • dimension:格納するデータ(ベクトル)の次元のこと。ここでは3にしていますがもっと巨大にもできます
  • metric:ベクトルDBではクエリ(ベクトルをリクエストする)との類似度が高いデータを返します。Pineconeでは3種類の設定ができます
    • euclidean:リクエストしたベクトルとのユークリッド距離を計算し、近いものから返します
    • dotproduct:リクエストしたベクトルとの内積を計算し、近いものから返します
    • cosine:リクエストしたベクトルとのコサイン類似度を計算し、近いものから返します
  • spec:serverlessかpodを選択できます。今回はpodで作りますが、Starter planの場合は上で書いた環境しか使えないようです

データの挿入・取得

DBに接続して使えるようにします。

index = pc.Index(name="command-test-cosine")

まだDBには何も入っていない状態なので、データを挿入しましょう。数値はfloatで入力してください。

index.upsert([
    ("X", [1.0, 0.0, 0.0]),
    ("Y", [0.0, 1.0, 0.0]),
    ("Z", [0.0, 0.0, 1.0]),
    ("A", [1.0, 1.0, 1.0])
])

image.png

これで4つのベクトルが格納されました。以下コードでも確認できます。

index.describe_index_stats()
{'dimension': 3,
 'index_fullness': 4e-05,
 'namespaces': {'': {'vector_count': 4}},
 'total_vector_count': 4}

それではベクトルを取得してみます。まずは原点をリクエストしてみましょう。

index.query(
    vector=[0.0, 0.0, 0.0],
    top_k=4,
    include_values=True
)
  • vector:基準となるベクトル
  • top_k:類似度の高いベクトルをいくつ取得するか設定できる
  • include_values:レスポンスにベクトルの中身を含めるか設定できる
{'matches': [{'id': 'A', 'score': 0.0, 'values': [1.0, 1.0, 1.0]},
             {'id': 'Y', 'score': 0.0, 'values': [0.0, 1.0, 0.0]},
             {'id': 'Z', 'score': 0.0, 'values': [0.0, 0.0, 1.0]},
             {'id': 'X', 'score': 0.0, 'values': [1.0, 0.0, 0.0]}],
 'namespace': '',
 'usage': {'read_units': 6}}

コサイン類似度は全て0になりました。そもそも意味のないリクエストなので、0で返すようになってたりするんでしょうか。
次は(1, 0, 0)をリクエストしてみます。

index.query(
    vector=[1.0, 0.0, 0.0],
    top_k=4,
    include_values=True
)
{'matches': [{'id': 'X', 'score': 1.0, 'values': [1.0, 0.0, 0.0]},
             {'id': 'A', 'score': 0.577350259, 'values': [1.0, 1.0, 1.0]},
             {'id': 'Z', 'score': 0.0, 'values': [0.0, 0.0, 1.0]},
             {'id': 'Y', 'score': 0.0, 'values': [0.0, 1.0, 0.0]}],
 'namespace': '',
 'usage': {'read_units': 6}}

類似するベクトルが降順にレスポンスされています。
(-1, 0, 0)もリクエストしてみます。

index.query(
    vector=[-1.0, 0.0, 0.0],
    top_k=4,
    include_values=True
)
{'matches': [{'id': 'Y', 'score': 0.0, 'values': [0.0, 1.0, 0.0]},
             {'id': 'Z', 'score': 0.0, 'values': [0.0, 0.0, 1.0]},
             {'id': 'A', 'score': -0.577350259, 'values': [1.0, 1.0, 1.0]},
             {'id': 'X', 'score': -1.0, 'values': [1.0, 0.0, 0.0]}],
 'namespace': '',
 'usage': {'read_units': 6}}

コサイン類似度の下で類似性の高いベクトルが返ってくることがわかりました。

インデックスの削除

使い終わったらインデックスを削除することができます。

pc.delete_index("command-test-cosine")

感想

ベクトルDBを簡単に体験できました。次はセマンティック検索を実装してみようと思います。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0