Content

こんにちは!みっちーです!


これまで構築してきたデータサイエンスエージェントは、BigQueryのデータを自然言語でSQLに変換して分析するエージェントです。db_agentがSQLを生成し、ds_agentがPythonで分析・可視化する流れで、BigQueryのテーブルに格納された数値データを扱うのは得意です。


ただ、実際の業務では「AlloyDB for PostgreSQLに蓄積された顧客レビューのテキストを分析したい」というケースもあります。例えば、AlloyDBに数万件のレビューテキストがあって、「ポジティブ・ネガティブ・ニュートラル」に分類したいというタスクが来たとします。


当初はデータサイエンスエージェントのds_agentにPythonでSentiment Analysis APIを呼ぶ処理を書こうとしていたのですが、「AlloyDBからデータを引っ張り出して外部サービスに投げるのは手間だし、データ量が多いときのレイテンシも気になる...」と悩んでいました。


そんなタイミングでAlloyDBに感情分析(ai.analyze_sentiment)・テキスト要約(ai.summarize)が追加された(プレビュー)という情報を見かけて、「SQLだけで完結するなら試してみよう」と早速使ってみました!今回はKaggleで公開されているディズニーランドのレビューデータセット(42,656件)を使って検証しています。

試した環境

  • AlloyDB for PostgreSQL(us-east1、PostgreSQL 16クラスタ)
  • テーブルdisneyland_reviewsKaggle公開データセット、42,656件、カリフォルニア・パリ・香港の3パーク分のレビュー)
  • 接続:VMインスタンスからpsqlで接続

やってみた

①:AI関数を有効化する

まずAI関数の拡張機能を有効化します。データベースに接続して以下を実行します:

CREATE EXTENSION IF NOT EXISTS google_ml_integration;

プレビュー段階のAI関数を使うには、セッションごとに以下のフラグも設定する必要があります:

SET google_ml_integration.enable_preview_ai_functions = 'on';

次に、AI関数が使用するAgent Platform(旧Vertex AI)におけるAIモデルへのアクセス権限を設定します。AlloyDBのサービスアカウントにroles/aiplatform.user(Agent Platform User、旧Vertex AI User)のロールをIAMで付与する必要があります。データサイエンスエージェントのデプロイ時にもAgent PlatformへのIAMロール設定が必要でしたが、AlloyDBでも同様のパターンです。ここを忘れると後でエラーになるので要注意です。


設定完了後にAI関数が使えるか確認:

SELECT ai.analyze_sentiment('このレストランの料理は最高でした!また来たいです。');


動きました!非常にシンプルで使いやすいです!

②:4万件のディズニーランドレビューを感情分析する

本題の大量レビュー分析です。まずサブクエリを使用して、小さいサンプルで試してみます。

SELECT review_id, branch, review_text, ai.analyze_sentiment(review_text) AS sentiment
FROM (
SELECT review_id, branch, review_text
FROM disneyland_reviews
WHERE branch = 'Disneyland_California'
LIMIT 20
) sub;


結果が返ってきました!20件で5分程度かかりますが、これはAI関数が1件ごとにAgent PlatformのAPIを呼ぶためです。感情分類の精度は体感的に申し分ないレベルで、「明らかにポジティブなのにnegative判定」みたいなケースはほぼありませんでした。

続いて3パーク別の集計です。こちらもサブクエリで先にデータを絞り、集計はその外側で行います:

SELECT
branch,
COUNT(*) AS total_reviews,
COUNT(*) FILTER (WHERE sentiment = 'positive') AS positive_count,
COUNT(*) FILTER (WHERE sentiment = 'negative') AS negative_count,
COUNT(*) FILTER (WHERE sentiment = 'neutral') AS neutral_count
FROM (
SELECT branch, ai.analyze_sentiment(review_text) AS sentiment
FROM (
SELECT branch, review_text
FROM disneyland_reviews
LIMIT 60
) sub
) analyzed
GROUP BY branch
ORDER BY negative_count DESC;


パーク別のネガティブレビュー数が出てきました。データサイエンスエージェントのdb_agentが得意とするSQL生成と、このAlloyDB AI関数を組み合わせれば、AlloyDBのテキストデータを「SQLで」分析できる環境が整います。

③:ai.summarizeとai.agg_summarizeで要約する

次に要約機能を試します。ai.summarizeは1行ずつ要約、ai.agg_summarizeは複数行をまとめて1つの要約を生成する集約関数です。

まずai.summarizeを試してみました。長文レビューを1件ずつ短く要約します:

SELECT
review_id,
branch,
ai.summarize(review_text) AS summary
FROM (
SELECT review_id, branch, review_text
FROM disneyland_reviews
WHERE branch = 'Disneyland_HongKong'
LIMIT 5
) sub;


長文のレビューが数行の要約に。データサイエンスエージェントのinsight_agentに渡すコンテキスト情報として、この要約済みテキストを活用できそうです。

次が面白かったai.agg_summarizeです。パークごとの10件のレビューをまとめて1段落に集約します:

SELECT
branch,
COUNT(*) AS review_count,
ai.agg_summarize(review_text) AS overall_summary
FROM (
(SELECT branch, review_text FROM disneyland_reviews WHERE branch = 'Disneyland_California' LIMIT 10)
UNION ALL
(SELECT branch, review_text FROM disneyland_reviews WHERE branch = 'Disneyland_Paris' LIMIT 10)
UNION ALL
(SELECT branch, review_text FROM disneyland_reviews WHERE branch = 'Disneyland_HongKong' LIMIT 10)
) sub
GROUP BY branch;


各パークのレビュー群が1段落にまとまって返ってきました。

カリフォルニアは「幼児連れには大人3人に幼児2人の体制が推奨され、開園15分前に到着すると待ち時間が短い」といった実用的なアドバイスが集約され、香港は「他パークより規模は小さいがアイアンマン体験やスペースマウンテンが人気で、2日券がおすすめ」という評価にまとまり、パリは「子連れに強くおすすめだが費用は高め、パレードや花火ショーが特に好評」という形で整理されました。

この要約テキストをデータサイエンスエージェントのinsight_agentへの入力として渡せば、AlloyDBのテキストデータを踏まえた上でのビジネス考察も生成できるようになります。

つまずいたポイント・気づいたこと

① IAM設定を最初に確認しておく

AlloyDBのサービスアカウントにAgent Platform Userの権限を付与しないと、AI関数呼び出し時に「権限エラー」が返ってきます。拡張機能の有効化より先にIAM設定を終わらせておくとスムーズです。

② LIMITはサブクエリで先に絞る

AI関数はFROM句で取得した全行に対して実行されるため、LIMIT を外側に書くだけでは全件分のAPI呼び出しが発生します。サブクエリで先に件数を絞ってからAI関数を適用する書き方が必須です。これはBigQueryのUDF系関数と同じ考え方で、WHERE句の絞り込みだけでなくLIMITも内側のクエリに入れる必要があります。

③ 大量データへの適用はバッチ処理で費用を抑えよう

AI関数の呼び出しはVertex AIのAPIを使うため、呼び出し回数に応じてコストがかかります。また今回の検証では20件で約5分かかりました。全件を一気にSELECTするとコストと時間の両方が課題になるので、WHERE句で絞り込んだり、更新分だけに適用するバッチ処理にするのが現実的です。

まとめ

AlloyDBのAI関数を実際に使ってみて、「データを動かさずにDBの中でAI処理が完結する」体験は想像以上に快適でした。データサイエンスエージェントのdb_agentがBigQueryに対してSQLを生成するように、AlloyDBに対してもai.analyze_sentimentai.agg_summarizeを含むSQLを生成すれば、テキスト分析のパイプライン構築をエージェント側に任せられる可能性があります。

  • ai.analyze_sentimentでテキストの感情を positive/negative/neutral に分類できる
  • ai.summarizeで1行ずつ、ai.agg_summarizeでGROUP BY集約の要約が作れる
  • LIMIT はサブクエリで先に絞らないと全件分のAPI呼び出しが発生するので要注意
  • 現時点はプレビューのため、本番適用前にコスト試算と動作検証を推奨

AlloyDBにテキストデータを持っていて「分析したいけどパイプライン構築が面倒」と思っている方々には、AlloyDBのAI関数はかなり有力な選択肢になってきたと思います。プレビュー期間中にぜひ試してみてください!

システムサポートでは、Google Cloudの導入や活用を支援しております。

Google Cloudを導入したい・導入したけど使いこなせていない…という方は、お気軽にご相談ください!


Google Cloud 導入・活動支援に関するご相談はこちら

2026年5月26日 AlloyDBのAI関数でSQLだけで感情分析・要約をしてみた!

Category Google Cloud

ご意見・ご相談・料金のお見積もりなど、
お気軽にお問い合わせください。

お問い合わせはこちら