ML.FEATURES_AT_TIME 関数

このドキュメントでは、ML.FEATURES_AT_TIME 関数について説明します。この関数を使用すると、特徴を取得する際にすべてのエンティティに対して特定の時点でのカットオフを使用できます。特徴に時間的制約があるデータが含まれている場合、特徴は時間的な依存性を持つためです。データ漏洩を回避するには、モデルをトレーニングして推論を実行するときに、特定の時点の特徴を使用します。

この関数を使用して、特徴の取得時にすべてのエンティティに同じ特定の時点でのカットオフを使用します。複数のエンティティに対して複数の特定の時点での特徴を取得するには、ML.ENTITY_FEATURES_AT_TIME 関数を使用します。

構文

ML.FEATURES_AT_TIME(
   { TABLE feature_table | (query_statement) }
   [, time => TIMESTAMP][, num_rows => INT64][, ignore_feature_nulls => BOOL])

引数

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

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

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

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

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

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

  • time: 特徴データのカットオフとして使用する特定の時点を指定する TIMESTAMP 値。feature_timestamp 列の値が time 値と同じかそれ以前の行のみが返されます。デフォルトは CURRENT_TIMESTAMP 関数の値です。

  • num_rows: 各エンティティ ID に対して返す行数を指定する 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' |
    +-----------+------+------+--------------------------+
    

    このクエリを実行すると:

    SELECT *
    FROM
      ML.FEATURES_AT_TIME(
        TABLE mydataset.feature_table,
        time => '2022-06-11 10:00:00+00',
        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.FEATURES_AT_TIME 関数は、特定の時点のカットオフ条件を満たす入力テーブルの行を返します。feature_timestamp 列は、time 引数の入力であったタイムスタンプを示します。

例 1

次の例は、2023-01-01 12:00:00+00 より前に作成または更新された特徴のみを使用してモデルを再トレーニングする方法を示しています。

CREATE OR REPLACE
  `mydataset.mymodel` OPTIONS (WARM_START = TRUE)
AS
SELECT * EXCEPT (feature_timestamp, entity_id)
FROM
  ML.FEATURES_AT_TIME(
    TABLE `mydataset.feature_table`,
    time => '2023-01-01 12:00:00+00',
    num_rows => 1,
    ignore_feature_nulls => TRUE);

例 2

次の例は、2023-01-01 12:00:00+00 より前に作成または更新された特徴に基づいて、モデルから予測を取得する方法を示しています。

SELECT
  *
FROM
  ML.PREDICT(
    MODEL `mydataset.mymodel`,
    (
      SELECT * EXCEPT (feature_timestamp, entity_id)
      FROM
        ML.FEATURES_AT_TIME(
          TABLE `mydataset.feature_table`,
          time => '2023-01-01 12:00:00+00',
          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')])
  )
SELECT *
FROM
  ML.FEATURES_AT_TIME(
    TABLE feature_table,
    time => '2022-06-12 10:00:00+00',
    num_rows => 1,
    ignore_feature_nulls => TRUE);