構造化データのベクトル化とクエリの究極ガイド
このガイドでは、構造化データをベクトル化する理由とタイミングについて説明し、Milvusを使用した構造化データのベクトル化とクエリを最初から最後まで説明します。
シリーズ全体を読む
- 筏か否か?クラウドネイティブデータベースにおけるデータ一貫性のベストソリューション
- Faiss(フェイスブックAI類似検索)を理解する
- 情報検索メトリクス
- ベクターデータベースにおける高度なクエリー技術
- ベクトル検索を支える人気の機械学習アルゴリズム
- ハイブリッド検索:テキストと画像を組み合わせて検索機能を強化
- ベクターデータベースの高可用性の確保
- ランキングモデル:ランキングモデルとは何か?
- Zillizでレキシカル検索とセマンティック検索を使いこなす
- バイナリ量子化とMilvusによるベクトル検索の効率化
- モデルプロバイダーオープンソースとクローズドソースの比較
- Milvusによる多言語言語の埋め込みとクエリー
- 構造化データのベクトル化とクエリの究極ガイド
- HNSWlibを理解する:高速近似最近傍探索のためのグラフベースライブラリ
- ScaNN(Scalable Nearest Neighbors)とは?
- ScaNNを始める
- 次世代検索:クロスエンコーダとスパース行列因子分解がk-NN検索を再定義する方法
- ボイジャーとは?
- 迷惑とは何か?
このガイドでは、構造化データをベクトル化する理由とそのタイミングについて説明し、Milvusによる構造化データのベクトル化とクエリについて、最初から最後まで説明します。しかし、具体的な説明に入る前に、いくつかの基本的な概念について説明します。
データのベクトル化とは?
データのベクトル化とも呼ばれるデータのベクトル化とは、様々なタイプのデータ(テキスト、画像、構造化データなど)を機械学習モデルを使って数値フォーマットに変換するプロセスのことです。これらのベクトルは、機械が処理・分析できる方法で元のデータを表す数値の配列である。ベクトル化されたデータは、アルゴリズムがデータに対して数学的演算を実行することを可能にするため、洞察を抽出したり、パターンを検出したり、機械学習モデルを適用したりすることができます。
例えば、"The cat sat on the mat "という文章を見てみよう。ベクトル化の基本的なアプローチはBag-of-words(BoW)モデルで、文中のユニークな単語はそれぞれ頻度で表されます。BoWを使うと、文は次のようなベクトルに変換される:\ここで、各数値は対応する単語のカウントを表す(この場合、"the "は2回出現し、他の単語は1回出現する)。しかし、これは単語の存在や頻度を表しているだけで、意味や単語間の関係を表しているわけではない。
現代の機械学習や深層学習モデルでは、単語埋め込み(Word2Vec、GloVe、BERTなど)のような、より高度なテクニックを使ってベクトルを作成する。これらの手法は、文脈に基づいて単語の意味を捉える高密度の高次元ベクトルを生成する。例えば、"cat "という単語は、[0.2, -0.3, 0.4, ...¬]のようなベクトルで表現され、その値は意味や他の単語との関係を表します。頻度ベースの手法とは異なり、埋め込みはテキストのより高度な分析を可能にするので、機械は文脈、類似性、意味をより深いレベルで理解することができます。
なぜデータをベクトル化するのか?
データをベクトル化する理由はいくつかあります:
機械学習の互換性:機械学習の互換性:ほとんどの機械学習アルゴリズムは数値データを扱います。ベクトル化により、様々な種類のデータ(テキスト、画像、構造化データなど)を数値形式に変換することができ、これらのアルゴリズムでの使用に適しています。
効率的な計算**:ベクトルはコンピュータで高速に処理できるため、類似検索や分類のような高速演算が可能になります。距離計算やドット積のようなベクトルに対する数学演算は、計算効率が高い。
意味的な意味を捉える**:埋め込みなどの高度なベクトル化技術は、データ点間の意味的関係を捉えることができる。例えば、単語の埋め込みは、文脈に基づいて単語の意味をエンコードすることができ、テキストのニュアンス分析や比較を可能にします。
次元削減**を可能にする:ベクトル化自体は次元を削減しませんが、(PCAやt-SNEなどの)次元削減技術を適用しやすくする方法でデータを表現することができます。これらのテクニックは、複雑なデータをより管理しやすい形に凝縮し、保存やさらなる分析に役立てることができます。
ベクターデータとは?
ベクトルデータとは、データを数値のリストに変換したもので、しばしばベクトルと呼ばれる。各ベクトルは1つのアイテム、データポイント、またはエンティティを表し、ベクトル内の数値はそのアイテムの異なる特徴や属性を符号化する。ベクトルは、複雑なデータ(テキスト、画像、ユーザープロファイルなど)をアルゴリズムで処理できるようにするため、機械学習やデータサイエンスにおいて重要な役割を果たします。
ベクトルデータの例
単語の埋め込み**:単語は実数の密なベクトルとして表現され、各次元は単語の意味や文脈のある側面を捉える。例えば、Word2VecやBERTのようなモデルによって生成された埋め込みは、類似した単語(「王」と「女王」のような)が高次元空間で近いベクトルを持つように単語を表現します。
画像符号化**:画像は、生のピクセル値(より単純なタスクの場合)、またはCNN(畳み込みニューラルネットワーク)のようなモデルによって抽出されたより複雑な特徴のどちらかによって、ベクトルとして表現することができる。これらのベクトルは、画像分類や類似検索のようなタスクのために、画像の主要な特徴をエンコードする。
ユーザー行動プロファイル**:推薦エンジンのようなシステムでは、ユーザーの行動(嗜好、行動、過去のインタラクションなど)をベクトルとして符号化することができる。ベクトルの各次元は、ユーザーが特定のカテゴリの商品を閲覧した回数や、特定のアクション(購入やクリックなど)の頻度などの特徴を表すことができる。
ベクターデータ処理とは?
ベクトルデータ処理とは、ベクトル形式に変換されたデータを操作、分析、照会することである。ベクトルは、アイテムやデータポイントを一連の数値として表します。このベクトルを処理することで、機械はデータポイント間の比較、グループ化、関係予測を含むタスクを効率的に処理することができます。
一般的なベクトルデータ処理タスクには、以下のようなものがある:
類似検索:類似度検索:与えられたクエリ・ベクトルに最も類似したベクトルを見つける。これは、推薦システムやセマンティック検索のような、クエリに類似したアイテムやドキュメントを迅速に特定する必要があるタスクにおいて不可欠である。
クラスタリング:類似したベクトルをその特徴に基づいてグループ化すること。k-meansクラスタリングのような技法は、データ中のグループやクラスターを自動的に発見するために使用され、顧客セグメンテーション、異常検出、探索的データ分析によく採用される。
分類:分類:特徴やパターンに基づいてベクトルにラベルを割り当てること。例えば、機械学習モデルは、電子メールフィルタリングシステムにおいて、ベクトルを「スパム」または「スパムでない」を表すものとして分類するかもしれない。
次元削減:高次元のベクトルを、最も重要な情報を保持しながら低次元の表現に圧縮すること。PCA(主成分分析)やt-SNE*のような技術は、データの複雑さを軽減するために使用され、可視化、ストレージの必要性の削減、計算の高速化に役立ちます。
ベクトルデータ処理は、データポイント間の関係や類似性を理解するタスクで特に威力を発揮する。推薦システム、自然言語処理(NLP)、コンピュータビジョンなど、ベクトルを効率的に比較することが正確な結果を出すために重要なアプリケーションで広く使用されています。
なぜ構造化データをベクトル化するのか?
ベクトル化は一般的にテキストや画像のような非構造化データに関連付けられますが、構造化データ(数値データ、カテゴリデータ、時系列データなどのラベル付きデータ)にも非常に有効です。ここでは、ベクトル化が構造化データに役立つ理由を説明します:
統一された表現:ベクトル化により、さまざまなタイプの構造化データ(数値、カテゴリ、日付など)を単一の統一フォーマットで表現できます。これにより、特に構造化データと非構造化データを統合する場合、機械学習モデル内で異なるタイプの特徴を処理、分析、組み合わせることが容易になります。
複雑な関係の把握:ベクトル表現は、特に高度なアルゴリズム(エンベッディングやニューラルネットワークなど)によって生成された場合、従来の構造化データ分析手法(線形モデルや決定木など)では見逃してしまうような特徴間の非線形関係**を捉えることができる。これは、より複雑な機械学習タスクに特に有用です。
効率的な類似性検索:構造化データがベクトル化されると、大規模なデータセット間で高速な類似性検索**が可能になります。例えば、ベクトルとして表現された顧客プロファイルは、複数の特徴に基づき、たとえそれらの特徴が複雑な方法で相互作用していたとしても、類似した顧客を見つけるために効率的に比較することができます。
高度なMLモデルとの互換性**:最先端の機械学習モデル(ニューラル・ネットワークや勾配ブースティング・モデルなど)の多くは、ベクトル化された入力に最適です。構造化データをベクトル化することで、分類、回帰、クラスタリングなどのタスクにこれらのモデルのパワーを活用することができます。
構造化データと半構造化データ、非構造化データ**の比較
データを扱っていると、「構造化」、「半構造化」、「非構造化」という言葉をよく耳にすると思います。しかし、これらは何を意味し、なぜ気にする必要があるのでしょうか?
これらのデータタイプの違いを説明しよう:
1.構造化データは、あらかじめ定義されたスキーマに従い、一貫したフォーマットを持っています。行が個々のレコードを表し、列が特定の属性を表す、完全に整理されたスプレッドシートのようなものだと考えてください。構造化データはデータ界の変人であり、常に厳格な構造を守っている。
2.半構造化データは、部分的に定義された構造を持つが、より柔軟性がある。見出しや段落など、ある程度の構造を持つ文書のようなものだが、それらの要素内の内容はさまざまである。電子メール、XML、JSON文書が半構造化データの代表例です。
3.非構造化データは、データファミリーの野生児で、テキスト文書、画像、動画、音声ファイルなど様々な形態がある。非構造化データは、従来の手法では飼い慣らしたり分析したりするのが難しい。
さて、"この生データをどこに保存すればいいのだろう?"と疑問に思うかもしれない。データベースの選択は、データの種類とアプリケーションの要件に依存します。
MySQL、PostgreSQL、Oracleのようなリレーショナル・データベースは、構造化データのデフォルトの選択肢です。これらのデータベースは、SQL(構造化クエリー言語)を使って構造化データを保存、検索、操作するための堅牢で効率的な方法を提供します。
半構造化データを扱う場合は、MongoDB、Couchbase、Cassandraのようなドキュメント指向のデータベースが適している。これらのデータベースは柔軟なスキーマを扱えるように設計されており、階層構造やネストされたデータ構造にも対応できる。
非構造化データを効率的に処理するには、Milvusのような特殊なベクトル・データベースが必要だ。これらのシステムは、高次元ベクトルで大量の非構造化データを扱うことができ、必要なスケーラビリティと高可用性を提供します。
構造化データをベクトル化する理由とタイミングは?
構造化データは正確な検索に使用されるため、なぜベクトル化するのでしょうか?完全一致だけでなく、その意味に基づいてデータベース内のレコードを検索できることを想像してみてください。あるいは、あなたが知らなかったデータの隠れたパターンや関係を見つけることができます。ベクトル化はそのすべてを可能にします。
構造化データをベクトル化すべきケースをいくつか挙げてみよう:
データセットに構造化データと非構造化データの両方がある場合。
データセットに構造化データと非構造化データの両方がある場合。構造化データに非構造化値がある場合。
一方、構造化データをベクトル化するのが良くない場合もあります:
商品の価格表のように、データがすべて量的な値である場合、ベクトル化してもあまり価値が上がりません。従来の構造化データベースはこの種のデータに適しており、通常はこの作業に最適なツールです。
例えば、何人があなたの動画に2秒以上費やしたか、といったロールアップ分析を行いたいとする。この場合、データにはベクトル化の恩恵を受けるような意味的価値はほとんどない。SQLのようなデータベースは、このようなクエリのために設計されているので、通常はSQLを使うのがベストだ。
なぜわざわざ構造化データをベクトル化するのか?
構造化データは通常、正確な検索に使用されるので、なぜわざわざベクトル化するのでしょうか?完全一致だけでなく、その意味に基づいてデータベース内の類似レコードを検索できることを想像してみてください。あるいは、あなたが知らなかったデータの隠れたパターンや関係を発見することもできます。ベクトル化によって、これらすべてが可能になります。
構造化データセットのベクトル化を検討すべきケースはいくつかあります:
データセットに構造化データと非構造化データの両方が含まれている場合。
データセットに構造化データと非構造化データの両方が含まれる場合: 構造化データに非構造化値が含まれる場合。
反面、構造化データをベクトル化することが得策でない場合もあります:
商品の価格表など、定量的な値だけで構成されているデータの場合、ベクトル化してもデータの変換にあまり価値が生まれない可能性があります。従来の構造化データベースは、この種のデータを処理するのに十分な機能を備えており、一般的に分析を行うのに最も適したツールです。
あなたのゴールが、あなたの動画に2秒以上費やした人の割合を決定するような、ロールアップ分析を実行することだとします。その場合、データにはベクトル化の恩恵を受けるような意味的価値はほとんどないかもしれません。SQLのようなデータベースは、このようなクエリを効率的に処理するように設計されているので、このような作業にはSQLを使うのが最善です。
性能比較:ベクトル検索と従来のクエリの比較
構造化データのベクトル化を決定する際には、パフォーマンスへの影響を理解する必要があります。ベクトル類似検索と従来の構造化データクエリを異なるシナリオで比較してみましょう。
シナリオ1:完全一致クエリ 単純な完全一致クエリでは、従来のデータベースがまだ勝っています。例えば、一意のIDで顧客を見つける:
従来のSQL:従来のSQL:非常に高速。
ベクトル検索:通常、多くの項目またはすべての項目をチェックする必要があるため、より遅い。
この場合、従来のデータベースの方が高速で効率的である。
シナリオ2:範囲クエリ 数値データに対する範囲クエリでは、従来のデータベースも優れた性能を発揮する:
従来のSQL:従来の SQL: 高速、特に適切なインデックスを使用した場合
ベクトル検索:通常、多くの項目またはすべての項目をチェックする必要があるため、より遅い。
これらのタイプのクエリでは、やはり従来のデータベースが勝る。
シナリオ3:意味的類似性検索 ベクトル検索が得意とするところである。意味的に類似したアイテムを見つけることは、従来のデータベースでは難しいが、ベクトル検索では簡単である:
従来のSQL:従来のSQL:遅くて複雑。
ベクトル検索:高速、特に適切なインデックス作成技術が必要
ベクトル検索は、データセットが大きくなるにつれて、意味的類似性クエリに対してより高速になる。
シナリオ4:マルチモーダルなクエリ 複数のデータ型(例えば、テキストと画像)を含むクエリでは、ベクトル検索が有利である:
従来のSQL:従来のSQL:非常に難しく、複雑なデータモデリングと遅い操作が必要な場合が多い。
ベクトル検索:単一の検索で異なるデータ型を簡単に組み合わせることができる。
ベクトル検索は、従来のデータベースでは不可能であったマルチモーダルデータへの単一アプローチである。
まとめると、従来のデータベースは完全一致と範囲検索で勝ち、ベクトル検索は意味的類似性とマルチモーダル検索で勝つ。賢く選択しましょう。
構造化データのベクトル化とクエリのためのMilvusの使い方
Milvusは、ベクトル類似検索エンジンやGenAIアプリケーションのためのオープンソースのベクトルデータベースです。Milvusは、ディープニューラルネットワークやその他の様々な機械学習アルゴリズム(ML)モデルによって生成された10億以上の埋め込みベクトルを保存、インデックス化、管理することができます。
Milvusは、OpenAI Embedding API、sentence-transformer、BM25、Splade、BGE-M3、およびVoyageAIを含む様々な一般的な埋め込みモデルと統合しており、お客様のデータに対するベクトル埋め込みを簡単に生成することができます。これらの埋め込みモデルを活用することで、Milvusは構造化データのベクトル化プロセスを簡素化し、ベクトル類似検索を利用した強力なアプリケーションの構築に集中することができます。
概念を理解したところで、Milvusインテグレーションを使用して構造化データをベクトル化し、類似検索を実行する手順を説明しましょう。
この例では、テキストのような非構造化データを含む構造化データセットであるDataFrameを作成します。構造化データ内の非構造化入力データをベクトル化し、データセット全体のベクトル表現のコレクションを作成し、クエリを実行します。
ベクトル生成のためにMilvusインテグレーションを利用する前に、Milvusと必要なパッケージをコンピュータにインストールする必要があります。このガイドに従ってMilvusのインストールを行ってください。
それでは、Milvusを使って構造化データをベクトル化し、クエリを実行する手順を順を追って説明します。
ステップ1: 必要なライブラリのインストール
# PyMilvus ライブラリをインストールします。
pip install pymilvus[model] # PyMilvusライブラリをインストールする。
このコマンドは必要な Python ライブラリをインストールします:pymilvus**(modelパッケージを含む)。pymilvusはMilvusのPythonクライアントです。
ステップ2: 必要なライブラリをインポートする。
# データ操作のためにpandasをインポートする
pandas を pd としてインポートする
# PyMilvus から必要なクラスとモジュールをインポートします。
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection
from pymilvus import model
from pymilvus import connections
from pymilvus import MilvusClient
ステップ 3: Milvus サーバの起動
# Milvus クライアントのインスタンスを作成する。
クライアント = MilvusClient('./milvus.db')
このステップでは、PyMilvusから必要なモジュールをインポートする。
Milvusに接続するためにMilvusClientのインスタンスを作成し、./milvus.dbというURIをMilvusClientの初期化に渡します。
URIをローカルファイル(例: ./milvus.db)に設定する方法は、自動的にMilvus Liteを利用してこのファイルにすべてのデータを格納するため、最も便利な方法です。
重要:ドキュメント数が100万件を超える場合は、DockerやKubernetes上でよりパフォーマンスの高いMilvusサーバを構築することをお勧めします。このセットアップを使用する場合、サーバURI、例えばhttp://localhost:19530をURIとして使用してください。
ステップ4:データを準備する**。
# データ操作のためにpandasをインポートする
pandas を pd としてインポートする
# データを辞書として定義する
data = {
'id':[1, 2, 3],
'title':['Milvusの紹介', 'Milvusの高度な機能', 'Milvusの使用例']、
'content':[
'Milvusはオープンソースの類似検索用ベクトルデータベースです'、
MilvusはIVF_FLAT、IVF_SQ8、HNSWなど様々なインデックスをサポートしています、
Milvusは機械学習フレームワークと簡単に統合できます。
]
}
# 辞書からpandas DataFrameを作成する
df = pd.DataFrame(data)
# DataFrame の最初の数行を表示する
df.head()
**出力
ここでは、pandas DataFrameの形式で構造化データを準備します。このデータには、id、title、content の 3 つのカラムが含まれます。content 列には、ベクトル化したいテキストデータが含まれています。
ステップ 5: データのベクトル化
# DefaultEmbeddingFunction のインスタンスを作成する。
ef = model.DefaultEmbeddingFunction()
# content' カラムのテキストデータをベクトル化(エンコード)する
embeddings = ef.encode_documents(df['content'].tolist())
ステップ6: コレクションスキーマとコレクションの作成
# コレクションスキーマのフィールドを定義する
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=False)、
FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=255)、
FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=500)、
FieldSchema(name="embedding",dtype=DataType.FLOAT_VECTOR,dim=ef.dim)]。
]
# 定義されたフィールドからコレクションスキーマを作成します。
schema = CollectionSchema(fields)
# コレクションの名前を定義する
コレクション名 = "structured_data"
# 与えられた名前とスキーマでコレクションを作成する
コレクション = Collection(name=collection_name, schema=schema)
フィールドとそのデータ型を指定して、コレクションを処理するデータのスキーマを定義します。FieldSchemaオブジェクトはコレクションのカラムを表します。この場合、id**, title, content, embeddingのフィールドがある。
embeddingフィールドは、埋め込み関数の出力次元(ef.dim**)に等しい次元を持つfloatベクトルです。次に、定義されたフィールドを持つ CollectionSchema を作成し、スキーマとコレクション名を持つ Collection オブジェクトをインスタンス化します。
ステップ 7: データをコレクションに挿入します。
# 埋め込みカラムを持つ新しい DataFrame を作成する。
data_with_embeddings = df.copy()
data_with_embeddings['embedding'] = embeddings
# データをMilvusコレクションに挿入する
collection.insert(data=data_with_embeddings.to_dict('records'))
元のDataFrame dfをコピーして新しいDataFrame data_with_embeddingsを作成し、embeddingカラムに計算されたembeddingsを追加します。そして、insertメソッドを用いて、データを辞書のリストとして渡し、Milvusコレクションに挿入します。
ステップ8: インデックスを作成する。
# インデックスのパラメータを定義する
index_params = {
"metric_type":"COSINE", # 余弦類似度メトリックを使用する
"index_type":"HNSW", # HNSWインデックス作成アルゴリズムを利用する
"params":{"M":48, "efConstruction":200} # インデックスパラメータを指定する
}
# 'embedding'フィールドにインデックスを作成する
コレクション.create_index("embedding", index_params)
効率的な類似検索のために、embeddingフィールドにインデックスを作成します。メトリックタイプ(余弦類似度)、インデックスタイプ(HNSW)、近傍数(M)や構築パラメータ(efConstruction)などのインデックスパラメータを指定します。
ステップ9: コレクションをメモリにロードする**。
# コレクションをメモリにロードする
client.load_collection(collection_name=collection_name)
# コレクションのロード状態をチェックする
res = client.get_load_state(collection_name=collection_name)
print(res)
**出力
{'state':<LoadState:ロード状態
検索を実行する前に、client.load_collectionを使用してコレクションをメモリにロードする必要があります。次に、client.get_load_stateを使用してコレクションのロード状態を確認し、クエリの準備が整っていることを確認します。
**ステップ10:類似検索の実行
# クエリーテキストを定義する
query = "milvusとは?"
# クエリテキストをエンコードする
query_embedding = ef.encode_documents([query])
# 検索パラメータを定義する
search_params = {"metric_type":"COSINE", "params":{"nprobe":10}}
# 類似性検索の実行
results = collection.search(query_embedding, anns_field="embedding", param=search_params, limit=1, output_fields=['content'])
# 検索結果を表示する
print(results)
**出力
データを出力する:['["id:1, distance:0.6577072143554688, entity:{'content':\Milvusは類似検索のためのオープンソースのベクトルデータベースです。]コスト:0
最後に、類似検索を実行する。同じ埋め込み関数(ef.encode_documents)を用いて、クエリテキストをエンコードする。メトリクスの種類(余弦類似度)や、検索中に探索する候補の数を制御する nprobe パラメータを含む検索パラメータを定義する。
次に、クエリ埋め込み、検索対象のembeddingフィールド、検索パラメータ、返す結果の最大数(limit=1)、結果に含めるoutput_fields(この場合はcontentフィールドのみ)を渡して、コレクションに対して検索メソッドを呼び出します。
検索結果には、クエリ埋め込みと文書埋め込み間の余弦類似度に基づき、最も類似した文書が含まれます。
これらのステップに従うことで、Milvusを活用して構造化データのベクトル化と類似検索を効率的に実行することができます。
Milvusを使ったRAGでの類似検索のためのベクトル化データの活用 ## **Milvusを使ったRAGでの類似検索のためのベクトル化データの活用
では、Milvus、LangChain、OpenAIの言語モデルを使って、シンプルなRAGシステムを構築するプロセスを見てみましょう。ウェブソースから構造化データを読み込み、ベクトル化し、Milvusに取り込み、類似検索を行い、取得した結果を言語モデルに送り、ユーザの質問に対する最終的な答えを生成します。
必要なライブラリのインストール
まず、必要なPythonライブラリをインストールします。
pip install -U langchain langchain-community langchain-openai pymilvus[model].
データセットのロードと前処理
サンプルデータセット(Seabornの "Tips "データセット)をロードし、Milvusに取り込むための前処理を行う。
pdとしてpandasをインポートする
from langchain.text_splitter import CharacterTextSplitter
from typing import List
from langchain_core.documents import ドキュメント
import seaborn as sns
# Tipsデータセットをロード
tips = sns.load_dataset("tips", cache=False)
# 欠損値のある行を削除
tips = tips.dropna()
tips = tips.head(4) # デモ用に小さなサブセットを取る
# DataFrameをドキュメントのリストに変換する
documents = [Document(page_content=str(tips.iloc[i])) for i in range(len(tips))] # ドキュメント(page_content=str(tips.iloc[i]))
# テキストをチャンクに分割するためのCharacterTextSplitterを初期化する。
text_splitter = CharacterTextSplitter(separator="\n", chunk_size=1000, chunk_overlap=0)
# text_splitter を使ってドキュメントをチャンクに分割する
docs = text_splitter.split_documents(documents)
ベクターストアとLLMのセットアップ
Milvusのベクターストアをセットアップし、OpenAIのエンベッディングと言語モデルを初期化し、ドキュメントをベクターストアに追加します。
from langchain_core.prompts import PromptTemplate
from langchain_community.vectorstores import Milvus
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
インポート os
# OpenAIのAPIキーを設定する
os.environ["OPENAI_API_KEY"] = "あなたのAPIキー"
# OpenAIのエンベッディングを初期化する
embeddings = OpenAIEmbeddings()
# Milvusベクトルストアの初期化
vectorstore = Milvus(
embedding_function=embeddings、
auto_id=True、
drop_old=True、
)
# ベクターストアにドキュメントを追加
vectorstore.add_documents(docs)
クエリの定義と類似検索の実行 ### **クエリの定義と類似検索の実行
次に、ユーザのクエリを定義し、Milvusで類似検索を行い、最も関連性の高い文書を取得します。
# ユーザーのクエリを定義する
query = "平均チップはいくらですか?"
# Milvus で類似度検索を行う
search_results = vectorstore.similarity_search(query)
RAGチェーンを構築する
RAGシステムのプロンプトテンプレートを定義し、OpenAIの言語モデルを初期化し、LangChainの表現言語を使ってRAGチェーンを構築します。
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
# RAGシステム用のプロンプトテンプレートを定義する。
prompt_template = """
Human: あなたはAIアシスタントで、可能な限り事実に基づいた統計的な情報を使って質問への回答を提供します。
<question>タグで囲まれた質問に対して簡潔な回答を提供するために、以下の情報を使用してください。
答えがわからない場合は、わからないと答えましょう。
<context>
{コンテキスト}
</context>
<question>
質問
</question>
回答は具体的で、可能であれば統計や数字を使うこと。
A:"""
# プロンプトテンプレートを初期化する
rag_prompt = PromptTemplate(
template=PROMPT_TEMPLATE, input_variables=["context", "question"].
)
# OpenAIの言語モデルを初期化する
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# ベクターストアをレトリバーに変換する
retriever = vectorstore.as_retriever()
# プロンプトの検索結果をフォーマットする
def format_docs(docs: List[Document]):
return "\nn".join(doc.page_content for doc in docs)
# AI応答生成のためのRAG(Retrieval-Augmented Generation)チェーンを定義する。
rag_chain = (
{"context": retriever | format_docs, "question":RunnablePassthrough()}を実行する。
| rag_prompt
| llm
| StrOutputParser()
)
アンサーを生成する
最後に、ユーザーのクエリでRAGチェーンを呼び出し、生成された回答を取得します。
# ユーザーの質問でRAGチェーンを起動し、生成された答えを取得する
res = rag_chain.invoke(query)
print("Question:", query)
print("Answer:", res)
**出力
質問:平均チップはいくらですか?
答え平均チップを計算するには、チップを合計し、エントリー数で割ります。
チップは1.66、3.31、3.50、1.01です。
チップの合計 = 1.66 + 3.31 + 3.50 + 1.01 = 9.48
エントリー数 = 4
平均チップ = 9.48 / 4 = 2.37
平均チップは2.37ドル
効率的なベクトル類似検索と機械学習モデルのMilvusを活用し、OpenAIのような強力な言語モデルと組み合わせることで、ユーザーのクエリに対して正確で文脈に関連した回答を人間の言語で提供する洗練されたRAGシステムを作成することができます。
Zilliz Cloud Pipelines**によるベクトル化とクエリ処理
Zilliz Cloud は、Milvus ベクターデータベースをベースとしたフルマネージドベクターデータベースです。Zilliz Cloud Pipelinesは、ベクター作成と検索のためのワンストップソリューションです。Zilliz Cloud Pipelines]()は、ベクター作成と検索のためのワンストップソリューションです。様々なデータソースに簡単に接続し、事前に構築されたベクター化モデルやカスタムベクター化モデルを適用し、ベクター化されたデータをZilliz Cloudに保存し、高性能な類似検索と取得を可能にする包括的なツールとAPIのセットを提供します。
Zilliz Cloud Pipelinesを使用してデータをベクトル化し、類似検索のためにZilliz Cloudにエンベッディングを保存する例を見てみましょう。
**Zilliz Cloud Pipelinesをセットアップする。
クラスタID、クラウド地域、APIキー、プロジェクトIDなど、Zilliz Cloudクラスタに関する必要な情報を取得します。詳しくはOn Zilliz Cloud Consoleをご参照ください。
CLOUD_REGION = 'gcp-us-west1'
CLUSTER_ID = 'あなたのCLUSTER_ID'
API_KEY = 'あなたのAPI_KEY'
PROJECT_ID = 'あなたのPROJECT_ID'
インジェスト・パイプラインを作成する。
構造化データを処理してベクトル化し、エンベッディングをMilvusに保存するためのIngestionパイプラインを定義します。
テキストデータにはINDEX_TEXT、追加メタデータにはPRESERVEなどの関数を指定します。
インポートリクエスト
headers = {
"Content-Type":"application/json"、
"Accept":"application/json"、
"Authorization": f "ベアラ{API_KEY}"
}
create_pipeline_url = f "https://controller.api.{CLOUD_REGION}.zillizcloud.com/v1/pipelines"
コレクション名 = 'my_structured_data_collection'
embedding_service = "zilliz/bge-base-ja-v1.5"
データ = {
"name":"my_ingestion_pipeline"、
"description":"構造化データの埋め込みを生成するパイプライン"、
"type":"ingestion"、
"projectId":PROJECT_ID、
"clusterId":CLUSTER_ID、
"collectionName": コレクション名、
"functions":[
{
"name":"index_text"、
"action":"INDEX_TEXT"、
"language":"ENGLISH"、
"embedding": embedding_service
},
{
"name":"preserve_metadata"、
"action":"PRESERVE"、
"inputField":「metadata"、
"outputField":"メタデータ"、
"fieldType":"VarChar"
}
]
}
# Ingestionパイプラインを作成するためにPOSTリクエストを送信する。
response = requests.post(create_pipeline_url, headers=headers, json=data)
# レスポンスからパイプラインIDを取り出す
ingestion_pipe_id = response.json()["data"]["pipelineId"] # レスポンスからパイプラインIDを取り出す
上記の例のコードでは、パイプライン名、説明、プロジェクトID、クラスタID、埋め込みデータをMilvusに保存するコレクション名など、必要な詳細を指定してIngestionパイプラインを定義しています。
また、パイプライン内に2つの関数を定義します:
- index_text:index_text:この関数はテキストデータの埋め込み処理と生成に使用されます。
preserve:この関数は、構造化データに関連付けられた追加のメタデータを保持します。
最後に、Ingestionパイプラインを作成するためにPOSTリクエストを送信し、レスポンスからパイプラインIDを抽出します。
Ingestion Pipelineを実行する。
作成したIngestionパイプラインを使って、構造化データをMilvusに取り込みます。
必要なデータとメタデータをパイプラインに入力します。
run_pipeline_url = f "https://controller.api.{CLOUD_REGION}.zillizcloud.com/v1/pipelines/{ingestion_pipe_id}/run"
data = {
"data":
{
"text_list":[
"これが最初のテキストです、
「これは2番目のテキストです、
「これは3番目のテキストです。
],
"メタデータ":"サンプルのメタデータ"
}
}
# 構造化されたデータでIngestionパイプラインを実行するためにPOSTリクエストを送信します。
response = requests.post(run_pipeline_url, headers=headers, json=data)
パイプラインの run エンドポイントに POST リクエストを送信して、構造化データを入力として Ingestion パイプラインを実行します。この例では、テキストのリスト(text_list)と、その他のテキストフォームに関連するメタデータ(metadata)があります。
Ingestionパイプラインは、構造化データを処理し、指定された埋め込みサービスを使用してテキストの埋め込みを生成し、指定されたMilvusコレクションにメタデータと一緒に埋め込みを格納します。
Zilliz Cloud Pipelinesを使用することで、構造化データを簡単にベクトル化し、類似検索用にZilliz Cloudにエンベッディングを保存することができます。このプラットフォームは、ベクトル埋め込みを使用して構造化データを処理し検索するためのシームレスで効率的な方法を提供します。
より詳細な情報やコード例については、クイックスタート|Zilliz Cloud Developer Hubをご参照ください。
要約
データのベクトル化について、構造化データのベクトル化とクエリを中心に説明してきました。おさらいしましょう:
データのベクトル化は、様々なデータを数値ベクトルに変換して効率的に処理する。機械学習、計算、意味、次元削減のためにデータをベクトル化する。
構造化データ、半構造化データ、非構造化データ、そしてそれぞれのタイプに適したデータベースについて説明した。構造化データをベクトル化することで、特に混合データにおいて、隠れたパターンを明らかにし、類似検索を可能にすることができる。
従来のデータベースは完全一致や範囲検索を得意とするが、ベクトル検索は意味検索においてそれらを凌駕する。構造化データを効率的にベクトル化することは、AIや機械学習アプリケーションにとって非常に重要であり、より深い洞察とより強力な分析を提供します。