1. はじめに
最終更新日: 2024 年 4 月 8 日
テキスト エンベディング
テキスト エンベディングとは、テキストデータを数値表現に変換するプロセスを指します。これらの数値表現(多くの場合ベクトル)は、テキスト内の単語の意味論的意味と関係性を捉えます。次のように考えてみましょう。
テキストは、ニュアンスや曖昧さが多く含まれる複雑な言語のようなものです。
テキスト エンベディングは、その言語をコンピュータが理解して操作できる、よりシンプルな数学的形式に変換します。
テキスト エンベディングのメリット
- 効率的な処理が可能: 数値表現は、生のテキストよりもコンピュータでの処理がはるかに高速です。これは、検索エンジン、レコメンデーション システム、機械翻訳などのタスクに不可欠です。
- 意味論的意味を捉える: エンベディングは、単語の文字通りの意味を超えて、意味論的意味を捉えます。単語間のコンテキストと関係を把握し、よりニュアンスのある分析を可能にします。
- 機械学習のパフォーマンスを向上させる: テキスト エンベディングは機械学習モデルの特徴として使用できるため、感情分析、テキスト分類、トピック モデリングなどのタスクのパフォーマンスが向上します。
テキスト エンベディングのユースケース
テキスト エンベディングは、テキストを数値表現に変換することで、自然言語処理(NLP)のさまざまなアプリケーションを実現します。主なユースケースは次のとおりです。
1. 検索エンジンと情報検索:
テキスト エンベディングを使用すると、検索エンジンはクエリの背後にあるセマンティックな意味を理解し、正確なキーワードが存在しない場合でも、関連するドキュメントと照合できます。
検索クエリのエンベディングとドキュメントのエンベディングを比較することで、検索エンジンは類似したトピックやコンセプトを扱うドキュメントを特定できます。
2. レコメンデーション システム:
レコメンデーション システムは、テキスト エンベディングを使用して、レビュー、評価、閲覧履歴で表されるユーザーの行動と好みを分析します。
システムは、ユーザーが操作した商品、記事、その他のコンテンツのエンベディングを比較して、類似アイテムを推奨できます。
3. 盗用の検出:
2 つのテキストのエンベディングを比較すると、セマンティック構造の大きな類似性を見つけて、潜在的な盗用を特定できます。
これらはほんの一例であり、テキスト エンベディング技術の進化に伴い、可能性は広がり続けています。エンベディングによってコンピュータの言語理解能力が向上するにつれて、将来的にはさらに革新的なアプリケーションが登場することが予想されます。
textembedding-gecko@003
textembedding-gecko@003 は、Google Cloud Platform(GCP)が Vertex AI とその AI ツールとサービスのスイートを通じて提供する、事前トレーニング済みのテキスト エンベディング モデルの特定のバージョンです。
作成するアプリの概要
この Codelab では、Python スクリプトを作成します。このスクリプトは次のようになります。
- Vertex API を使用して textembedding-gecko@003 を呼び出し、テキストをテキスト エンベディング(ベクトル)に変換します。
- テキストとそのベクトルで構成されるシミュレートされたデータベースを作成する
- ベクトルを比較してシミュレートされたベクトル データベースにクエリを実行し、最も可能性の高いレスポンスを取得します。
学習内容
- GCP でテキスト エンベディングを使用する方法
- textembedding-gecko@003 を呼び出す方法
- Workbench で実行する方法
- Vertex AI - Workbench を使用してスクリプトを実行する方法
必要なもの
- 最新バージョンの Chrome
- Python に関する知識
- Google Cloud プロジェクト
- Vertex AI - Workbench へのアクセス
2. 設定方法
Vertex AI Workbench インスタンスを作成する
- Google Cloud コンソールの [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
- プロジェクト セレクタに移動
- Google Cloud プロジェクトの課金が有効になっていることを確認します。
- Notebooks API を有効にします。
Vertex AI Workbench インスタンスは、Google Cloud コンソール、gcloud CLI、または Terraform を使用して作成できます。このチュートリアルでは、Google Cloud コンソールを使用して作成します。その他の方法について詳しくは、こちらをご覧ください。
- Google Cloud コンソールで、Vertex AI メニューの [ノートブック] セクションからアクセスできる [インスタンス] ページに移動し、[ワークベンチ] をクリックします。

- [インスタンス] に移動します。
- [新規作成] をクリックします。

- [インスタンスを作成] ダイアログの [詳細] セクションで、新しいインスタンスについて次の情報を入力します。
名前: 新しいインスタンスの名前を入力します。名前は先頭を英字にして、その後に 62 文字以下の英小文字、数字、ハイフン(-)で構成します。末尾をハイフンにすることはできません。
リージョンとゾーン: 新しいインスタンスのリージョンとゾーンを選択します。最適なネットワーク パフォーマンスを得るには、地理的に最も近いリージョンを選択してください。
GPU をインストールする必要がない
[ネットワーキング] セクションで、次の情報を入力します。
ネットワーキング: 現在のプロジェクトのネットワーク、またはホスト プロジェクトから共有 VPC ネットワーク(構成されている場合)を使用するように、ネットワーク オプションを調整します。ホスト プロジェクトで共有 VPC を使用している場合は、サービス プロジェクトの Notebooks サービス エージェントに Compute ネットワーク ユーザーのロール(roles/compute.networkUser)を付与する必要があります。
[ネットワーク] フィールド: 目的のネットワークを選択します。ネットワークで限定公開の Google アクセスが有効になっているか、インターネットにアクセスできる場合は、VPC ネットワークを選択できます。
[サブネットワーク] フィールド: 目的のサブネットワークを選択します。デフォルトのものを選択できます。
インスタンスのプロパティはデフォルトの e2-standard-4 のままで構いません。

- [作成] をクリックします。
Vertex AI Workbench がインスタンスを作成し、自動的に起動します。インスタンスを使用する準備が整うと、Vertex AI Workbench で [JupyterLab を開く] リンクが有効になります。クリックします。
Python 3 ノートブックを作成する
- JupyterLab のランチャーの [Notebook] セクションで、Python3 と表示された Python ロゴのアイコンをクリックします。

- Jupyter ノートブックが作成され、名前は Untitled、拡張子は ipynb になります。

- 左側のファイル ブラウザ セクションを使用して名前を変更することも、そのままにすることもできます。
これで、ノートブックにコードを配置できるようになりました。
3. 必要なライブラリをインポートする
インスタンスが作成され、JupyterLab が開いたら、この Codelab に必要なライブラリをすべてインストールする必要があります。
必要なもの:
- numpy
- pandas
- TextEmbeddingInput、TextEmbeddingModel(vertexai.language_models)
次のコードをコピーしてセルに貼り付けます。
from vertexai.language_models import TextEmbeddingInput, TextEmbeddingModel
import numpy as np
import pandas as pd
これは次のようになります。

4. シミュレートされたベクトル データベースを作成する
コードをテストするために、gecko@003 テキスト エンベディング モデルを使用して変換されたテキストとそれぞれのベクトルで構成されるデータベースを作成します。
ユーザーがテキストを検索し、ベクトルに変換して、データベースで検索し、最も近似した結果を返すことが目的です。
ベクトル データベースには 3 つのレコードが保持されます。作成方法は次のとおりです。
次のコードをコピーして、新しいセルに貼り付けます。
DOCUMENT1 = {
"title": "Operating the Climate Control System",
"content": "Your Googlecar has a climate control system that allows you to adjust the temperature and airflow in the car. To operate the climate control system, use the buttons and knobs located on the center console. Temperature: The temperature knob controls the temperature inside the car. Turn the knob clockwise to increase the temperature or counterclockwise to decrease the temperature. Airflow: The airflow knob controls the amount of airflow inside the car. Turn the knob clockwise to increase the airflow or counterclockwise to decrease the airflow. Fan speed: The fan speed knob controls the speed of the fan. Turn the knob clockwise to increase the fan speed or counterclockwise to decrease the fan speed. Mode: The mode button allows you to select the desired mode. The available modes are: Auto: The car will automatically adjust the temperature and airflow to maintain a comfortable level. Cool: The car will blow cool air into the car. Heat: The car will blow warm air into the car. Defrost: The car will blow warm air onto the windshield to defrost it."}
DOCUMENT2 = {
"title": "Touchscreen",
"content": "Your Googlecar has a large touchscreen display that provides access to a variety of features, including navigation, entertainment, and climate control. To use the touchscreen display, simply touch the desired icon. For example, you can touch the \"Navigation\" icon to get directions to your destination or touch the \"Music\" icon to play your favorite songs."}
DOCUMENT3 = {
"title": "Shifting Gears",
"content": "Your Googlecar has an automatic transmission. To shift gears, simply move the shift lever to the desired position. Park: This position is used when you are parked. The wheels are locked and the car cannot move. Reverse: This position is used to back up. Neutral: This position is used when you are stopped at a light or in traffic. The car is not in gear and will not move unless you press the gas pedal. Drive: This position is used to drive forward. Low: This position is used for driving in snow or other slippery conditions."}
documents = [DOCUMENT1, DOCUMENT2, DOCUMENT3]
df_initial_db = pd.DataFrame(documents)
df_initial_db.columns = ['Title', 'Text']
df_initial_db
次のようになります。

コードを分析する
変数 DOCUMENT1、DOCUMENT2、DOCUMENT3 には、タイトルとコンテンツを含むドキュメントをエミュレートするディクショナリを保存します。これらの「ドキュメント」は、Google 製の車のシミュレートされたマニュアルを参照しています。
次の行では、これらの 3 つのドキュメント(辞書)からリストを作成します。
documents = [DOCUMENT1, DOCUMENT2, DOCUMENT3]
最後に、pandas を利用して、そのリストから df_initial_db という DataFrame を作成します。
df_initial_db = pd.DataFrame(documents)
df_initial_db.columns = ['Title', 'Text']
df_initial_db
5. テキスト エンベディングを作成する
次に、ドキュメントのシミュレートされたデータベースの各レコードに対して、gecko@003 モデルを使用してテキスト エンベディングを取得します。
次のコードをコピーして、新しいセルに貼り付けます。
def embed_fn(df_input):
list_embedded_values = []
for index, row in df_input.iterrows():
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])
list_embedded_values.append(embeddings[0].values)
df_input['Embedded text'] = list_embedded_values
return df_input
df_embedded_values_db = embed_fn(df_initial_db)
df_embedded_values_db
次のようになります。

コードを分析する
embed_fn という関数を定義しました。この関数は、エンベディングを実行するテキストを含む pandas データフレームを入力として受け取ります。この関数は、ベクトルとしてエンコードされたテキストを返します。
def embed_fn(df_input):
list_embedded_values = []
for index, row in df_input.iterrows():
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])
list_embedded_values.append(embeddings[0].values)
df_input['Embedded text'] = list_embedded_values
return df_input
list_embedded_values というリストに、各行のエンコードされたテキストを保存して追加します。
pandas の iterrows メソッドを使用すると、データフレームのすべての行を反復処理し、列 Text(シミュレートされたデータベースの手動情報を含む)から値を取得できます。
gecko@003 モデルを使用して通常のテキストを送信し、そのベクトルを返すには、TextEmbeddingModel.from_pretrained 関数を呼び出して使用するモデルを設定する変数 model を初期化します。
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(row['Text'])])
次に、変数 embeddings で、model.get_embeddings 関数を介して送信するテキストのベクトルを取得します。
関数の最後に、データフレームに「Embedded text」という新しい列を作成します。この列には、gecko@003 モデルに基づいて作成されたベクトルのリストが含まれます。
df_input['Embedded text'] = list_embedded_values
return df_input
最後に、変数 df_embedded_values_db に、シミュレートされたデータベースの元のデータと、各行のベクトルのリストを含む新しい列を含む DataFrame をキャプチャします。
df_embedded_values_db = embed_fn(df_initial_db)
df_embedded_values_db
6. ベクトル データベースに質問する
データベースにテキストとそのベクトルが含まれているので、質問をしてデータベースにクエリを実行し、回答を見つけることができます。
そのため、次のコードをコピーして新しいセルに貼り付けます。
question='How do you shift gears in the Google car?'
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings = model.get_embeddings([(question)])
text_to_search=embeddings[0].values
len(text_to_search)
結果は次のようになります。

コードを分析する
前のステップの関数と同様に、まずデータベースに問い合わせる内容で質問変数を初期化します。
question='How do you shift gears in the Google car?'
次に、モデル変数で、TextEmbeddingModel.from_pretrained 関数を使用して使用するモデル(この場合は gecko@003 モデル)を設定します。
model = TextEmbeddingModel.from_pretrained("textembedding-gecko@003")
embeddings 変数で、model.get_embeddings 関数を呼び出し、ベクトルに変換するテキストを渡します。この場合、質問を渡します。
embeddings = model.get_embeddings([(question)])
最後に、text_to_search 変数には、質問から変換されたベクトルのリストが格納されます。
参照としてベクトルの長さを出力します。
text_to_search=embeddings[0].values
len(text_to_search)
7. ベクトルの比較
これで、シミュレートされたデータベースにベクトルのリストが作成され、質問がベクトルに変換されました。つまり、質問のベクトルをデータベース内のすべてのベクトルと比較して、質問に最も正確に回答できるベクトルを見つけることができます。
これを行うには、質問のベクトルとデータベースの各ベクトルの間の距離を測定します。ベクトル間の距離を測定する手法は複数ありますが、この Codelab ではユークリッド距離または L2 ノルムを使用します。

Python では、numpy 関数を利用してこれを実現できます。
次のコードをコピーして、新しいセルに貼り付けます。
list_embedded_text_from_db = df_embedded_values_db['Embedded text']
shortest_distance=1
for position, embedded_value in enumerate(list_embedded_text_from_db):
distance=np.linalg.norm((np.array(embedded_value) - np.array(text_to_search)), ord = 2)
print(distance)
if distance<shortest_distance:
shortest_distance=distance
shortest_position=position
print(f'The shortest distance is {shortest_distance} and the position of that value is {shortest_position}')
結果は次のようになります。

コードを分析する
まず、エンベディングされたテキストまたはデータベースのベクトルを保持する列をリストに変換し、list_embedded_text_from_db に保存します。
また、実際の最短距離が見つかるまで更新を続けるために、shortest_distance 変数を 1 に初期化しました。
list_embedded_text_from_db = df_embedded_values_db['Embedded text']
shortest_distance=1
次に、for ループを使用して、質問のベクトルとデータベースの各ベクトル間の距離を反復処理して取得します。
numpy linalg.norm 関数を使用して、距離を計算します。
計算された距離が shortest_distance 変数の距離よりも小さい場合、計算された距離がこの変数に設定されます。
次に、最短距離と、その距離が見つかったリスト内の位置をキャプチャします。shortest_distance 変数と shortest_position 変数に格納します。
for position, embedded_value in enumerate(list_embedded_text_from_db):
distance=np.linalg.norm((np.array(embedded_value) - np.array(text_to_search)), ord = 2)
print(distance)
if distance<shortest_distance:
shortest_distance=distance
shortest_position=position
8. 結果
質問とデータベース間の距離が最も短いベクトルがリストのどの位置にあるかがわかれば、結果を出力できます。
次のコードをコピーして、新しいセルに貼り付けます。
print("Your question was:\n "+question+ " \nAnd our answer is:\n "+
df_embedded_values_db.at[shortest_position, 'Title']+": "+
df_embedded_values_db.at[shortest_position, 'Text'])
実行すると、次のような結果が得られます。

9. 完了
これで、実際のユースケースで textembedding-gecko@003 モデルを使用して最初のアプリケーションを構築できました。
テキスト エンベディングの基礎と、GCP Workbench で gecko003 モデルを使用する方法について学習しました。
これで、知識をより多くのユースケースに適用し続けるために必要な主な手順を理解できました。
次のステップ
以下の Codelab をご覧ください。