こんにちは、中村です。皆さんはCortex Analystを使っていますか?
Snowflake×AIを使っていくうえで欠かせない機能だと思います!
今回はCortex Analystについて解説していこうと思います!
目次
Cortex Analystとは
Snowflake Cortex Analystは、Snowflakeプラットフォーム上で動作するフルマネージドサービスで、自然言語での質問をSQLクエリに変換し、構造化データに基づいてビジネス上の質問に対する回答を提供します。LLMを活用しているため、ユーザーはSQLを直接書くことなく、データにアクセスし、分析を行うことができるのが大きなメリットです。
現在Cortex Analystはセマンティックモデルとセマンティックビューの2つが対応しています。
今回はセマンティックモデルとセマンティックビューの両方を作成したいと思います!
準備
セマンティックモデルの準備
セマンティックモデルはYAML形式で記述されているものを指します。
今回はこちらの公式クイックスタートをもとにセマンティックモデルを作成していきます。
セマンティックモデルの例
name: Revenue
tables:
- name: daily_revenue
description: Daily total revenue, aligned with daily "Cost of Goods Sold" (COGS), and forecasted revenue.
base_table:
database: cortex_analyst_demo
schema: revenue_timeseries
table: daily_revenue
primary_key:
columns:
- date
- product_id
- region_id
time_dimensions:
- name: date
expr: date
description: date with measures of revenue, COGS, and forecasted revenue.
unique: true
data_type: date
dimensions:
- name: product_id
expr: product_id
data_type: number
- name: region_id
expr: region_id
data_type: number
facts:
- name: daily_revenue
expr: revenue
description: total revenue for the given day
synonyms:
- sales
- income
default_aggregation: sum
data_type: number
- name: daily_cogs
expr: cogs
description: total cost of goods sold for the given day
synonyms:
- cost
- expenditures
default_aggregation: sum
data_type: number
- name: daily_forecasted_revenue
expr: forecasted_revenue
description: total forecasted revenue for a given day
synonyms:
- forecasted sales
- forecasted income
default_aggregation: sum
data_type: number
- name: daily_profit
description: profit is the difference between revenue and expenses.
expr: revenue - cogs
data_type: number
- name: daily_forecast_abs_error
synonyms:
- absolute error
- L1
description: absolute error between forecasted and actual revenue
expr: abs(forecasted_revenue - revenue)
data_type: number
default_aggregation: avg
- name: product
description: Product dimension table with unique product identifiers and attributes.
base_table:
database: cortex_analyst_demo
schema: revenue_timeseries
table: product_dim
primary_key:
columns:
- product_id
dimensions:
- name: product_id
expr: product_id
data_type: number
- name: product_line
expr: product_line
description: Product line associated with revenue
data_type: varchar
sample_values:
- Electronics
- Clothing
- Home Appliances
- Toys
- Books
- name: region
description: Region dimension table with unique region identifiers and geographic attributes.
base_table:
database: cortex_analyst_demo
schema: revenue_timeseries
table: region_dim
primary_key:
columns:
- region_id
dimensions:
- name: region_id
expr: region_id
data_type: number
- name: sales_region
expr: sales_region
description: Region associated with revenue
data_type: varchar
sample_values:
- North America
- Europe
- Asia
- South America
- Africa
- name: product_dimension
base_table:
database: cortex_analyst_demo
schema: revenue_timeseries
table: product_dim
dimensions:
- name: product_line
expr: product_line
cortex_search_service_name: product_line_search_service
data_type: varchar
relationships:
- name: revenue_to_product
left_table: daily_revenue
right_table: product
relationship_columns:
- left_column: product_id
right_column: product_id
join_type: left_outer
relationship_type: many_to_one
- name: revenue_to_region
left_table: daily_revenue
right_table: region
relationship_columns:
- left_column: region_id
right_column: region_id
join_type: left_outer
relationship_type: many_to_one
verified_queries:
- name: daily cumulative expenses in 2023 dec
question: 2023年12月の日ごとの累積費用は?
verified_at: 1714752498
verified_by: renee
sql: ' SELECT date, SUM(daily_cogs) OVER ( ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_cogs FROM daily_revenue WHERE date BETWEEN ''2023-12-01'' AND ''2023-12-31'' ORDER BY date DESC; '
- name: lowest revenue each month
question: 各月において、1日当たりの最低の収益はいくらで、それはいつ?
sql: WITH monthly_min_revenue AS ( SELECT DATE_TRUNC('MONTH', date) AS month, MIN(daily_revenue) AS min_revenue FROM daily_revenue GROUP BY DATE_TRUNC('MONTH', date) ) SELECT mmr.month, mmr.min_revenue, dr.date AS min_revenue_date FROM monthly_min_revenue AS mmr JOIN daily_revenue AS dr ON mmr.month = DATE_TRUNC('MONTH', dr.date) AND mmr.min_revenue = dr.daily_revenue ORDER BY mmr.month DESC NULLS LAST
verified_at: 1715187400
verified_by: renee
まずはデータベース、スキーマ、WHと内部ステージを作っていきます。
SnowsightのSQLワークシートから以下を実行してください。
/*--
• Database, schema, warehouse, and stage creation
--*/
USE ROLE SECURITYADMIN;
CREATE ROLE cortex_user_role;
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE cortex_user_role;
GRANT ROLE cortex_user_role TO USER <user>;
USE ROLE sysadmin;
-- Create demo database
CREATE OR REPLACE DATABASE cortex_analyst_demo;
-- Create schema
CREATE OR REPLACE SCHEMA cortex_analyst_demo.revenue_timeseries;
-- Create warehouse
CREATE OR REPLACE WAREHOUSE cortex_analyst_wh
WAREHOUSE_SIZE = 'large'
WAREHOUSE_TYPE = 'standard'
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED = TRUE
COMMENT = 'Warehouse for Cortex Analyst demo';
GRANT USAGE ON WAREHOUSE cortex_analyst_wh TO ROLE cortex_user_role;
GRANT OPERATE ON WAREHOUSE cortex_analyst_wh TO ROLE cortex_user_role;
GRANT OWNERSHIP ON SCHEMA cortex_analyst_demo.revenue_timeseries TO ROLE cortex_user_role;
GRANT OWNERSHIP ON DATABASE cortex_analyst_demo TO ROLE cortex_user_role;
USE ROLE cortex_user_role;
-- Use the created warehouse
USE WAREHOUSE cortex_analyst_wh;
USE DATABASE cortex_analyst_demo;
USE SCHEMA cortex_analyst_demo.revenue_timeseries;
-- Create stage for raw data
CREATE OR REPLACE STAGE raw_data DIRECTORY = (ENABLE = TRUE);
/*--
• Fact and Dimension Table Creation
--*/
-- Fact table: daily_revenue
CREATE OR REPLACE TABLE cortex_analyst_demo.revenue_timeseries.daily_revenue (
date DATE,
revenue FLOAT,
cogs FLOAT,
forecasted_revenue FLOAT,
product_id INT,
region_id INT
);
-- Dimension table: product_dim
CREATE OR REPLACE TABLE cortex_analyst_demo.revenue_timeseries.product_dim (
product_id INT,
product_line VARCHAR(16777216)
);
-- Dimension table: region_dim
CREATE OR REPLACE TABLE cortex_analyst_demo.revenue_timeseries.region_dim (
region_id INT,
sales_region VARCHAR(16777216),
state VARCHAR(16777216)
);
次に内部ステージにCSVファイルとYAMLファイルを追加していきます。
追加するのは以下の4つです。
・daily_revenue.csv
・region.csv
・product.csv
・revenue_timeseries.yaml
それぞれGitHubからダウンロードして、CORTEX_ANALYST_DEMO/REVENUE_TIMESERIES/RAW_DATAにインポートしてください。
最後にテーブルに内部ステージのデータをロードしましょう。
以下をSQLワークシートで実行します。
/*--
• load data into tables
--*/
USE ROLE CORTEX_USER_ROLE;
USE DATABASE CORTEX_ANALYST_DEMO;
USE SCHEMA CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES;
USE WAREHOUSE CORTEX_ANALYST_WH;
COPY INTO CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.DAILY_REVENUE
FROM @raw_data
FILES = ('daily_revenue.csv')
FILE_FORMAT = (
TYPE=CSV,
SKIP_HEADER=1,
FIELD_DELIMITER=',',
TRIM_SPACE=FALSE,
FIELD_OPTIONALLY_ENCLOSED_BY=NONE,
REPLACE_INVALID_CHARACTERS=TRUE,
DATE_FORMAT=AUTO,
TIME_FORMAT=AUTO,
TIMESTAMP_FORMAT=AUTO
EMPTY_FIELD_AS_NULL = FALSE
error_on_column_count_mismatch=false
)
ON_ERROR=CONTINUE
FORCE = TRUE ;
COPY INTO CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.PRODUCT_DIM
FROM @raw_data
FILES = ('product.csv')
FILE_FORMAT = (
TYPE=CSV,
SKIP_HEADER=1,
FIELD_DELIMITER=',',
TRIM_SPACE=FALSE,
FIELD_OPTIONALLY_ENCLOSED_BY=NONE,
REPLACE_INVALID_CHARACTERS=TRUE,
DATE_FORMAT=AUTO,
TIME_FORMAT=AUTO,
TIMESTAMP_FORMAT=AUTO
EMPTY_FIELD_AS_NULL = FALSE
error_on_column_count_mismatch=false
)
ON_ERROR=CONTINUE
FORCE = TRUE ;
COPY INTO CORTEX_ANALYST_DEMO.REVENUE_TIMESERIES.REGION_DIM
FROM @raw_data
FILES = ('region.csv')
FILE_FORMAT = (
TYPE=CSV,
SKIP_HEADER=1,
FIELD_DELIMITER=',',
TRIM_SPACE=FALSE,
FIELD_OPTIONALLY_ENCLOSED_BY=NONE,
REPLACE_INVALID_CHARACTERS=TRUE,
DATE_FORMAT=AUTO,
TIME_FORMAT=AUTO,
TIMESTAMP_FORMAT=AUTO
EMPTY_FIELD_AS_NULL = FALSE
error_on_column_count_mismatch=false
)
ON_ERROR=CONTINUE
FORCE = TRUE ;
これでセマンティックモデルの作成が完了しました。今回は内部ステージに直接YAMLファイルをインポートしましたが、AIとML>Cortex分析が表示されるようになったので、Create new model>Upload your YAML fileを選択すると、同じようにCORTEX_ANALYST_DEMO/REVENUE_TIMESERIES/RAW_DATAにインポートできます。
すでにテーブルがあるものに関するYAMLファイルの追加はこっちからの方が楽そうですね!


ここで一旦作成したセマンティックモデルを見てみましょう。
AIとML>Cortex分析から上部タブでセマンティックモデルを選び、先ほどインポートしたrevenue_timeseries.yamlを選択

これでYAML形式のセマンティックモデルがわかりやすく見ることができます。

各項目とその意味は以下の通りです。
カスタム手順
LLM(大規模言語モデル)が生成する SQL クエリに追加ルールや振る舞いを自然言語で指示できる機能
標準出力の丸めやデフォルトフィルタなど、共通ビジネスロジックをSQL生成に組み込みたいときなどに有効
論理テーブル
論理テーブルは、物理データベーステーブルまたはビューのシンプルなビューとして考えることができる。各論理テーブルは論理列のコレクションであり、ディメンション、時間ディメンション、およびファクトに分類される
関係
テーブル間の関係を記述できる
確認済みクエリ
よく使うクエリなどはあらかじめ名前をつけて直接作成することができる
セマンティックビューの準備
セマンティックビューはViewとしてSnowflake上で物理的に保持しているものです。
今度は、REVENUE_TIMESERIESのセマンティックモデルと同じセマンティックビューを0から作っていきましょう。
AIとML>Cortex分析>Create new model>Create new modelを選択。
セマンティックビューを選択し、保管場所はCORTEX_ANALYST_DEMO/REVENUE_TIMESERIES、名前はセマンティックモデルと同じく、REVENUE_TIMESERIESにします。

続いてセマンティックビューの対象となるテーブルを選択していきます。
先ほどセマンティックモデル作成で作った3つのテーブルを選択します。

続いて選択したテーブル内で対象の列を選択していきます。
今回はすべての列を選択します。

最後にCortex検索との接続設定です。
製品名称などユニークな値が多い列の場合、Cortex検索と接続することで、クエリ実行時に適切な値をより正確に選択できるようになります。
今回は作成していないので、そのまま作成して保存しましょう。

これでセマンティックビューの中身が自動で作成できました。現在どのようなものができているか確認しましょう。
現在論理テーブルは物理テーブルと一対一で対応しているものが3つ、関係はなし、確認済みクエリはまだありません。
ファクトにproduct_idやregion_idが入っているのも少し気になりますね。
実際に使うには細かい設定が必要なようです。

ここでは細かい修正をGUIで行いましょう。
まずは、ファクトに入ったid系の列をディメンションに移します。
論理テーブルのDAILY_REVENUEのファクト>PRODUCT_IDの三点リーダーより移動先Dimensionsを選択

これ以外にも
・DAILY_REVENUEのREGION_ID
・PRODUCT_DIMのPRODUCT_ID
・REGION_DIMのREGION_ID
をファクトからディメンションに変更します。
次に関係を設定します。
関係の項目の右の+から関係の設定をします。
まずは、DAILY_REVENUEとPRODUCT_DIMの関係を定義しましょう。
以下の様に入力して追加を選択します。

続けてDAILY_REVENUEとREGION_DIMの関係を定義しましょう。

これで3つのテーブルがつながりました!

これでセマンティックビューの作成が完了です!
また先述の通り、セマンティックビューはViewでもあるので、直接クエリを書いて結果を表示させる表示させることができます。

Cortex Analystを使ってみた
準備に時間がかかりましたが、ここからはCortex Analystを実際に使ってみます。
どのように使うのかというと先ほどまで使っていた、セマンティックモデル、セマンティックビューの詳細の画面の右側で質問ができるようになっています!

今回は作成したセマンティックビューの方で質問をしていきましょう。
まずは中央のの「データセットを説明」を選択して対象のデータがどのようなもので、どのような分析ができるか説明してもらいましょう。

訳:この意味的データモデルには、異なる製品カテゴリと地理的地域にわたる日次収益データが含まれています。収益、コスト、および時系列での予測収益を分析可能です。データを活用することで、製品カテゴリ別および販売地域・州別の財務パフォーマンスを詳細に分解分析できます。収益トレンドの分析、収益性の計算、予測精度の比較、地理的パフォーマンスの評価など、さまざまな分析手法を適用できます。
ちなみに、返答の下に3つほど追加の質問がありますが、ここは確認済みクエリを設定すると、それらが表示されるようになります。
続いて、真ん中の「How does actual revenue compare to forecasted revenue by sales region for last month?」を選択
すると結果は空のようです。
データセットには2024年までのデータしか入っていないので、先月の結果は出せなくて当然ですね。
これは各カラムでサンプル値を設定すれば解決するかもしれませんね。

最後に2023年12月の累計費用を聞いてみましょう!
プロンプトに「What are the daily cumulative costs for December 2023?」を入力
するとちゃんと累計の費用が表示されました!

またこの結果を見返せるように確認済みクエリに追加しましょう!

名前は「2023年12月の日ごとの累積費用」にします。

追加されているのも確認できました!

まとめ
今回はセマンティックモデル、セマンティックビューの作成からCortex Analystの使い方まで解説しました。
AIの普及によってセマンティックモデル、セマンティックビューは重要になること間違いなしなので、ぜひ使いこなしたいですね!
Snowflakeの他のAI機能に関する記事も多数ご用意しています。ぜひあわせてご覧ください!