2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BrainPadAdvent Calendar 2023

Day 23

BigQuery ML テキストエンべディングを使ったセマンティック検索

Posted at

BigQueryMLを使うことで、BigQuery上のテーブルデータを元にエンベディングを生成し、生成したエンベディングを用いて類似度の計算などが行えます。
BigQuery上のテーブルの特定のカラムに対して、セマンティック検索を試します。

検索元テーブルを用意

pixabayというフリー音源サイトを元に、track名、サイトURL、タグ情報を持つテーブルを作成しました。

タグ情報を元にセマンティック検索できるようにします。

music_list_table.png

BigQueryからVertexAIのモデルを使用するための準備

クラウドリソースへの接続を作成

データセットと同じロケーションに接続を作成します。
コマンドラインで接続を作成するには以下を実行。

bq mk --connection --location=REGION --project_id=PROJECT_ID \
    --connection_type=CLOUD_RESOURCE CONNECTION_ID

次の値を自身の環境に合わせて置き換えます。

  • REGION: データセットと同じリージョン。(asia-northeast1 など)
  • PROJECT_ID: Google CloudのプロジェクトID
  • CONNECTION_ID: 接続のID。 bqml_test_connection などと適当に命名してください。

作成されたサービスアカウントは以下コマンドで確認できます。

bq show --connection PROJECT_ID.REGION.CONNECTION_ID

サービスアカウントにアクセス権を付与する

先ほど作成した接続の使用権限をサービスアカウントに付与します。

gcloud projects add-iam-policy-binding 'PROJECT_NUMBER' --member='serviceAccount:MEMBER' --role='roles/aiplatform.user' --condition=None

次の値を自身の環境に合わせて置き換えます。

  • PROJECT_NUMBER: Google Cloudのプロジェクト番号
  • MEMBER: 先ほど作成したサービスアカウントのID

モデルをBigQuery上に作成

textembedding-gecko モデルをリモートモデルとして登録します。

model_create.png

CREATE OR REPLACE MODEL `DATASET_ID.MODEL_ID`
REMOTE WITH CONNECTION `PROJECT_ID.REASION.CONNECTION_ID`
OPTIONS (REMOTE_SERVICE_TYPE = 'CLOUD_AI_TEXT_EMBEDDING_MODEL_V1');

次の値を自身の環境に合わせて置き換えます。

  • DATASET_ID: 今回使用するデータセットのID
  • MODEL_ID: 作成するモデルのID。 embedding_model などと適当に命名してください。
  • PROJECT_ID: Google CloudのプロジェクトID
  • REGION: データセットと同じリージョン
  • CONNECTION_ID: 先ほど作成した接続のID

テーブルにEmbedding列を追加

登録したモデルを ML.GENERATE_TEXT_EMBEDDING という BigQuery ML 関数を介して呼び出すことでエンべディングを生成します。
create_embedding_table.png

CREATE OR REPLACE TABLE `DATASET_ID.music_list_embedding` AS (
  -- music_listテーブルのtag列からEmbedding列を作成
  WITH tag_embedding AS (
    SELECT *
    FROM ML.GENERATE_TEXT_EMBEDDING(
      MODEL `DATASET_ID.embedding_model`,
      (
      SELECT
        track_id,
        tag as content
      FROM
        `DATASET_ID.music_list` 
      ),
      STRUCT(TRUE AS flatten_json_output)
    )
  )

  -- music_listテーブルにtext_embedding列を追加
  SELECT
    music_list.*,
    tag_embedding.text_embedding
  FROM `DATASET_ID.music_list` as music_list
  JOIN tag_embedding
  ON music_list.track_id = tag_embedding.track_id
);

ML.GENERATE_TEXT_EMBEDDINGの第二引数で、変換する対象のテキストを渡します。
今回はtag列のテキストを変換します。
このとき、Embeddingする対象のカラム名をcontentとして渡す必要があります。

FLOAT型 REPEATEDモードのtext_embedding列が追加されました。

music_list_embedding.png

セマンティック検索してみる

ML.DISTANCE という BigQuery ML 関数を使ってベクトル間の距離を計算します。
検索元テーブルの各行との距離が最も近い(数値が低い)曲を今回は検索結果として解釈します。

-- 質問文をベクトル化
WITH search_word_embedding AS (
  SELECT *
  FROM ML.GENERATE_TEXT_EMBEDDING(
    MODEL `DATASET_ID.embedding_model`,
    (SELECT "都会の夜道で聞きたいlofiな曲" AS content),
    STRUCT(TRUE AS flatten_json_output)
  )
)

-- 質問文と music_list のベクトル空間上の距離を計算し、近い順に出力する
SELECT
  m_list.track_id AS track_id,
  m_list.track_name AS track_name,
  m_list.url AS track_url,
  m_list.tag AS track_tag,
  s_word.content AS search_word,
  ML.DISTANCE(m_list.text_embedding, s_word.text_embedding, 'COSINE') AS distance
FROM
  `DATASET_ID.music_list_embedding` AS m_list,
  search_word_embedding AS s_word
ORDER BY distance ASC;

「都会の夜道で聞きたいlofiな曲」と検索した場合が以下。
「lofi」や「都市」などの文字に反応してちゃんとlofiな曲がレコメンドされた。
検索でマッチした曲:https://pixabay.com/ja/music/good-night-160166/
search_lofi.png

もう少し難易度を上げて、直接的にマッチするタグがない状態での検索も試します。
「サッカーに合う曲」と検索した場合が以下。
search_soccer.png
今回の検索語の場合、直接的にマッチするタグ情報を持つ曲はありませんが、
「スポーツ」や「パワー」、「過激」などのサッカーと類似してそうなタグを持つ曲が最近傍と算出されました。
検索でマッチした曲:https://pixabay.com/ja/music/for-future-bass-159125/

参考URL

2
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?