メインコンテンツまでスキップ
バージョン: User Guides (Cloud)

バイナリベクトル

バイナリベクトルは、従来の高次元浮動小数点ベクトルを0と1のみを含むバイナリベクトルに変換する特殊なデータ表現形式です。この変換はベクトルのサイズを圧縮するだけでなく、セマンティック情報を保持しながらストレージと計算コストを削減します。非重要機能の精度が必須でない場合、バイナリベクトルは元の浮動小数点ベクトルの大部分の完全性と有用性を効果的に維持できます。

バイナリベクトルは、計算効率とストレージ最適化が重要な状況で特に広範な応用があります。検索エンジンやレコメンドシステムなどの大規模AIシステムでは、大量のデータをリアルタイムで処理することが鍵となります。ベクトルのサイズを小さくすることで、バイナリベクトルは精度を大きく犠牲にすることなくレイテンシと計算コストを低減します。さらに、メモリと処理能力が限られているモバイルデバイスや組み込みシステムのようなリソース制約環境でも、バイナリベクトルは有用です。バイナリベクトルを使用することで、これらの制限された環境でも高性能を維持したまま複雑なAI機能を実装できます。

概要

バイナリベクトルは、画像、テキスト、音声などの複雑なオブジェクトを固定長バイナリ値にエンコードする方法です。Zilliz Cloudクラスターでは、バイナリベクトルは通常ビット配列またはバイト配列として表されます。例えば、8次元のバイナリベクトルは[1, 0, 1, 1, 0, 0, 1, 0]のように表されます。

以下の図は、バイナリベクトルがテキストコンテンツのキーワードの存在をどのように表現するかを示しています。この例では、10次元のバイナリベクトルを使用して2つの異なるテキスト(Text 1Text 2)を表しており、各次元は語彙の単語に対応しています:1はテキスト中に単語が存在することを示し、0は単語が存在しないことを示します。

TuIGwtyEkh9g04bvo0icsWdynBd

バイナリベクトルには以下の特徴があります:

  • 効率的なストレージ: 各次元はストレージに1ビットしか必要としないため、ストレージ容量を大幅に削減できます。

  • 高速計算: XORのようなビット演算を使用してベクトル間の類似性を迅速に計算できます。

  • 固定長: 元のテキストの長さに関係なくベクトルの長さは一定であるため、インデックス作成と検索が容易になります。

  • 単純で直感的: キーワードの存在を直接反映しているため、特定の専門的な検索タスクに適しています。

バイナリベクトルはさまざまな方法で生成できます。テキスト処理では、事前定義された語彙を使用して単語の存在に基づいて対応するビットを設定できます。画像処理では、知覚的ハッシュアルゴリズム(pHashなど)を使用して画像のバイナリ特徴量を生成できます。機械学習アプリケーションでは、モデル出力をバイナリ化してバイナリベクトル表現を得ることができます。

バイナリベクトル化後、データはZilliz Cloudクラスターに保存され、管理およびベクトル検索が可能になります。以下の図は基本的なプロセスを示しています。

TF1uw4AQVhFdmBbrhyVcJO6WnXe

📘注釈

バイナリベクトルは特定のシナリオでは優れていますが、表現能力に限界があり、複雑なセマンティック関係を捉えることが難しいという制限があります。したがって、実際のシナリオでは、効率性と表現性のバランスを取るために他のベクトルタイプと併用されることが多いです。詳しくは、デンスベクトルおよびスパースベクトルを参照してください。

バイナリベクトルの使用

ベクトルフィールドの追加

Zilliz Cloudクラスターでバイナリベクトルを使用するには、まずコレクション作成時にバイナリベクトルを保存するためのベクトルフィールドを定義します。このプロセスには以下の作業が含まれます:

  1. datatypeをサポートされているバイナリベクトルデータ型、つまりBINARY_VECTORに設定します。

  2. dimパラメータを使用してベクトルの次元を指定します。バイナリベクトルは挿入時にバイト配列に変換される必要があるため、dimは8の倍数でなければならないことに注意してください。8つのブール値(0または1)ごとに1バイトにパックされます。例えば、dim=128の場合、挿入には16バイトの配列が必要です。

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="binary_vector", datatype=DataType.BINARY_VECTOR, dim=128)

この例では、バイナリベクトルを保存するためのbinary_vectorという名前のベクトルフィールドが追加されています。このフィールドのデータ型はBINARY_VECTORで、次元は128です。

ベクトルフィールドのインデックスパラメータ設定

検索を高速化するために、バイナリベクトルフィールドに対してインデックスを作成する必要があります。インデックス作成により、大規模ベクトルデータの検索効率を大幅に向上させることができます。

index_params = client.prepare_index_params()

index_params.add_index(
field_name="binary_vector",
index_name="binary_vector_index",
index_type="AUTOINDEX",
metric_type="HAMMING"
)

上記の例では、binary_vectorフィールドに対してbinary_vector_indexという名前のインデックスが作成されており、AUTOINDEXインデックスタイプを使用しています。metric_typeHAMMINGに設定されており、類似性測定にハミング距離が使用されることを示しています。

さらに、Zilliz Cloudはバイナリベクトルに対して他の類似性メトリックもサポートしています。詳しくは、メトリックタイプを参照してください。

コレクションの作成

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

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

データの挿入

コレクションを作成した後、insertメソッドを使用してバイナリベクトルを含むデータを追加します。バイナリベクトルはバイト配列の形式で提供する必要があることに注意してください。各バイトは8つのブール値を表します。

例えば、128次元のバイナリベクトルの場合、16バイトの配列が必要です(128ビット ÷ 8ビット/バイト = 16バイト)。以下はデータ挿入のためのサンプルコードです:

def convert_bool_list_to_bytes(bool_list):
if len(bool_list) % 8 != 0:
raise ValueError("The length of a boolean list must be a multiple of 8")

byte_array = bytearray(len(bool_list) // 8)
for i, bit in enumerate(bool_list):
if bit == 1:
index = i // 8
shift = i % 8
byte_array[index] |= (1 << shift)
return bytes(byte_array)

bool_vectors = [
[1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0] + [0] * 112,
[0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1] + [0] * 112,
]

data = [{"binary_vector": convert_bool_list_to_bytes(bool_vector)} for bool_vector in bool_vectors]

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

類似性検索はZilliz Cloudクラスターのコア機能の1つであり、ベクトル間の距離に基づいてクエリベクトルと最も類似するデータをすばやく見つけることができます。バイナリベクトルを使用した類似性検索を実行するには、クエリベクトルと検索パラメータを準備し、searchメソッドを呼び出します。

検索操作中、バイナリベクトルもバイト配列の形式で提供する必要があります。クエリベクトルの次元がdimの定義時に指定した値と一致し、8つのブール値ごとに1バイトに変換されていることを確認してください。

search_params = {
"params": {"nprobe": 10}
}

query_bool_list = [1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0] + [0] * 112
query_vector = convert_bool_list_to_bytes(query_bool_list)

res = client.search(
collection_name="my_collection",
data=[query_vector],
anns_field="binary_vector",
search_params=search_params,
limit=5,
output_fields=["pk"]
)

print(res)

# Output
# data: ["[{'id': '453718927992172268', 'distance': 10.0, 'entity': {'pk': '453718927992172268'}}]"]

類似性検索パラメータの詳細については、基本ANN検索を参照してください。