マネージド AI 関数を使用してセマンティック分析を行う
このチュートリアルでは、BigQuery ML マネージド AI 関数を使用して顧客フィードバックのセマンティック分析を行う方法について説明します。
目標
このチュートリアルの内容は次のとおりです。
- データセットを作成して感情データをテーブルに読み込む
- Cloud リソース接続を作成する
- 次の AI 関数を使用して、セマンティック分析を行います。
AI.IF: 自然言語条件でデータをフィルタするAI.SCORE: 感情で入力を評価するAI.CLASSIFY: 入力をユーザー定義のカテゴリに分類する
費用
このチュートリアルでは、 Google Cloudの課金対象となる以下のコンポーネントを使用しています。
- BigQuery
- BigQuery ML
BigQuery の費用の詳細については、BigQuery の料金ページをご覧ください。
BigQuery ML の費用の詳細については、BigQuery ML の料金をご覧ください。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
このガイドで既存のプロジェクトを使用する場合は、このガイドを完了するために必要な権限があることを確認します。新しいプロジェクトを作成した場合は、必要な権限がすでに付与されています。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
このガイドで既存のプロジェクトを使用する場合は、このガイドを完了するために必要な権限があることを確認します。新しいプロジェクトを作成した場合は、必要な権限がすでに付与されています。
-
Enable the BigQuery API and BigQuery Connection API APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.新しいプロジェクトでは、BigQuery API が自動的に有効になります。
- (省略可)プロジェクトに対する課金を有効にします。課金を有効にしない場合や、クレジット カードを指定しない場合でも、このドキュメントの手順は行えます。BigQuery には、この手順を実施するためのサンドボックスが用意されています。詳細については、BigQuery サンドボックスを有効にするをご覧ください。
-
クエリジョブと読み込みジョブを実行する: BigQuery ジョブユーザー (
roles/bigquery.jobUser) -
接続を作成する: BigQuery Connection 管理者(
roles/bigquery.connectionAdmin) -
データセットの作成、テーブルの作成、テーブルへのデータの読み込み、テーブルのクエリ: BigQuery データ編集者(
roles/bigquery.dataEditor) [BigQuery] ページに移動します。
左側のペインで、 [エクスプローラ] をクリックします。

左側のペインが表示されていない場合は、 左ペインを開くをクリックしてペインを開きます。
[エクスプローラ] ペインで、プロジェクト名を開き、[接続] をクリックします。
[接続] ページで、[接続を作成] をクリックします。
[接続タイプ] で、[Vertex AI リモートモデル、リモート関数、BigLake、Spanner(Cloud リソース)] を選択します。
[接続 ID] フィールドに接続の名前を入力します。
[ロケーション タイプ] で、接続のロケーションを選択します。接続は、データセットなどの他のリソースと同じ場所に配置する必要があります。
[接続を作成] をクリックします。
[接続へ移動] をクリックします。
[接続情報] ペインで、後の手順で使用するサービス アカウント ID をコピーします。
コマンドライン環境で接続を作成します。
bq mk --connection --location=REGION --project_id=PROJECT_ID \ --connection_type=CLOUD_RESOURCE CONNECTION_ID
--project_idパラメータは、デフォルト プロジェクトをオーバーライドします。次のように置き換えます。
REGION: 接続のリージョンPROJECT_ID: 実際の Google Cloud プロジェクト IDCONNECTION_ID: 接続の ID
接続リソースを作成すると、BigQuery は、一意のシステム サービス アカウントを作成し、それを接続に関連付けます。
トラブルシューティング: 次の接続エラーが発生した場合は、Google Cloud SDK を更新します。
Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
後の手順で使用するため、サービス アカウント ID を取得してコピーします。
bq show --connection PROJECT_ID.REGION.CONNECTION_ID
出力は次のようになります。
name properties 1234.REGION.CONNECTION_ID {"serviceAccountId": "connection-1234-9u56h9@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}- Cloud Shell を起動します。
-
Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。
このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。
export GOOGLE_CLOUD_PROJECT=PROJECT_ID
Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。
-
Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は
.tfにする必要があります(例:main.tf)。このチュートリアルでは、このファイルをmain.tfとします。mkdir DIRECTORY && cd DIRECTORY && touch main.tf
-
チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。
新しく作成した
main.tfにサンプルコードをコピーします。必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。
- 環境に適用するサンプル パラメータを確認し、変更します。
- 変更を保存します。
-
Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行います。
terraform init
最新バージョンの Google プロバイダを使用する場合は、
-upgradeオプションを使用します。terraform init -upgrade
-
構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
terraform plan
必要に応じて構成を修正します。
-
次のコマンドを実行します。プロンプトで「
yes」と入力して、Terraform 構成を適用します。terraform apply
Terraform に「Apply complete!」というメッセージが表示されるまで待ちます。
- Google Cloud プロジェクトを開いて結果を表示します。 Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。
[IAM と管理] ページに移動します。
[アクセス権を付与] をクリックします。
[新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。
[ロールを選択] フィールドで、[Vertex AI]、[Vertex AI ユーザーロール] の順に選択します。
[保存] をクリックします。
- レビューから顧客満足度を測定します。
- ソーシャル メディアでのブランド認知度をモニタリングします。
- ユーザーの不満度に基づいてサポート チケットの優先順位を付けます。
- お客様のフィードバックに共通するテーマを見つけます。
- ドキュメントを主題別に整理します。
- サポート チケットをトピック別にルーティングします。
- 重複するエントリまたはほぼ重複するエントリを見つけます。
- 同様のフィードバックをグループ化します。
- セマンティック検索アプリケーションを強化します。
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
必要なロール
AI 関数を使用するために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
サンプルデータを作成する
このチュートリアル用に my_dataset というデータセットを作成するには、次のクエリを実行します。
CREATE SCHEMA my_dataset OPTIONS (location = 'LOCATION');
次に、デバイスの顧客レビューのサンプルを含む customer_feedback というテーブルを作成します。
CREATE TABLE my_dataset.customer_feedback AS (
SELECT
*
FROM
UNNEST( [STRUCT<review_id INT64, review_text STRING>
(1, "The battery life is incredible, and the screen is gorgeous! Best phone I've ever had. Totally worth the price."),
(2, "Customer support was a nightmare. It took three weeks for my order to arrive, and when it did, the box was damaged. Very frustrating!"),
(3, "The product does exactly what it says on the box. No complaints, but not exciting either."),
(4, "I'm so happy with this purchase! It arrived early and exceeded all my expectations. The quality is top-notch, although the setup was a bit tricky."),
(5, "The price is a bit too high for what you get. The material feels cheap and I'm worried it won't last. Service was okay."),
(6, "Absolutely furious! The item arrived broken, and getting a refund is proving impossible. I will never buy from them again."),
(7, "This new feature for account access is confusing. I can't find where to update my profile. Please fix this bug!"),
(8, "The shipping was delayed, but the support team was very helpful and kept me informed. The product itself is great, especially for the price.")
])
);
接続を作成する
クラウド リソース接続を作成し、接続のサービス アカウントを取得します。
次のオプションのいずれかを選択します。
コンソール
bq
Terraform
google_bigquery_connection リソースを使用します。
BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、クライアント ライブラリの認証を設定するをご覧ください。
次の例では、US リージョンに my_cloud_resource_connection という名前の Cloud リソース接続を作成します。
Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。
Cloud Shell を準備する
ディレクトリを準備する
Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。
変更を適用する
接続のサービス アカウントに権限を付与する
接続のサービス アカウントに Vertex AI ユーザーロールを付与します。このロールは、始める前にで作成または選択したプロジェクトで付与する必要があります。別のプロジェクトでロールを付与すると、「bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource」というエラーが発生します。
ロールを付与する手順は次のとおりです。
全体的なセンチメントを分類する
テキストで表現された全体的な感情を抽出すると、次のようなユースケースで役立ちます。
次のクエリは、AI.CLASSIFY 関数を使用して customer_feedback テーブルのレビューを「肯定的」、「否定的」、「どちらでもない」に分類する方法を示しています。
SELECT
review_id,
review_text,
AI.CLASSIFY(
review_text,
categories => ['positive', 'negative', 'neutral'],
connection_id => "CONNECTION_ID") AS sentiment
FROM
my_dataset.customer_feedback;
結果は次のようになります。
+-----------+------------------------------------------+-----------+ | review_id | review_text | sentiment | +-----------+------------------------------------------+-----------+ | 7 | This new feature for account access is | negative | | | confusing. I can't find where to update | | | | my profile. Please fix this bug! | | +-----------+------------------------------------------+-----------+ | 4 | "I'm so happy with this purchase! It | positive | | | arrived early and exceeded all my | | | | expectations. The quality is top-notch, | | | | although the setup was a bit tricky." | | +-----------+------------------------------------------+-----------+ | 2 | "Customer support was a nightmare. It | negative | | | took three weeks for my order to | | | | arrive, and when it did, the box was | | | | damaged. Very frustrating!" | | +-----------+------------------------------------------+-----------+ | 1 | "The battery life is incredible, and | positive | | | the screen is gorgeous! Best phone I've | | | | ever had. Totally worth the price." | | +-----------+------------------------------------------+-----------+ | 8 | "The shipping was delayed, but the | positive | | | support team was very helpful and kept | | | | me informed. The product itself is | | | | great, especially for the price." | | +-----------+------------------------------------------+-----------+ | 5 | The price is a bit too high for what | negative | | | you get. The material feels cheap and | | | | I'm worried it won't last. Service was | | | | okay. | | +-----------+------------------------------------------+-----------+ | 3 | "The product does exactly what it says | neutral | | | on the box. No complaints, but not | | | | exciting either." | | +-----------+------------------------------------------+-----------+ | 6 | "Absolutely furious! The item arrived | negative | | | broken, and getting a refund is proving | | | | impossible. I will never buy from them | | | | again." | | +-----------+------------------------------------------+-----------+
アスペクトベースの感情を分析する
ユースケースで 肯定的や否定的などの全体的な感情では不十分な場合は、テキストの意味の特定の側面を分析できます。たとえば、価格に関するユーザーの考え方は考慮せずに、商品の品質に対するユーザーの態度を把握したい場合があります。特定の側面が適用されないことを示すカスタム値をリクエストすることもできます。
次の例は、AI.SCORE 関数を使用して、customer_feedback テーブルの各レビューが価格、カスタマー サービス、品質に対してどの程度好意的であるかに基づいて、ユーザーの感情を 1 ~ 10 の範囲で評価する方法を示しています。レビューでアスペクトが言及されていない場合、関数はカスタム値 -1 を返します。これにより、後でこれらの値をフィルタできます。
SELECT
review_id,
review_text,
AI.SCORE(
("Score 0.0 to 10 on positive sentiment about PRICE for review: ", review_text,
"If price is not mentioned, return -1.0"),
connection_id => "CONNECTION_ID") AS price_score,
AI.SCORE(
("Score 0.0 to 10 on positive sentiment about CUSTOMER SERVICE for review: ", review_text,
"If customer service is not mentioned, return -1.0"),
connection_id => "CONNECTION_ID") AS service_score,
AI.SCORE(
("Score 0.0 to 10 on positive sentiment about QUALITY for review: ", review_text,
"If quality is not mentioned, return -1.0"),
connection_id => "CONNECTION_ID") AS quality_score
FROM
my_dataset.customer_feedback
LIMIT 3;
結果は次のようになります。
+-----------+------------------------------------------+--------------+---------------+---------------+ | review_id | review_text | price_score | service_score | quality_score | +-----------+------------------------------------------+--------------+---------------+---------------+ | 4 | "I'm so happy with this purchase! It | -1.0 | -1.0 | 9.5 | | | arrived early and exceeded all my | | | | | | expectations. The quality is top-notch, | | | | | | although the setup was a bit tricky." | | | | +-----------+------------------------------------------+--------------+---------------+---------------+ | 8 | "The shipping was delayed, but the | 9.0 | 8.5 | 9.0 | | | support team was very helpful and kept | | | | | | me informed. The product itself is | | | | | | great, especially for the price." | | | | +-----------+------------------------------------------+--------------+---------------+---------------+ | 6 | "Absolutely furious! The item arrived | -1.0 | 1.0 | 0.0 | | | broken, and getting a refund is proving | | | | | | impossible. I will never buy from them | | | | | | again." | | | | +-----------+------------------------------------------+--------------+---------------+---------------+
感情を検出する
ポジティブまたはネガティブな感情に加えて、選択した特定の感情に基づいてテキストを分類できます。これは、ユーザーの回答をより深く理解したり、感情的なフィードバックにフラグを付けてレビューしたりする場合に便利です。
SELECT
review_id,
review_text,
AI.CLASSIFY(
review_text,
categories => ['joy', 'anger', 'sadness', 'surprise', 'fear', 'disgust', 'neutral', 'other'],
connection_id => "CONNECTION_ID"
) AS emotion
FROM
my_dataset.customer_feedback;
結果は次のようになります。
+-----------+------------------------------------------+---------+ | review_id | review_text | emotion | +-----------+------------------------------------------+---------+ | 2 | "Customer support was a nightmare. It | anger | | | took three weeks for my order to | | | | arrive, and when it did, the box was | | | | damaged. Very frustrating!" | | +-----------+------------------------------------------+---------+ | 7 | This new feature for account access is | anger | | | confusing. I can't find where to update | | | | my profile. Please fix this bug! | | +-----------+------------------------------------------+---------+ | 4 | "I'm so happy with this purchase! It | joy | | | arrived early and exceeded all my | | | | expectations. The quality is top-notch, | | | | although the setup was a bit tricky." | | +-----------+------------------------------------------+---------+ | 1 | "The battery life is incredible, and | joy | | | the screen is gorgeous! Best phone I've | | | | ever had. Totally worth the price." | | +-----------+------------------------------------------+---------+ | 8 | "The shipping was delayed, but the | joy | | | support team was very helpful and kept | | | | me informed. The product itself is | | | | great, especially for the price." | | +-----------+------------------------------------------+---------+ | 5 | The price is a bit too high for what | sadness | | | you get. The material feels cheap and | | | | I'm worried it won't last. Service was | | | | okay. | | +-----------+------------------------------------------+---------+ | 3 | "The product does exactly what it says | neutral | | | on the box. No complaints, but not | | | | exciting either." | | +-----------+------------------------------------------+---------+ | 6 | "Absolutely furious! The item arrived | anger | | | broken, and getting a refund is proving | | | | impossible. I will never buy from them | | | | again." | | +-----------+------------------------------------------+---------+
レビューをトピック別に分類する
AI.CLASSIFY 関数を使用すると、レビューを事前定義されたトピックにグループ化できます。たとえば、次の操作が可能です。
次の例は、顧客のフィードバックを「請求に関する問題」や「アカウントへのアクセス」などのさまざまなタイプに分類し、各カテゴリに属するレビューの数をカウントする方法を示しています。
SELECT
AI.CLASSIFY(
review_text,
categories => ['Billing Issue', 'Account Access',
'Product Bug', 'Feature Request',
'Shipping Delay', 'Other'],
connection_id => "CONNECTION_ID") AS topic,
COUNT(*) AS number_of_reviews,
FROM
my_dataset.customer_feedback
GROUP BY topic
ORDER BY number_of_reviews DESC;
結果は次のようになります。
+----------------+-------------------+ | topic | number_of_reviews | +----------------+-------------------+ | Other | 5 | | Shipping Delay | 2 | | Product Bug | 1 | +----------------+-------------------+
意味的に類似したレビューを特定する
AI.SCORE 関数を使用すると、意味の類似度を評価して、2 つのテキストの意味がどの程度類似しているかを評価できます。これは、次のようなタスクに役立ちます。
次のクエリは、製品のセットアップの難しさについて言及しているレビューを検索します。
SELECT
review_id,
review_text,
AI.SCORE(
(
"""How similar is the review to the concept of 'difficulty in setting up the product'?
A higher score indicates more similarity. Review: """,
review_text),
connection_id => "CONNECTION_ID") AS setup_difficulty
FROM my_dataset.customer_feedback
ORDER BY setup_difficulty DESC
LIMIT 2;
結果は次のようになります。
+-----------+------------------------------------------+------------------+ | review_id | review_text | setup_difficulty | +-----------+------------------------------------------+------------------+ | 4 | "I'm so happy with this purchase! It | 3 | | | arrived early and exceeded all my | | | | expectations. The quality is top-notch, | | | | although the setup was a bit tricky." | | +-----------+------------------------------------------+------------------+ | 7 | This new feature for account access is | 1 | | | confusing. I can't find where to update | | | | my profile. Please fix this bug! | | +-----------+------------------------------------------+------------------+
AI.IF 関数を使用して、テキストに関連するレビューを見つけることもできます。
SELECT
review_id,
review_text
FROM my_dataset.customer_feedback
WHERE
AI.IF(
(
"Does this review discuss difficulty setting up the product? Review: ",
review_text),
connection_id => "CONNECTION_ID");
結合関数
これらの関数を 1 つのクエリに結合すると便利な場合があります。たとえば、次のクエリは、最初に否定的な感情のクチコミをフィルタし、次に不満の種類で分類します。
SELECT
review_id,
review_text,
AI.CLASSIFY(
review_text,
categories => [
'Poor Quality', 'Bad Customer Service', 'High Price', 'Other Negative'],
connection_id => "CONNECTION_ID") AS negative_topic
FROM my_dataset.customer_feedback
WHERE
AI.IF(
("Does this review express a negative sentiment? Review: ", review_text),
connection_id => "CONNECTION_ID");
再利用可能なプロンプト UDF を作成する
クエリの可読性を維持するために、ユーザー定義関数を作成してプロンプト ロジックを再利用できます。次のクエリは、カスタム プロンプトを使用して AI.IF を呼び出し、否定的な感情を検出する関数を作成します。次に、その関数を呼び出して否定的なレビューでフィルタします。
CREATE OR REPLACE FUNCTION my_dataset.is_negative_sentiment(review_text STRING)
RETURNS BOOL
AS (
AI.IF(
("Does this review express a negative sentiment? Review: ", review_text),
connection_id => "CONNECTION_ID")
);
SELECT
review_id,
review_text
FROM my_dataset.customer_feedback
WHERE my_dataset.is_negative_sentiment(review_text);
クリーンアップ
課金されないようにするには、作成したリソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
プロジェクトの削除
プロジェクトを削除するには:
データセットを削除する
データセットと、それに含まれるすべてのリソース(すべてのテーブルと関数を含む)を削除するには、次のクエリを実行します。
DROP SCHEMA my_dataset CASCADE;