ML.ENTITY_FEATURES_AT_TIME 関数

このドキュメントでは、ML.ENTITY_FEATURES_AT_TIME 関数について説明します。この機能を使用すると、特徴を取得する際に、複数のエンティティに対して複数のポイントインタイム カットオフを使用できます。これは、時間にセンシティブ データが含まれていると、時間の制約があるためです。データ漏洩を回避するには、モデルをトレーニングして推論を実行するときに、特定の時点の特徴を使用します。

この関数を使用して、複数のエンティティから特定の時点の特徴を取得します。たとえば、エンティティ 1 について 3 つの異なる時点より前に作成された特徴を取得し、エンティティ 2 について別の時点より前に作成された特徴を取得できます。特徴を取得するときに、すべてのエンティティに同じポイントインタイムのカットオフを使用するには、ML.FEATURES_AT_TIME 関数を使用します。

構文

ML.ENTITY_FEATURES_AT_TIME(
  { TABLE feature_table | (feature_query_statement) },
  { TABLE entity_time_table | (entity_time_query_statement) }
  [, num_rows => INT64][, ignore_feature_nulls => BOOL])

引数

ML.ENTITY_FEATURES_AT_TIME は次の引数を取ります。

  • feature_table: 特徴データを含む BigQuery テーブルの名前を指定する STRING 値。特徴テーブルには次の列が含まれている必要があります。

    • entity_id: 特徴に関連するエンティティの ID を含む STRING 列。
    • 1 つ以上の特徴列。
    • feature_timestamp: 特徴データの最終更新日を識別する TIMESTAMP 列。

    列名の大文字と小文字は区別されません。たとえば、entity_id の代わりに Entity_ID という名前の列を使用できます。

    特徴テーブルは、特徴ごとに 1 列ずつ、wide 形式にする必要があります。

  • feature_query_statement: 特徴データを返す GoogleSQL クエリを指定する STRING 値。このクエリは、feature_table と同じ列を返す必要があります。feature_query_statement 句でサポートされる SQL 構文については、GoogleSQL クエリ構文をご覧ください。

  • entity_time_table: エンティティ ID を特徴ルックアップ時間にマッピングする BigQuery テーブルの名前を指定する STRING 値。エンティティ時間テーブルには次の列が必要です。

    • entity_id: エンティティ ID を含む STRING 列。
    • time: エンティティ ID で表されるエンティティの特徴を選択する際に、カットオフ時間として使用する時点を識別する TIMESTAMP 列。

    列名の大文字と小文字は区別されません。たとえば、entity_id の代わりに Entity_ID という名前の列を使用できます。

    entity_time_table で識別されるテーブルは 100 MB 以下である必要があります。

  • entity_time_query_statement: エンティティ時間データを返す GoogleSQL クエリを指定する STRING 値。このクエリは、entity_time_table と同じ列を返す必要があります。entity_time_query_statement 句でサポートされる SQL 構文については、GoogleSQL クエリ構文をご覧ください。

  • num_rows: entity_time_table の各行について返す行数を指定する INT64 値。デフォルトは 1 です。

  • ignore_feature_nulls: 特徴列の NULL 値を、時間的に直前の同じエンティティの行からの特徴列の値に置き換えるかどうかを示す BOOL 値。たとえば、次の特徴テーブルとエンティティ時間テーブルの場合はこのようになります。

    特徴の表

    +-----------+------+------+--------------------------+
    | entity_id | f1   | f2   | feature_timestamp        |
    +-----------+------+------+--------------------------+
    | '2'       | 5.0  | 8.0  | '2022-06-10 09:00:00+00' |
    +-----------+------+------+--------------------------+
    | '2'       | 2.0  | 4.0  | '2022-06-10 12:00:00+00' |
    +-----------+------+------+--------------------------+
    | '2'       | 7.0  | NULL | '2022-06-11 10:00:00+00' |
    +-----------+------+------+--------------------------+
    

    エンティティ タイムテーブル

    +-----------+--------------------------+
    | entity_id | time                     |
    +-----------+--------------------------+
    | '2'       | '2022-06-11 10:00:00+00' |
    +-----------+--------------------------+
    

    このクエリを実行します。

    SELECT *
    FROM
      ML.ENTITY_FEATURES_AT_TIME(
        TABLE mydataset.feature_table,
        TABLE mydataset.entity_time_table,
        num_rows => 1,
        ignore_feature_nulls => TRUE);
    

    次のような出力が得られます。ここで、タイムスタンプが '2022-06-10 12:00:00+00' であるエンティティ ID 2 の行の f2 値が、タイムスタンプが NULL である行の '2022-06-11 10:00:00+00' 値を置き換えます。

    +-----------+------+------+--------------------------+
    | entity_id | f1   | f2   | feature_timestamp        |
    +-----------+------+------+--------------------------+
    | '2'       | 7.0  | 4.0  | '2022-06-11 10:00:00+00' |
    +-----------+------+------+--------------------------+
    

    使用可能な置換値がない場合(たとえば、そのエンティティ ID の前の行がない場合)は、NULL 値が返されます。

    デフォルトは FALSE です。

出力

ML.ENTITY_FEATURES_AT_TIME は、特定の時点のカットオフ条件を満たす入力テーブルの行を返します。feature_timestamp 列はエンティティ タイムテーブルの time 列のタイムスタンプを示します。

同じエンティティの特徴を取得する複数の時点を指定できるため、特徴とエンティティの時刻テーブルのタイムスタンプに応じて重複する行を返し、num_rows を指定します。たとえば、エンティティ ID 1 の特徴テーブルの唯一の行に 2022-06-11 10:00:00+00 のタイムスタンプが付けられており、エンティティ タイムテーブルにエンティティ ID 1 の行が 2 つあり、どちらもタイムスタンプが後である場合、この関数は出力には、エンティティ ID 1 に対して同じ特徴データを持つ 2 つの行が含まれます。

次のいずれかの条件に該当する場合:

  • エンティティ タイムテーブルのエンティティ ID が特徴テーブルに見つかりません。
  • エンティティ ID がエンティティ タイムテーブルのものと一致する特徴テーブルの行が、ポイントインタイムの条件を満たしていません。

この場合、関数はそのエンティティ タイムテーブルの行の出力を返しません。

例 1

この例では、mydataset.entity_time_table で識別されるタイムスタンプより前に作成または更新された特徴のみを使用して、モデルを再トレーニングする方法を示します。

CREATE OR REPLACE
  `mydataset.mymodel` OPTIONS (WARM_START = TRUE)
AS
SELECT * EXCEPT (feature_timestamp, entity_id)
FROM
  ML.ENTITY_FEATURES_AT_TIME(
    TABLE `mydataset.feature_table`,
    TABLE `mydataset.entity_time_table`,
    num_rows => 1,
    ignore_feature_nulls => TRUE);

例 2

この例では、mydataset.entity_time_table で識別されるタイムスタンプの前に作成または更新された特徴に基づいて、モデルから予測を取得する方法を示します。

SELECT
  *
FROM
  ML.PREDICT(
    MODEL `mydataset.mymodel`,
    (
      SELECT * EXCEPT (feature_timestamp, entity_id)
      FROM
        ML.ENTITY_FEATURES_AT_TIME(
          TABLE `mydataset.feature_table`,
          TABLE `mydataset.entity_time_table`,
          num_rows => 1,
          ignore_feature_nulls => TRUE)
    )
  );

例 3

次の工夫された例は、関数の出力を確認するために使用できます。

WITH
  feature_table AS (
    SELECT * FROM UNNEST(
      ARRAY<STRUCT<entity_id STRING, f_1 FLOAT64, f_2 FLOAT64, feature_timestamp TIMESTAMP>>[
        ('id1', 1.0, 1.0, TIMESTAMP '2022-06-10 12:00:00+00'),
        ('id2', 12.0, 24.0, TIMESTAMP '2022-06-11 12:00:00+00'),
        ('id1', 11.0, NULL, TIMESTAMP '2022-06-11 12:00:00+00'),
        ('id1', 6.0, 12.0, TIMESTAMP '2022-06-11 10:00:00+00'),
        ('id2', 2.0, 4.0, TIMESTAMP '2022-06-10 12:00:00+00'),
        ('id2', 7.0, NULL, TIMESTAMP '2022-06-11 10:00:00+00')])
  ),
  entity_time_table AS (
    SELECT * FROM UNNEST(
      ARRAY<STRUCT<entity_id STRING, time TIMESTAMP>>[
        ('id1', TIMESTAMP '2022-06-12 12:00:00+00'),
        ('id2', TIMESTAMP '2022-06-11 10:00:00+00'),
        ('id1', TIMESTAMP '2022-06-10 13:00:00+00')])
  )
SELECT *
FROM
  ML.ENTITY_FEATURES_AT_TIME(
    TABLE feature_table, TABLE entity_time_table, num_rows => 1, ignore_feature_nulls => TRUE);