はじめに
Snowflakeでは自然言語を用いてSnowflakeデータに対する質問を行うことができるCortex Analystと呼ばれる機能を提供しています。ビジネスユーザーがデータに関する質問をする際に使用する語彙と、データベーススキーマで使用される語彙の間にはギャップがあります。このギャップを埋めるために、Snowflakeはセマンティックモデルを採用しています。本記事では、Snowflakeのセマンティックモデルの仕様について調べたことをまとめます。
Cortex Analystとは?
ユーザーの問い合わせに対して構造化データの内容を元に回答を作成するアプリケーションの作成を手助けするものだそうです。構造化データを使ったRAGチャットアプリみたいなものを作るのに必要な機能を提供するような感じかと。
Cortex Analyst is a fully-managed, LLM-powered Snowflake Cortex feature that helps you create applications capable of reliably answering business questions based on your structured data in Snowflake.With Cortex Analyst, business users can ask questions in natural language and receive direct answers without writing SQL. Available as a convenient REST API, Cortex Analyst can be seamlessly integrated into any application.
セマンティックモデルとは?
セマンティックモデルは、データの意味を明確にし、ユーザーがデータをより直感的に理解できるようにするための手法です。この概念は、SnowflakeのCortex Analystだけでなく、他の多くのビジネスインテリジェンス(BI)ツールやデータ分析プラットフォームでも広く採用されています。セマンティックモデルを採用することでユーザがデータの構造や関係性を意識しなくて済みます。
Snowflakeにおけるセマンティックモデルの基本概念
セマンティックモデルは、物理的なデータベーステーブルやビューの上に構築された論理テーブルの集合です。各論理テーブルは、次のような論理カラムの集合で構成されます。
- Dimensions: カテゴリカルな値(例:state, user_type)
- Time Dimensions: 時間に関する値(例:sale_date, created_at)
- Measures: 数値的な値(例:revenue, impressions)
論理カラムは、基礎となる物理カラムへの参照や、複数の物理カラムを含む式で構成されます。例えば、SUM(売上個数)*単価
のような式を使用して売上額を計算することができます。
Snowflakeにおけるセマンティックモデルの構造
セマンティックモデルはYAML形式で記述されます。ドキュメントにあった例を載せます。
# セマンティックモデルの名前と説明
name: <name>
description: <string>
# セマンティックモデルは1つ以上の論理テーブルを含むことができます
tables:
- name: <name>
description: <string>
base_table:
database: <database>
schema: <schema>
table: <base table name>
dimensions:
- name: <name>
synonyms: <array of strings>
description: <string>
expr: <SQL expression>
data_type: <data type>
unique: <boolean>
time_dimensions:
- name: <name>
synonyms: <array of strings>
description: <string>
expr: <SQL expression>
data_type: <data type>
unique: <boolean>
measures:
- name: <name>
synonyms: <array of strings>
description: <string>
expr: <SQL expression>
data_type: <data type>
default_aggregation: <aggregate function>
filters:
- name: <name>
synonyms: <array of strings>
description: <string>
expr: <SQL expression>
ジョインの定義
複数のテーブルをひとつのセマンティックモデルに記載してその関係性を定義できます。特にスター・スキーマ構造において、ファクトテーブルとディメンションテーブル間のデータクエリが容易になります。
relationships:
- name: <string>
left_table: <string>
right_table: <string>
relationship_columns:
- left_column: <string>
right_column: <string>
join_type: <join_type>
relationship_type: <relationship_type>
実際に作ってみた
サンプルのデータセットを使って実際にセマンティックモデルを作成してみました。
セマンティックモデル作成の手助けをしてくれるsemantic model generatorなるものがあったので使ってみました。
データセットの作成:
デモとして書店の売上情報のデータを作成。
create database demo;
create schema book_store;
CREATE TABLE demo.book_store.Books (
BookID INT PRIMARY KEY,
Title VARCHAR(255),
AuthorID INT,
Genre VARCHAR(100),
Price DECIMAL(10, 2),
PublishedDate DATE
);
INSERT INTO demo.book_store.Books (BookID, Title, AuthorID, Genre, Price, PublishedDate) VALUES
(1, '吾輩は猫である', 1, '小説', 1200.00, '1905-01-01'),
(2, 'こころ', 1, '小説', 1500.00, '1914-01-01'),
(3, '羅生門', 2, '短編小説', 800.00, '1915-01-01');
CREATE TABLE demo.book_store.Authors (
AuthorID INT PRIMARY KEY,
Name VARCHAR(255),
BirthDate DATE,
Nationality VARCHAR(100)
);
INSERT INTO demo.book_store.Authors (AuthorID, Name, BirthDate, Nationality) VALUES
(1, '夏目漱石', '1867-02-09', '日本'),
(2, '芥川龍之介', '1892-03-01', '日本');
CREATE TABLE demo.book_store.Sales (
SaleID INT PRIMARY KEY,
BookID INT,
SaleDate DATE,
Quantity INT,
TotalAmount DECIMAL(10, 2)
);
INSERT INTO demo.book_store.Sales (SaleID, BookID, SaleDate, Quantity, TotalAmount) VALUES
(1, 1, '2024-01-15', 2, 2400.00),
(2, 2, '2024-01-16', 1, 1500.00),
(3, 3, '2024-01-17', 3, 2400.00),
(4, 1, '2024-01-18', 1, 1200.00),
(5, 2, '2024-01-19', 2, 3000.00),
(6, 3, '2024-01-20', 1, 800.00),
(7, 1, '2024-01-21', 3, 3600.00),
(8, 2, '2024-01-22', 1, 1500.00),
(9, 3, '2024-01-23', 2, 1600.00),
(10, 1, '2024-01-24', 2, 2400.00);
semantic model generatorをデプロイ
レポジトリのREADMEを元にデプロイ
セマンティックモデルを作る
create a new semantic modelを選ぶ
モデル名と対象のテーブルを選択する
「Join Editor」ボタンからJoinの定義を設定することも可能
右側のウィンドウでセマンティックモデルを使ったチャットアプリがすぐ試せるので、Joinしないとわからないような質問を投げてみる
いい感じに返ってきた
最終的にできたセマンティックモデル
name: my_model
tables:
- name: AUTHORS
description: Table to store information about authors, including their ID, name,
birthdate, and nationality.__
base_table:
database: DEMO
schema: BOOK_STORE
table: AUTHORS
primary_key:
columns:
- AUTHORID
dimensions:
- name: NAME
synonyms:
- ' '
description: List of renowned Japanese authors.__
expr: NAME
data_type: TEXT
sample_values:
- 夏目漱石
- 芥川龍之介
- name: NATIONALITY
synonyms:
- ' '
description: Nationality of the author.__
expr: NATIONALITY
data_type: TEXT
sample_values:
- 日本
- name: AUTHORID
synonyms:
- ' '
description: Unique identifier for each author.__
expr: AUTHORID
data_type: NUMBER
sample_values:
- '1'
- '2'
time_dimensions:
- name: BIRTHDATE
synonyms:
- ' '
description: Date of birth for authors.__
expr: BIRTHDATE
data_type: DATE
sample_values:
- '1867-02-09'
- '1892-03-01'
- name: BOOKS
description: The BOOKS table stores information about published books, including
their unique identifier, title, author, genre, price, and publication date.__
base_table:
database: DEMO
schema: BOOK_STORE
table: BOOKS
primary_key:
columns:
- BOOKID
dimensions:
- name: TITLE
synonyms:
- ' '
description: Japanese Book Titles__
expr: TITLE
data_type: TEXT
sample_values:
- 吾輩は猫である
- こころ
- 羅生門
- name: GENRE
synonyms:
- ' '
description: Genre of the book, such as novel or short story.__
expr: GENRE
data_type: TEXT
sample_values:
- 小説
- 短編小説
- name: BOOKID
synonyms:
- ' '
description: Unique identifier for each book in the database.__
expr: BOOKID
data_type: NUMBER
sample_values:
- '1'
- '2'
- '3'
- name: AUTHORID
synonyms:
- ' '
description: Unique identifier for each author.__
expr: AUTHORID
data_type: NUMBER
sample_values:
- '1'
- '2'
time_dimensions:
- name: PUBLISHEDDATE
synonyms:
- ' '
description: Date of publication for books.__
expr: PUBLISHEDDATE
data_type: DATE
sample_values:
- '1905-01-01'
- '1914-01-01'
- '1915-01-01'
measures:
- name: PRICE
synonyms:
- ' '
description: The price of the book.__
expr: PRICE
data_type: NUMBER
sample_values:
- '1200.00'
- '1500.00'
- '800.00'
- name: SALES
description: This table represents sales transactions of books, storing information
about each sale, including the sale ID, book ID, sale date, quantity sold, and
total amount.__
base_table:
database: DEMO
schema: BOOK_STORE
table: SALES
primary_key:
columns:
- SALEID
dimensions:
- name: BOOKID
synonyms:
- ' '
description: Unique identifier for each book in the sales database.__
expr: BOOKID
data_type: NUMBER
sample_values:
- '1'
- '2'
- '3'
time_dimensions:
- name: SALEDATE
synonyms:
- ' '
description: Date of sale.__
expr: SALEDATE
data_type: DATE
sample_values:
- '2023-01-15'
- '2023-01-16'
- '2023-01-17'
measures:
- name: SALEID
synonyms:
- ' '
description: Unique identifier for each sales record.__
expr: SALEID
data_type: NUMBER
sample_values:
- '1'
- '2'
- '3'
- name: QUANTITY
synonyms:
- ' '
description: Quantity of items sold.__
expr: QUANTITY
data_type: NUMBER
sample_values:
- '2'
- '1'
- '3'
- name: TOTALAMOUNT
synonyms:
- ' '
description: Total Sales Amount__
expr: TOTALAMOUNT
data_type: NUMBER
sample_values:
- '2400.00'
- '1500.00'
- '1200.00'
relationships:
- name: 売上と書籍
left_table: SALES
right_table: BOOKS
join_type: inner
relationship_type: one_to_one
relationship_columns:
- left_column: BOOKID
right_column: BOOKID
- name: 書籍と著者
left_table: BOOKS
right_table: AUTHORS
join_type: inner
relationship_type: one_to_one
relationship_columns:
- left_column: AUTHORID
right_column: AUTHORID
セマンティックモデルの作成のヒント
ドキュメントの内容を転記。
-
ビジネスドメインやトピックごとにYAMLファイルを整理する: セマンティックモデルを特定のビジネスドメインやトピックに合わせて構造化し、スコープを絞ることで、より効果的なデータ取得が可能になります。
-
エンドユーザーの視点から考える: ユーザーが質問しそうな主要な質問を特定し、それに答えるために必要なテーブルやカラムのみを含めます。
-
複雑な計算をキャプチャする: ビジネス固有のクエリを式(expr)に組み込みます。
-
広いテーブルを使用する: メトリックごとにカラムを持つテーブルを使用することで、各メトリックに関するセマンティック情報を提供します。
-
自動生成された説明をレビューする: セマンティックモデルジェネレーターを使用する場合、自動生成された説明を必ず確認し、必要に応じて修正します。
-
シンプルに始めて徐々に拡張する: 小規模なテーブルとカラムから始め、徐々にセマンティックモデルYAMLを拡張していきます。
-
検証済みクエリを含める: 検証済みクエリリポジトリ(VQR)を含めることで、結果の精度と信頼性を向上させます。
まとめ
AIを用いてデータを活用する際はデータソースの質が回答精度に大きく影響します。セマンティックモデルを適切に構築することで、データの理解とクエリの精度を大幅に向上させることが期待できます。この記事が何かの参考になれば幸いです。
参考URL