3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

前書き

ポーラ・オルビスHDでデータエンジニアをしている井山と申します。

みなさん、Snowflake使ってますか?

弊社でも最近、いろいろなデータ活用に向けてSnowflakeの利用を始めたところです。
SnowflakeにはAIを活用した機能がたくさんありますよね。
直近だと Snowflake Intelligence がGAされて話題になりました。

ちょこちょこ触ってみて「これは便利だなぁ…」と思いつつ、まだ本格的には利用できていない状況です。
今回は、以下の機能について実際に触りながら試してみた内容を記事にしたいと思います。

  • Cortex Analyst
  • Cortex Data Agent
  • Snowflake Intelligence
  • Sematic View(Model)
  • CortexSearch(チョットダケ)

前提

利用データについて

今回は化粧品業界に関しての株価データ(オープンデータで利用できるもの)とをSnowflakeに突っ込み、いい感じに分析・可視化出来るところまでやってみたいと思います。

※ロールなどの設定に関しては今回は省略します

各種利用サービスについて

詳細は公式のドキュメントを参照した方が早いと思いますが、ざっくり以下のような理解をしています。

コンポーネント 役割
Semantic Model YAML形式でビジネス用語とDB定義をマッピング。ステージに配置
Semantic View Semantic Modelと同等だがDBオブジェクトとして管理。GRANT可能
Cortex Search 非構造化データのベクトル検索・RAG
Cortex Analyst 自然言語→SQL変換・実行
Cortex Data Agent 質問を解析し、Analyst/Searchを適切にルーティング
Snowflake Intelligence チャット、可視化、Explore、履歴管理

※今回 Cortex Search はメインでは扱いませんが、公開されているIR情報のドキュメントなどを試しに入れてみてIntelligenceに参照させたりしたのでおまけで最後につけています。

データの準備

元となるデータの準備からです。
今回は yfinance を利用してそれらを利用したいと思います。
Yahoo APIを利用してのデータ取得になるので、今回のデモ作成のみに限定して利用します。

※利用規約の確認
https://legal.yahoo.com/us/en/yahoo/terms/product-atos/apiforydn/index.html
https://legal.yahoo.com/us/en/yahoo/terms/otos/index.html

この記事で使っている株価データは、yfinance を使って一度だけ取得したものです。
自動で取得を継続する等、業務システムへの利用はないものとなります。

yfinance は Yahoo! の公式 API ではないため、あくまで 個人的な学習・技術検証の範囲で利用に限定し、記事内で扱うデータは再配布せず、加工後の可視化のみを掲載しています。

データは以下の形式のデータ取り込みます。

company_info

カラム名 データ型 説明
ticker VARCHAR(10) 証券コード(例:4911.T)
company_name VARCHAR(100) 企業名(日本語)
long_name VARCHAR(200) 正式企業名(英語)
sector VARCHAR(100) セクター
industry VARCHAR(100) 業界
market_cap BIGINT 時価総額
enterprise_value BIGINT 企業価値
employees INTEGER 従業員数
website VARCHAR(500) ウェブサイトURL
business_summary TEXT 事業概要
country VARCHAR(50)
currency VARCHAR(10) 通貨
exchange VARCHAR(50) 取引所
forward_pe DECIMAL(8,2) 予想PER
trailing_pe DECIMAL(8,2) 実績PER
price_to_book DECIMAL(8,2) PBR(株価純資産倍率)
dividend_yield DECIMAL(8,6) 配当利回り
payout_ratio DECIMAL(8,4) 配当性向
beta DECIMAL(8,4) ベータ値
fifty_two_week_high DECIMAL(10,2) 52週高値
fifty_two_week_low DECIMAL(10,2) 52週安値
created_at TIMESTAMP データ作成日時

stock_historical_data

カラム名 データ型 説明
ticker VARCHAR(10) 証券コード
company_name VARCHAR(100) 企業名
data_date DATE データ日付
open_price DECIMAL(10,2) 始値
high_price DECIMAL(10,2) 高値
low_price DECIMAL(10,2) 安値
close_price DECIMAL(10,2) 終値
volume BIGINT 出来高
dividends DECIMAL(8,4) 配当金
stock_splits DECIMAL(8,4) 株式分割比率
price_change DECIMAL(8,2) 前日比価格変動
price_change_pct DECIMAL(8,4) 前日比変動率(%)
volume_ma_5 DECIMAL(15,2) 5日移動平均出来高
price_ma_5 DECIMAL(10,2) 5日移動平均価格
price_ma_25 DECIMAL(10,2) 25日移動平均価格
volatility_20d DECIMAL(8,4) 20日ボラティリティ
daily_range DECIMAL(8,2) 日次価格レンジ(高値-安値)
daily_range_pct DECIMAL(8,4) 日次価格レンジ率(%)
created_at TIMESTAMP データ作成日時

Sematinc View と Cortex Analyst の準備

まずは Semantic View の定義について。

新しいスキーマレベルオブジェクトである セマンティックビュー に、セマンティックなビジネスコンセプトを直接データベースに格納することができます。ビジネス・メトリクスを定義し、ビジネス・エンティティとその関係をモデリングできます。物理データにビジネス上の意味を付加することで、セマンティックビューはデータ主導の意思決定を強化し、エンタープライズアプリケーション全体で一貫したビジネス定義を提供します。

要するにビジネス用語とデータベースの翻訳レイヤーを定義できる機能で、これを定義することで以下が実現できるものだと認識しています。

  • メトリクス計算の一貫性担保(単一の真実)
  • LLMが自然言語クエリを理解しやすくなる(Cortex Analyst利用時)
  • 物理データが変わっても、一貫したビジネス定義を後続のBI・アプリで利用可能
物理テーブル(raw data)
    ↓
セマンティックビュー(ビジネス定義層)
    ↓
各種アプリ・BI・AI

Seamtic View自体の定義には以下の3つの要素が存在しています

概念 定義 具体例 集約レベル 用途
ファクト 行レベルの数値データ。個別イベントの「いくら」「いくつ」 単価、数量、原価、取引金額 行単位(集約前) メトリクス計算の材料
メトリクス ファクトを集約した KPI。ビジネス成果を測る指標 総売上高 SUM(単価×数量)、利益率 (売上-原価)/売上 集約後 意思決定・レポート
ディメンジョン カテゴリ属性。メトリクスを切り分けるフィルタ軸 顧客名、商品カテゴリ、地域、日付 - グループ化・フィルタ

※ファクトは素材、メトリクスは料理、ディメンジョンは切り分け方。

今回のSemantic Viewは以下のような定義を行いました。
(UIからでもそれぞれ追加していけると思いますが、今回は yml ファイルで定義したものをアップロードしています)

以下は実際に定義しているものを少し簡略化したものになります。


name: COSMETICS_IR_ANALYSIS
description: 化粧品業界4社の株価・IR情報を分析するセマンティックモデル

# ===================
# テーブル定義
# ===================
tables:
  # --- 企業情報テーブル ---
  - name: COMPANY_INFO
    description: 企業基本情報・財務指標
    base_table:
      database: IR_ANALYSIS
      schema: STOCK_DATA
      table: COMPANY_INFO

    # 分析軸(グループ化・絞り込み用)
    dimensions:
      - name: COMPANY_NAME
        synonyms: [会社名, 企業名, 銘柄名]
        description: 企業名
        expr: company_name
        data_type: VARCHAR(100)
        sample_values: [資生堂, 花王, コーセー, ポーラ・オルビスHD]

      - name: TICKER
        synonyms: [ティッカー, 証券コード]
        expr: ticker
        data_type: VARCHAR(10)

    # 数値項目(集計対象)
    facts:
      - name: FORWARD_PE
        synonyms: [PER, 予想PER, 株価収益率, 割安, 割高]
        description: 予想PER。10倍未満=割安、20倍超=割高
        expr: forward_pe
        data_type: NUMBER(8,2)
        default_aggregation: avg

      - name: MARKET_CAP
        synonyms: [時価総額, 企業価値]
        expr: market_cap
        data_type: NUMBER(38,0)
        default_aggregation: sum

    primary_key:
      columns: [TICKER]

  # --- 株価履歴テーブル ---
  - name: STOCK_HISTORICAL_DATA
    description: 日次株価データ(OHLCV、移動平均、ボラティリティ)
    base_table:
      database: IR_ANALYSIS
      schema: STOCK_DATA
      table: STOCK_HISTORICAL_DATA

    dimensions:
      - name: COMPANY_NAME
        synonyms: [会社名, 企業名]
        expr: company_name
        data_type: VARCHAR(100)

    # 時間軸
    time_dimensions:
      - name: DATA_DATE
        synonyms: [日付, 取引日, いつ]
        expr: data_date
        data_type: DATE

    facts:
      - name: CLOSE_PRICE
        synonyms: [株価, 終値, 現在価格]
        expr: close_price
        data_type: NUMBER(10,2)
        default_aggregation: avg

      - name: VOLUME
        synonyms: [出来高, 取引量]
        expr: volume
        data_type: NUMBER(38,0)
        default_aggregation: sum

      - name: PRICE_CHANGE_PCT
        synonyms: [変動率, パフォーマンス, リターン]
        expr: price_change_pct
        data_type: NUMBER(8,4)
        default_aggregation: avg

    # 定義済みフィルター
    filters:
      - name: recent_30days
        synonyms: [直近30日, 過去30日]
        expr: data_date >= DATEADD(day, -30, CURRENT_DATE())

      - name: current_year
        synonyms: [今年, 本年]
        expr: YEAR(data_date) = YEAR(CURRENT_DATE())

    # 定義済みメトリクス
    metrics:
      - name: AVG_CLOSE_PRICE
        synonyms: [平均株価, 平均価格]
        expr: avg(close_price)

      - name: TOTAL_VOLUME
        synonyms: [合計出来高]
        expr: sum(volume)

    primary_key:
      columns: [TICKER, DATA_DATE]

# ===================
# テーブル間リレーション
# ===================
relationships:
  - name: STOCK_TO_COMPANY
    left_table: STOCK_HISTORICAL_DATA
    right_table: COMPANY_INFO
    relationship_columns:
      - left_column: TICKER
        right_column: TICKER
    relationship_type: many_to_one
    join_type: left_outer

# ===================
# 検証済みクエリ(精度向上用サンプル)
# ===================
verified_queries:
  - name: avg_price_30days
    question: 資生堂の直近30日間の平均株価は?
    sql: |
      SELECT avg(close_price) as avg_price
      FROM IR_ANALYSIS.STOCK_DATA.STOCK_HISTORICAL_DATA
      WHERE company_name = '資生堂'
        AND data_date >= DATEADD(day, -30, CURRENT_DATE())
    use_as_onboarding_question: true

  - name: volume_ranking
    question: 2024年の出来高合計を企業ごとに比較
    sql: |
      SELECT company_name, sum(volume) as total_volume
      FROM IR_ANALYSIS.STOCK_DATA.STOCK_HISTORICAL_DATA
      WHERE YEAR(data_date) = 2024
      GROUP BY company_name
      ORDER BY total_volume DESC
    use_as_onboarding_question: true
用語 説明
dimension 分析軸。グループ化や絞り込みに使う項目(企業名、地域など)
time_dimension 時間に関する分析軸。期間指定に使用(日付、年月など)
fact 数値項目。集計対象となる値(株価、売上、数量など)
filter 事前定義されたWHERE条件(直近30日、今年など)
metric 事前定義された計算式(平均株価、合計出来高など)
synonyms 同義語。自然言語の揺らぎに対応(「株価」「終値」「現在価格」→同一カラム)

先ほど作成したSematic ViewのYAMLを利用したCortexAlanystを定義します。

image.png

今回はYAMLファイルで作成したのでアップロードするだけで完了となります。
※何かしら定義間違いなどがあった場合はこちらの画面でエラーが表示されます。

この時点で画面の右側に Playground が表示されて実際に試してみることができるようになっていますね。
せっかくなのでやってみましょう。

Q:どんなデータが利用できますか?

image.png

Q:各社の直近30日の平均終値はいくらですか?

image.png

このように Cortex Analyst に対して自然言語でデータに対して問い合わせが可能になっています。
この時点でもかなり使えそうな印象がありますが、ここからさらに Snowflake Intelligence を用いた設定を行ってみましょう。

Snowflake Intelligence の設定

Snowflake Intelligenceの設定については公式のドキュメントを参考に実施します。

-- データベースの作成
CREATE DATABASE IF NOT EXISTS snowflake_intelligence;
GRANT USAGE ON DATABASE snowflake_intelligence TO ROLE PUBLIC;

-- Agent格納用のスキーマの作成
CREATE SCHEMA IF NOT EXISTS snowflake_intelligence.agents;
GRANT USAGE ON SCHEMA snowflake_intelligence.agents TO ROLE PUBLIC;

-- Agent作成の権限付与
GRANT CREATE AGENT ON SCHEMA snowflake_intelligence.agents TO ROLE <role>;

今回は一般ナレッジエージェントではなく、Cortex Analystのセマンティックビューを利用するエージェントを作成します。
https://docs.snowflake.com/ja/user-guide/snowflake-cortex/snowflake-intelligence#create-an-agent-that-uses-a-semantic-view-in-cortex-analyst

image.png

ここからエージェントの各種設定を行います。

image.png

About 部分
こちらは基本的なエージェントの説明とサンプル質問などを登録できるので以下のように設定しています。

image.png

Tool部分

image.png

Description部分については、 Generate with Cortex を利用して自動生成されたものを設定しています。

どういった設定になった?(日本語訳)

テーブル1: COMPANY_INFO
データベース: IR_ANALYSIS、スキーマ: STOCK_DATA
日本の大手化粧品企業4社(資生堂、花王、コーセー、ポーラ・オルビスホールディングス)の基礎的な財務指標および企業情報を格納。
企業プロファイルとバリュエーション指標のマスターリファレンスとして機能する。
化粧品業界セクターにおける比較財務分析、バリュエーション評価、投資意思決定に必要なデータを提供。
カラム一覧: TICKER(証券コード)、COMPANY_NAME(企業名)、INDUSTRY(業種分類)、SECTOR(市場セクター)、BETA(市場感応度リスク指標)、DIVIDEND_YIELD(年間配当利回り)、FORWARD_PE(予想PER)、MARKET_CAP(時価総額)、PRICE_TO_BOOK(PBR)、TRAILING_PE(実績PER)

テーブル2: STOCK_HISTORICAL_DATA
データベース: IR_ANALYSIS、スキーマ: STOCK_DATA
OHLC価格、出来高、テクニカル指標、算出指標を含む包括的な日次取引データを格納。
過去の株価パフォーマンス分析用。市場の動きと取引パターンを時系列で記録。
化粧品4社における移動平均線やリスク指標を通じたトレンド分析、パフォーマンス比較、ボラティリティ評価、テクニカル分析を可能にする。
カラム一覧: TICKER(証券コード - COMPANY_INFOと連携)、DATA_DATE(取引日)、COMPANY_NAME(企業名)、MONTH(月)、QUARTER(四半期)、YEAR(年)、CLOSE_PRICE(終値)、DAILY_RANGE(日中値幅)、DAILY_RANGE_PCT(日中値幅率)、HIGH_PRICE(高値)、LOW_PRICE(安値)、OPEN_PRICE(始値)、PRICE_CHANGE(価格変動)、PRICE_CHANGE_PCT(騰落率)、PRICE_MA_25(25日移動平均)、PRICE_MA_5(5日移動平均)、VOLATILITY_20D(20日ボラティリティ)、VOLUME(出来高)

設計理由:
このセマンティックビューは、日本の化粧品業界に対する包括的な分析機能を提供するため、
基礎的な企業データと過去の株価パフォーマンスを統合している。
COMPANY_INFOテーブルは基礎的な財務指標と企業プロファイルを提供し
STOCK_HISTORICAL_DATAは詳細な取引データとテクニカル指標を提供する。
TICKERカラムを介したテーブル間の関連付けにより
ファンダメンタルのバリュエーション指標と市場パフォーマンストレンドのクロス分析が可能となる。
この構造は、化粧品大手4社における比較バリュエーション分析
パフォーマンスベンチマーキング、リスク評価、投資意思決定などの多様な分析ユースケースをサポートする。

説明:
COSMETICS_ANALYSISセマンティックビューは
IR_ANALYSISデータベース内で日本の化粧品大手4社(資生堂、花王、コーセー、ポーラ・オルビスホールディングス)の
株式市場および財務分析を統合的に提供する。
COMPANY_INFOの基礎的財務指標とSTOCK_HISTORICAL_DATAの包括的な過去取引データを組み合わせ
バリュエーション指標、市場パフォーマンス、リスク指標の比較分析を可能にする。
株価トレンド、ボラティリティ分析、配当利回り比較、テクニカル指標評価など様々な分析クエリをサポート。
ユーザーは、基礎的な企業データと詳細な日次取引情報の両方を統合したデータセットを通じて
企業間ベンチマーキング、投資機会評価、市場行動パターン分析を実行できる。

ここの具体的な挙動 ( generate with cortex ) についてはAgentsやCortexAnalystのページから見つけることができず...(私の探し方が悪い気もするのですが)
ただ、Snowflake Horizon Catalog などでは以下に記載がありました。

今回でいえば Semantic View を設定しているのでそちらを内容をベースに推論した結果を出してくれているのかなと勝手に思っています :bow:

Orchestration

こちらでは 利用する Model や Orchestration instructions、Response instructions などの設定が可能です(Budgetについての設定も可能ですが今回は割愛)

公式ドキュメントの例として
https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-rest-api

response は

"You will respond in a friendly but concise manner"

orchestration は

"For any query related to revenue we should use Analyst; For all policy questions we should use Search"

などを定義するようです。
今回は以下のように設定しています。

image.png

使ってみよう

これで大枠の設定が完了したので、実際に Intelligence の画面で実行してみましょう。

image.png

まずは株価データについての簡単な可視化を依頼してみます。

Intelligence.gif

いい感じに可視化してくれていますね!

今回、裏でIR資料についてのドキュメントも Cortex Search で参照できるように登録してみたので、そちらも合わせて実施できないか依頼してみましょう。

Intelligence2.gif

こちらも Agent が Cortex Search を利用してデータを取得してくれていますね。

また実行後のグラフ化されたデータについては、元となるデータのテーブル表示や、 Explore を実行することで、SQLなども提示されているので、特に非エンジニアの方には使い勝手が良さそうだなと感じています。

image.png

まとめ

良かった点

Semantic View さえ整備すれば、非エンジニアでもチャットで質問→可視化→SQL確認という流れを実現できます。
「SQLは詳しくないけどデータは見たい」という層に対して、大きな価値を提供できると感じました。

課題

YAML を書く作業自体は難しくありませんが、本質的なハードルは、その前提となる「ビジネス用語の統一」や「メトリクス定義の合意形成」が大変そうと感じています。

特に弊社のようなHD体制では、事業会社ごとに同じ言葉でも定義や粒度が異なるケースも多く、この合意形成には時間がかかりそうです。

ただ、これはデータガバナンス上いずれ向き合うべき課題です。Semantic View を作る過程でそれが明文化・可視化されると考えれば、むしろ良い機会とも捉えています。

また、現状の Snowflake の機能としてのLLM利用は基本的にクロスリージョンでの利用となる認識でいます。
会社や利用するデータによってはガバナンスなどの問題でこのあたりの機能の利用が難しいパターンもあると考えています。

今後の検討事項

  • 実際の社内データでの欠損・表記揺れへの対応
  • 複雑な集計やJOINが絡むクエリでの精度検証
  • verified_queries の充実による精度向上
  • etc...

これらの課題はありつつも、Snowflake の AI 機能を活用したデータ利活用は積極的に推進していきたいと考えています!!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?