Top Insights(Snowflake ML 関数)

Top Insightsは、主要な要因分析のための ML 関数 であり、時間の経過に伴うメトリックの変化の要因を特定したり、さまざまな業種間でのメトリックの違いを説明したりするのに役立ちます。Top Insightsでは、分析するメトリックに関連して異なる動作を持つセグメントにデータセットを分割する決定木モデルを活用しています。数行の SQL で、Top Insightsを BI ワークフローに統合し、あらゆるメトリックの変化の原因となるセグメントを自動的に監視できます。

Top Insightsのユースケースには以下のようなものがあります。

  • 時系列分析: 時間の経過に伴うメトリックの変化の要因を特定します。たとえば、最近の収益不足の原因となっている場所、営業担当者、顧客、業種、その他の要因を自動的に特定します。

  • 業種分析: さまざまな業種間でメトリックが異なる要因について特定します。たとえば、米国と EMEA の国における新規ユーザー数の増加の違いの原因となっているユーザーセグメントを把握し、ターゲットを絞ったマーケティングキャンペーンの策定に役立てることができます。

Top Insightsについて

Top Insightsは、分析するメトリックに関連して異なる動作を持つセグメントにデータセットを分割する決定木モデルを使用します。アルゴリズムにより、コントロールグループとテストグループのメトリックにおけるセグメント間の違いが分析されます。

  • コントロールグループは、モデルがベースラインとして使用するデータポイントで構成されます。

  • テストグループは、分析対象のポイントから構成されます。

次に、Top Insightsでは、コントリビューターの組み合わせをいくつか生成し、その重要性と独自性に基づいてフィルタリングします。Top Insightsでは冗長なセグメントは返されません。

Top Insightsによる分析に適した候補データセットには通常、データをセグメント化するために使用される列やディメンションが多数含まれており、どのセグメントがメトリックに影響を与えるかを直感的に特定することは困難です。ディメンションは、カテゴリ(場所、市場セグメントなど)または連続(つまり、温度や出席者数などの定量的)にすることができます。

Top Insightsモデルはスキーマレベルのオブジェクトです。インスタンスは状態を保持しないため、必要なインスタンスは1つだけです。

Tip

ディメンションは、そのタイプに基づいてカテゴリまたは連続として推測されます。数値は連続ディメンションとして扱われ、文字列値とブール値はカテゴリとして扱われます。数値をカテゴリディメンションとして使用するには、それを文字列に変換します。

必要な権限

TOP_INSIGHTS インスタンスはスキーマレベルのオブジェクトです。そのため、インスタンスの作成に使用するロールには、インスタンスが作成されるスキーマに対する CREATE SNOWFLAKE.ML.TOP_INSIGHTS 権限が必要です。この権限は CREATE TABLE や CREATE VIEW のような他のスキーマ権限と類似しています。

インスタンスの所有者でない場合は、その GET_DRIVERS メソッドを呼び出すには、そのインスタンスに対する USAGE 権限を持っている必要があります。

Top Insightsの活用

クエリとパイプラインでTop Insightsを使用するには、まず TOP_INSIGHTS (SNOWFLAKE.ML) クラスのインスタンスを作成します。以下の SQL ステートメントは、 my_insights という名前のインスタンスを作成します。インスタンスの作成には引数は必要ありません。

CREATE SNOWFLAKE.ML.TOP_INSIGHTS IF NOT EXISTS my_insights();
Copy

インスタンスを作成したら、 GET_DRIVERS メソッドを使用して、キードライバー分析を実行するデータセットからキードライバーを抽出できます。入力データをすべて1つの部分(単一のテーブル、ビュー、またはクエリへの 参照)として渡し、入力データ内のメトリックとラベル列の名前を追加の引数として指定します。カテゴリディメンションと連続ディメンションはタイプによって推測されるため、明示的に指定する必要はありません。

CALL my_insights!get_drivers (
  INPUT_DATA => TABLE(my_table),
  LABEL_COLNAME => 'label',
  METRIC_COLNAMe => 'sales');
Copy

Top Insights用のデータの準備

Top Insightsを使用するには、コントロールグループの一部である行(ラベルは FALSE)とテストグループ内の行(ラベルは TRUE)を区別するブール値のラベル列があることを確認します。この列は通常、タイムスタンプや業種名など、データセット内の他の値から派生するため、これを行うにはビューを作成するのが一般的です。このビューは、分析対象外の列をフィルタリング処理するのにも適しています。

以下の例では、時系列分析のために、日付範囲に基づいてラベル列を持つビューを作成します。具体的には、最新月の記録を TRUE (テストデータ)としてラベル付けし、それ以前のすべての記録を FALSE (コントロールデータ)としてラベル付けします。Top Insightsでは、指定したメトリックの月ごとの変化における違いを説明する連続ディメンションとカテゴリディメンションを分析できます。

CREATE VIEW input_table_time_series_label (
  ds, metric, dim_country, dim_vertical, label ) AS
  SELECT
    ds,
    metric,
    dim_country,
    dim_vertical,
    ds >= dateadd(month, -1, current_date) AS label
  FROM input_table;
Copy

以下の例では、業種分析用に、国に基づいたラベル列が含まれるビューを作成しています。具体的には、 US 以外の国の記録には TRUE というラベルを付け、 USA の記録には FALSE というラベルを付けます。次に、Top Insightsは、これらの人口グループ間のメトリックの違いを説明する連続ディメンションとカテゴリディメンションを分析します。

CREATE VIEW input_table_vertical_label (
  ds, metric,  dim_country, dim_vertical, label ) AS
  SELECT
    ds,
    metric,
    dim_country,
    dim_vertical,
    dim_country <> 'USA' as label
  FROM input_table;
Copy

結果の解釈

Top Insightsでは、データから検出された該当のセグメントごとに行が返されます。各行には、セグメントのわかりやすい英語による説明が含まれており、複数の条件を含めることができます(たとえば、「COUNTRY = france, not VERTICAL = fashion, not VERTICAL = tech」で単一のセグメントを説明できるかもしれません。Top Insightsでは、各セグメントについて、コントロールグループとテストグループ間の変化にセグメントがどの程度貢献しているかを定量化する以下の値を提供しています。

出力列

説明

METRIC_CONTROL

特定のセグメントの制御期間にあるメトリックの合計値。

METRIC_TEST

特定のセグメントのテスト期間にあるメトリックの合計値。

CONTRIBUTION

メトリックの変化に対するセグメントの絶対的影響度。

RELATIVE_CONTRIBUTION

テストと制御の間のメトリック全体の変化に占めるセグメントの影響の割合。

GROWTH_RATE

セグメント内の制御グループの指標に対する、セグメント内のメトリックの変化の割合。

貢献度、相対的貢献度、および成長率がマイナスになる場合があり、これはセグメントがマイナスの影響を及ぼしていることを示します。

コストの考慮事項

Top Insightsを使用すると、コンピューティングコストが発生します。実行時間は、処理される行数とディメンション数に応じて変化します。Snowflakeのコンピューティングコストに関する一般的な情報については、 コンピューティングコストについて をご参照ください。

Top Insightsのパフォーマンスは、通常、メモリに収まる必要がある分析対象のすべてのデータをロードするために必要なサイズよりも大きいウェアハウスを使用しても向上しません。約1,000,000行および1,000列を超えるデータセットでは、メモリが不足する可能性があります。Snowflakeでは、標準的な大規模ウェアハウスではなく、Snowparkに最適化されたウェアハウスを使用することを推奨しています。Snowparkに最適化されたウェアハウスには、対応するサイズの標準ウェアハウスよりも多くのメモリがあります。

Top Insightsクラスのインスタンスはスキーマレベルのオブジェクトですが、データは保存されず、ストレージコストへの影響はごくわずかです。

以下の例は、時系列分析と業種分析におけるTop Insightsの使用方法を示しています。

時系列分析の例

この例では、2つの期間間のメトリックの差に寄与するセグメント、具体的には国と業種ディメンションが2021年以降のメトリックにどのように影響するかを調べます。

以下の SQL ステートメントを使用して、この例の合成データを含む入力テーブルを作成します。

CREATE OR REPLACE TABLE input_table(
  ds DATE, metric NUMBER, dim_country VARCHAR, dim_vertical VARCHAR);

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'usa' AS dim_country,
    'tech' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'usa' AS dim_country,
    'auto' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, seq4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'usa' AS dim_country,
    'fashion' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'usa' AS dim_country,
    'finance' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'canada' AS dim_country,
    'fashion' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'canada' AS dim_country,
    'finance' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'canada' AS dim_country,
    'tech' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'canada' AS dim_country,
    'auto' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'france' AS dim_country,
    'fashion' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'france' AS dim_country,
    'finance' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'france' AS dim_country,
    'tech' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 4, 1)) AS ds,
    UNIFORM(1, 10, RANDOM()) AS metric,
    'france' AS dim_country,
    'auto' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

-- Data for the test group

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 8, 1)) AS ds,
    UNIFORM(300, 320, RANDOM()) AS metric,
    'usa' AS dim_country,
    'auto' AS dim_vertica
  FROM TABLE(GENERATOR(ROWCOUNT => 365));

INSERT INTO input_table
  SELECT
    DATEADD(day, SEQ4(), DATE_FROM_PARTS(2020, 8, 1))  AS ds,
    UNIFORM(400, 420, RANDOM()) AS metric,
    'usa' AS dim_country,
    'finance' AS dim_vertical
  FROM TABLE(GENERATOR(ROWCOUNT => 365));
Copy

日付スタンプに基づいてラベル列を持つビューを作成します。

CREATE OR REPLACE VIEW input_view AS (
    SELECT
        metric,
        dim_country as country,
        dim_vertical as vertical,
        ds >= '2021-01-01' AS label
    FROM input_table
);
Copy

次に、 TOP_INSIGHTS インスタンスの GET_DRIVERS メソッドを呼び出して、このデータを分析します。

CREATE OR REPLACE SNOWFLAKE.ML.TOP_INSIGHTS my_insights_model()

CALL my_insights_model!GET_DRIVERS(
  INPUT_DATA => TABLE(input_view),
  LABEL_COLNAME => 'label',
  METRIC_COLNAME => 'metric'
)
Copy

出力は以下のようになります。

+---------------------------------------------------------------------+----------------+-------------+--------------+-----------------------+---------------+
| CONTRIBUTOR                                                         | METRIC_CONTROL | METRIC_TEST | CONTRIBUTION | RELATIVE_CONTRIBUTION |   GROWTH_RATE |
|---------------------------------------------------------------------+----------------+-------------+--------------+-----------------------+---------------|
| ["Overall"]                                                         |         128445 |      158456 |        30011 |         1             |  0.2336486434 |
| ["COUNTRY = usa"]                                                   |         116238 |      154574 |        38336 |         1.277398287   |  0.3298060875 |
| ["COUNTRY = usa","VERTICAL = finance"]                              |          64281 |       87423 |        23142 |         0.771117257   |  0.3600130676 |
| ["COUNTRY = usa","VERTICAL = auto"]                                 |          48930 |       66131 |        17201 |         0.5731565093  |  0.3515430206 |
| ["COUNTRY = usa","VERTICAL = tech"]                                 |           1543 |         503 |        -1040 |        -0.03465396021 | -0.6740116656 |
| ["COUNTRY = canada","VERTICAL = finance"]                           |           1538 |         482 |        -1056 |        -0.03518709806 | -0.6866059818 |
| ["COUNTRY = canada","VERTICAL = fashion"]                           |           1519 |         446 |        -1073 |        -0.03575355703 | -0.7063857801 |
| ["COUNTRY = france","VERTICAL = auto"]                              |           1534 |         460 |        -1074 |        -0.03578687814 | -0.7001303781 |
| ["COUNTRY = usa","not VERTICAL = auto","not VERTICAL = finance"]    |           3027 |        1020 |        -2007 |        -0.06687547899 | -0.6630327056 |
| ["COUNTRY = france","not VERTICAL = fashion","not VERTICAL = tech"] |           3100 |         962 |        -2138 |        -0.07124054513 | -0.6896774194 |
| ["COUNTRY = france","not VERTICAL = fashion"]                       |           4687 |        1456 |        -3231 |        -0.1076605245  | -0.689353531  |
| ["COUNTRY = france"]                                                |           6202 |        1947 |        -4255 |        -0.1417813468  | -0.68606901   |
| ["not COUNTRY = usa"]                                               |          12207 |        3882 |        -8325 |        -0.2773982873  | -0.6819857459 |
+---------------------------------------------------------------------+----------------+-------------+--------------+-----------------------+---------------+

注釈

入力データはランダムに生成されるため、結果は上記の結果とは異なります。

出力は CONTRIBUTION 順に並べられ、Overallセグメントが常に一番上に表示されます。CONTRIBUTOR 列にはセグメントを説明する文字列の配列が含まれ、残りの列は、そのセグメントがメトリックの値にどのように貢献するかを定量化します。詳細については、 結果の解釈 をご参照ください。

上の出力例では、米国にいること自体がメトリックに最も大きな影響を与えています。米国内の金融および自動車業界を基盤とする2つの追加セグメントも、大きな影響力を持っています。その後、セグメントの貢献はマイナスに転じます。

業種分析の例

この例では、 USA と EMEA の2つのリージョンの企業のクレジット使用状況を比較し、各セグメントのクレジット使用状況がリージョン間でどのように異なるかを理解することを目的としています。

以下の SQL ステートメントを使用して、この例の合成データを含む入力テーブルを作成します。

CREATE OR REPLACE TABLE vertical_input_table(
  region VARCHAR, industry VARCHAR, num_employee NUMBER, credits FLOAT);

INSERT INTO vertical_input_table
  SELECT
    'USA' as region,
    ['technology', 'finance', 'healthcare', 'consumer'][MOD(ABS(RANDOM()), 4)] as industry,
    UNIFORM(100, 10000, RANDOM()) as num_employee,
    UNIFORM(1000, 3000, RANDOM()) AS credits,
  FROM TABLE(GENERATOR(ROWCOUNT => 450));

INSERT INTO vertical_input_table
  SELECT
    'EMEA' as region,
    ['technology', 'finance', 'healthcare', 'consumer'][MOD(ABS(RANDOM()), 4)] as industry,
    UNIFORM(100, 10000, RANDOM()) as num_employee,
    UNIFORM(100, 5000, RANDOM()) AS credits,
  FROM TABLE(GENERATOR(ROWCOUNT => 350));
Copy

リージョンに基づいてラベル列を持つビューを作成します。

CREATE OR REPLACE VIEW vertical_input_view AS (
    SELECT
        credits,
        industry,
        num_employee,
        region = 'EMEA' AS label
    FROM vertical_input_table
);
Copy

次に、 TOP_INSIGHTS インスタンスの GET_DRIVERS メソッドを呼び出して、このデータを分析します。

CREATE OR REPLACE SNOWFLAKE.ML.TOP_INSIGHTS my_insights_model();

CALL my_insights_model!get_drivers(
  INPUT_DATA => TABLE(vertical_input_view),
  LABEL_COLNAME => 'label',
  METRIC_COLNAME => 'credits'
);
Copy

出力は以下のようになります。

+-------------------------------------------------------------------------------------------------------+----------------+-------------+--------------+-----------------------+------------------+|
| CONTRIBUTOR                                                                                           | METRIC_CONTROL | METRIC_TEST | CONTRIBUTION | RELATIVE_CONTRIBUTION |      GROWTH_RATE |
|-------------------------------------------------------------------------------------------------------+----------------+-------------+--------------+-----------------------+------------------|
| ["Overall"]                                                                                           |         896672 |      895326 |        -1346 |           1           |  -0.001501106313 |
| ["not INDUSTRY = consumer","NUM_EMPLOYEE <= 6248.0","NUM_EMPLOYEE > 4235.0"]                          |         141138 |       70337 |       -70801 |          52.601040119 |  -0.5016437813   |
| ["NUM_EMPLOYEE <= 6248.0","NUM_EMPLOYEE > 4235.0"]                                                    |         188770 |      127320 |       -61450 |          45.653789004 |  -0.3255284208   |
| ["not INDUSTRY = technology","NUM_EMPLOYEE <= 8670.0","NUM_EMPLOYEE > 7582.5"]                        |         100533 |       42925 |       -57608 |          42.799405646 |  -0.5730257726   |
| ["not INDUSTRY = consumer","NUM_EMPLOYEE <= 5562.5","NUM_EMPLOYEE > 4235.0"]                          |         103851 |       47052 |       -56799 |          42.198365527 |  -0.54692781     |
+-------------------------------------------------------------------------------------------------------+----------------+-------------+--------------+-----------------------+------------------+

注釈

入力データはランダムに生成されるため、結果は上記の結果とは異なります。

出力は CONTRIBUTION 順に並べられ、Overallセグメントが常に一番上に表示されます。CONTRIBUTOR 列にはセグメントを説明する文字列の配列が含まれ、残りの列は、そのセグメントがメトリックの値にどのように貢献するかを説明します。詳細については、 <instance_name>!GET_DRIVERS をご参照ください。

上の出力例では、セグメントが顧客の業界と従業員数に基づいていることがわかります。Top Insightsは、連続ディメンションに対してこのような範囲を自動的に選択します。一定規模の顧客(従業員数約4,000~6,000人)の場合、マイナスの影響が特に大きいようです。

現在の制限

  • 入力メトリックは、個々の観測値または集計値でなくてはなりません。

  • 25を超える値を持つカテゴリ機能の場合、Top Insightsは最も影響力のある上位25の値のみを使用してセグメントを作成します。

  • 1件のジョブで1億行以上を処理すると、Snowparkに最適化されたウェアハウスであってもメモリが枯渇する可能性があります。