Top Insights(Snowflake ML 函数)

Top Insights 是一个 ML 函数,用于关键驱动因素分析,帮助您识别指标随时间变化的驱动因素或解释不同垂直领域之间指标的差异。Top Insights 是由决策树模型驱动的,该模型将数据集划分为在您想要分析的指标方面表现不同的各个市场细分。通过几行 SQL,您可将 Top Insight 集成到 BI 工作流程中,以自动监控负责任何指标变化的市场细分。

Top Insights 的用例包括:

  • 时间序列分析: 识别指标随时间变化的驱动因素。例如,自动识别导致最近收入不足的地点、销售人员、客户、垂直因素和其他因素。

  • 垂直分析: 确定不同垂直领域中指标差异的驱动因素。例如,了解哪些用户市场细分导致美国和 EMEA 国家之间的新用户增长产生差异,以帮助制定有针对性的营销活动。

关于 Top Insights

Top Insights 使用决策树模型,该模型将数据集划分为在您想要分析的指标方面表现不同的各个市场细分。该算法分析了对照组和测试组之间的指标的区间差异。

  • 对照组由模型将用作基线的数据点组成。

  • 测试组由待分析的兴趣点组成。

然后,Top Insights 生成多个可能的贡献者组合,并根据其重要性和独特性对这些组合进行筛选。Top Insights 不会返回冗余的市场细分。

适合使用 Top Insights 进行分析的较好候选数据集通常具有大量的列或维度,用于对数据进行细分,这使得直观地识别哪些部分影响指标变得困难。维度可以是分类的(位置、市场细分等)或是连续维度(即定量的,例如温度或出席人数)。

Top Insights 模型是一个架构级对象。您仅需一个实例,因为该实例不保持任何状态。

小技巧

维度根据其类型被推断为分类或连续维度。数值被视为连续维度,而字符串和布尔值被视为分类。要将数值用作分类维度,请将其转换为字符串。

所需权限

TOP_INSIGHTS 实例是一个架构级对象。因此,您用于创建实例的角色必须对创建实例的架构具有 CREATE SNOWFLAKE.ML.TOP_INSIGHTS 权限。此权限类似于其他架构权限,如 CREATE TABLE 或 CREATE VIEW。

如果您不是实例的所有者,则必须对其具有 USAGE 权限,才能调用其 GET_DRIVERS 方法。

使用 Top Insights

要在查询和管道中使用 Top Insights,首先创建 TOP_INSIGHTS (SNOWFLAKE.ML) 类的实例。下面的 SQL 语句创建了一个名为 my_insights 的实例。创建实例不需要任何实参。

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

创建实例后,您可以使用 GET_DRIVERS 方法从您想要执行关键驱动分析的数据集中提取关键驱动因素。您将输入数据完整传递(引用 一个表、视图或查询),并以其他实参形式提供输入数据内的指标和标签列名称。分类和连续维度根据其类型进行推断,不需要明确指定。

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 = 法国,不是 VERTICAL = 时尚,不是 VERTICAL = 科技"可能描述一个单一的市场细分)。对于每个市场细分,Top Insights 提供以下值,以量化该市场细分对控制组和测试组之间变化的贡献度。

输出列

描述

METRIC_CONTROL

特定市场细分中对照期间的指标总值。

METRIC_TEST

特定市场细分中测试期间的指标总值。

CONTRIBUTION

该市场细分对指标变化的绝对影响。

RELATIVE_CONTRIBUTION

该市场细分的影响占测试组和对照组间的指标总体变化的比例。

GROWTH_RATE

该市场细分中指标的变化占对照组中对应市场细分指标的比例。

贡献、相对贡献和增长率可能为负,表明某个市场细分产生了负面影响。

成本注意事项

使用 Top Insights 会产生计算成本。执行时间与处理的行数和维度数量成比例。有关 Snowflake 计算成本的一般信息,请参阅 了解计算成本

对于加载所有正在分析的数据,使用比实际所需更大的仓库通常不会使 Top Insights 的性能得到显著改善,这些数据必须适合内存。超过约 1,000,000 行和 1,000 列的数据集可能会耗尽内存。Snowflake 建议使用经 Snowpark 优化的仓库,而不是更大的标准仓库。Snowpark-Optimized Warehouses 比相应大小的标准仓库具有更多内存。

虽然 Top Insights 类的实例是架构级对象,但它们不存储任何数据,并且对存储成本的影响微乎其微。

示例

以下示例演示了如何使用 Top Insights 进行时间序列分析和垂直分析。

时间序列分析示例

此示例查找导致两个时间段间指标差异的市场细分,特别是国家/地区和垂直领域维度在 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 排序,整个市场细分始终位列第一。CONTRIBUTOR 列包含描述该市场细分的字符串数组;其余列量化该市场细分对指标值的贡献度。有关更多详细信息,请参阅 解释结果

在上面的示例输出中,仅美国对该指标的影响最大。在美国,基于金融和汽车行业的两个额外领域也产生了巨大的影响。除此之外,市场细分的贡献值则为负数。

垂直领域分析示例

此示例比较了两个地区的(即 USA 和 EMEA)公司信用使用量,目的是了解每个市场细分的信用使用量在这两个地区之间的差异。

使用以下 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 排序,整个市场细分始终位列第一。CONTRIBUTOR 列包含一个描述该市场细分的字符串数组;其余列描述了该市场细分对指标值的贡献度。有关更多详细信息,请参阅 <instance_name>!GET_DRIVERS

在上面的示例输出中,您可以看到这些市场细分基于行业和客户拥有的员工数量。Top Insights 自动选择连续维度的范围。特定规模的客户(大约有 4,000 到 6,000 名员工)似乎对业务产生了过大的负面影响。

当前限制

  • 输入指标必须是单个观察或一个汇总。

  • 对于具有超过 25 个值的分类特征,Top Insights 仅使用前 25 个最具影响力的值来创建市场细分。

  • 在单个作业中处理超过 1 亿行可能会耗尽内存,即使使用 Snowpark-Optimized Warehouses 也是如此。

语言: 中文