관리형 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 연결 관리자(
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 프로젝트를 설정합니다.
이 명령어는 프로젝트당 한 번만 실행하면 되며 어떤 디렉터리에서도 실행할 수 있습니다.
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을 초기화합니다. 이 작업은 디렉터리당 한 번만 수행하면 됩니다.
terraform init
원하는 경우 최신 Google 공급업체 버전을 사용하려면
-upgrade옵션을 포함합니다.terraform init -upgrade
-
구성을 검토하고 Terraform에서 만들거나 업데이트할 리소스가 예상과 일치하는지 확인합니다.
terraform plan
필요에 따라 구성을 수정합니다.
-
다음 명령어를 실행하고 프롬프트에
yes를 입력하여 Terraform 구성을 적용합니다.terraform apply
Terraform에 '적용 완료' 메시지가 표시될 때까지 기다립니다.
- 결과를 보려면 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 함수를 사용하여 의미의 유사성을 평가하도록 요청하여 두 텍스트가 얼마나 의미적으로 유사한지 평가할 수 있습니다. 이를 통해 다음과 같은 작업을 수행할 수 있습니다.
다음 쿼리는 제품 설정의 어려움을 설명하는 리뷰를 찾습니다.
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");
함수 결합
단일 쿼리에서 이러한 함수를 결합하면 유용할 수 있습니다. 예를 들어 다음 쿼리는 먼저 부정적인 감정의 리뷰를 필터링한 다음 불만의 유형별로 분류합니다.
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;