時系列特徴量テーブルを使用したポイントインタイムのサポート

この記事では、ポイントインタイムの正確性を使用して、ラベル観測が記録された時点の特徴値を正確に反映するトレーニング データセットを作成する方法について説明します。 これは、ラベルが記録された時点では利用できなかったモデルトレーニングの特徴値を使用する場合に発生する データ漏洩を防ぐために重要です。 このタイプのエラーは検出が難しく、モデルのパフォーマンスに悪影響を与える可能性があります。

時系列特徴テーブルには、トレーニングデータセットの各行が行のタイムスタンプの時点で最新の既知の特徴値を表すことを保証するタイムスタンプキー列が含まれています。 時系列データ、イベントベースのデータ、時間集計データなど、時間の経過と共に特徴値が変化する場合は常に、時系列特徴テーブルを使用する必要があります。

次の図は、タイムスタンプ キーの使用方法を示しています。 各タイムスタンプに記録された特徴値は、そのタイムスタンプより前の最新の値であり、枠線で囲まれたオレンジ色の円で示されています。 値が記録されていない場合、フィーチャ値は null です。 詳細については、 time series 特徴量テーブルの仕組みを参照してください。

異なる時間に到着した機能値。

  • Databricks Runtime13.3LTS 以降では、主キーとタイムスタンプDelta Unity Catalogキーを持つ 内の テーブルを時系列特徴量テーブルとして使用できます。

  • ポイントインタイム ルックアップのパフォーマンスを向上させるために、 Databricksでは時系列テーブルに流動クラスタリング(databricks-feature-engineering 0.6.0 以降の場合) またはZ-Ordering (databricks-feature-engineering 0.6.0 以下の場合) を適用することをお勧めします。

  • ポイントインタイムルックアップ機能は、"タイムトラベル" と呼ばれることもあります。 Databricks Feature Store のポイントインタイム機能は 、Delta Lake タイム トラベルとは関係ありません。

時系列特徴量テーブルの仕組み

次の機能テーブルがあるとします。 このデータは、 サンプル ノートブックから取得されます。

テーブルには、部屋の温度、相対湿度、周囲光、二酸化炭素を測定するセンサーデータが含まれています。 グラウンドトゥルーステーブルは、部屋に人がいたかどうかを示します。 各テーブルには、主キー ('room') とタイムスタンプキー ('ts') があります。 わかりやすくするために、主キーの単一の値 ('0') のデータのみが表示されます。

フィーチャ テーブル データの例

次の図は、タイムスタンプキーを使用して、トレーニングデータセットの特定の時点の正確性を確保する方法を示しています。 フィーチャ値は、AS OF 結合を使用して、主キー (図には示されていません) とタイムスタンプ キーに基づいて照合されます。 AS OF 結合により、タイムスタンプの時点での特徴の最新値がトレーニング セットで使用されます。

ポイントインタイムの仕組み

図に示すように、トレーニング データセットには、観測されたグラウンド トゥルースのタイムスタンプより前の各センサーの最新の特徴値が含まれています。

タイムスタンプキーをアカウントに取り込まずにトレーニングデータセットを作成した場合、次の特徴値と観測されたグラウンドトゥルースを含む行が存在する可能性があります。

temp

rh

light

co2

ground truth

15.8

32

212

630

0

ただし、630のCO2読み取り値は、8:50のグラウンドトゥルースの観測後、8:52に取得されたため、これはトレーニングに有効な観測ではありません。 将来のデータはトレーニングセットに「漏れ」、モデルのパフォーマンスが低下します。

要件

  • Unity Catalogでの特徴量エンジニアリングの場合: Unity Catalogでの特徴量エンジニアリング クライアント (任意のバージョン)。

  • ワークスペースFeature Storeの場合: Feature Storeクライアントv0.3.7以降。

Unity Catalogで時系列特徴量テーブルを作成する

Unity Catalog では、 TIMESERIES 主キーを持つテーブルはすべて時系列特徴量テーブルです。 作成方法については、「 Unity Catalog で特徴量テーブルを作成する 」を参照してください。

ローカルワークスペースでの時系列特徴量テーブルの作成

ローカル ワークスペース Feature Storeで時系列特徴テーブルを作成するには、DataFrame またはスキーマにタイムスタンプ キーとして指定する列が含まれている必要があります。

Feature Store クライアントv0.13.4以降、タイム・スタンプ・キー列は、 primary_keys 引数で指定する必要があります。 タイムスタンプ キーは、特徴量テーブルの各行を一意に識別する "主キー" の一部です。 他の主キー列と同様に、タイムスタンプキー列に NULL 値を含めることはできません。

fe = FeatureEngineeringClient()
# user_features_df DataFrame contains the following columns:
# - user_id
# - ts
# - purchases_30d
# - is_free_trial_active
fe.create_table(
  name="ml.ads_team.user_features",
  primary_keys=["user_id", "ts"],
  timeseries_columns="ts",
  features_df=user_features_df,
)
fs = FeatureStoreClient()
# user_features_df DataFrame contains the following columns:
# - user_id
# - ts
# - purchases_30d
# - is_free_trial_active
fs.create_table(
  name="ads_team.user_features",
  primary_keys=["user_id", "ts"],
  timestamp_keys="ts",
  features_df=user_features_df,
)
fs = FeatureStoreClient()
# user_features_df DataFrame contains the following columns:
# - user_id
# - ts
# - purchases_30d
# - is_free_trial_active
fs.create_table(
  name="ads_team.user_features",
  primary_keys="user_id",
  timestamp_keys="ts",
  features_df=user_features_df,
)

時系列特徴テーブルには 1 つのタイムスタンプ キーが必要であり、パーティション列を含めることはできません。 タイム・スタンプ・キー列は TimestampType または DateTypeでなければなりません。

Databricks では、パフォーマンスの高い書き込みと参照を確保するために、時系列特徴量テーブルには 2 つ以下の主キー列を含めることをお勧めします。

時系列特徴量テーブルの更新

時系列特徴テーブルに特徴を書き込む場合、DataFrame は、通常の特徴テーブルとは異なり、特徴テーブルのすべての特徴の値を提供する必要があります。 この制約により、時系列特徴テーブル内のタイムスタンプ間で特徴値のスパース性が減少します。

fe = FeatureEngineeringClient()
# daily_users_batch_df DataFrame contains the following columns:
# - user_id
# - ts
# - purchases_30d
# - is_free_trial_active
fe.write_table(
  "ml.ads_team.user_features",
  daily_users_batch_df,
  mode="merge"
)
fs = FeatureStoreClient()
# daily_users_batch_df DataFrame contains the following columns:
# - user_id
# - ts
# - purchases_30d
# - is_free_trial_active
fs.write_table(
  "ads_team.user_features",
  daily_users_batch_df,
  mode="merge"
)

時系列特徴テーブルへのストリーミング書き込みがサポートされています。

時系列特徴量テーブルを含むトレーニングセットを作成する

時系列特徴テーブルから特徴量のポイントインタイム検索を実行するには、時系列特徴を検索するタイムスタンプを含む DataFrame 列の名前を示す、特徴 FeatureLookuptimestamp_lookup_key を指定する必要があります。Databricks Feature Store は、DataFrame の timestamp_lookup_key 列で指定されたタイムスタンプより前の最新の特徴量テーブル値を取得し、その主キー (タイムスタンプ キーを除く) が DataFrame の lookup_key 列の値と一致するか、そのような特徴量テーブル値が存在しない場合は null を取得します。

feature_lookups = [
  FeatureLookup(
    table_name="ml.ads_team.user_features",
    feature_names=["purchases_30d", "is_free_trial_active"],
    lookup_key="u_id",
    timestamp_lookup_key="ad_impression_ts"
  ),
  FeatureLookup(
    table_name="ml.ads_team.ad_features",
    feature_names=["sports_relevance", "food_relevance"],
    lookup_key="ad_id",
  )
]

# raw_clickstream DataFrame contains the following columns:
# - u_id
# - ad_id
# - ad_impression_ts
training_set = fe.create_training_set(
  df=raw_clickstream,
  feature_lookups=feature_lookups,
  exclude_columns=["u_id", "ad_id", "ad_impression_ts"],
  label="did_click",
)
training_df = training_set.load_df()

ヒント

Photonが有効な場合に検索パフォーマンスを高速化するには、 use_spark_native_join=TrueFeatureEngineeringClient.create_training_setに渡します。 これには databricks-feature-engineering バージョン0.6.0以降が必要です。

feature_lookups = [
  FeatureLookup(
    table_name="ads_team.user_features",
    feature_names=["purchases_30d", "is_free_trial_active"],
    lookup_key="u_id",
    timestamp_lookup_key="ad_impression_ts"
  ),
  FeatureLookup(
    table_name="ads_team.ad_features",
    feature_names=["sports_relevance", "food_relevance"],
    lookup_key="ad_id",
  )
]

# raw_clickstream DataFrame contains the following columns:
# - u_id
# - ad_id
# - ad_impression_ts
training_set = fs.create_training_set(
  df=raw_clickstream,
  feature_lookups=feature_lookups,
  exclude_columns=["u_id", "ad_id", "ad_impression_ts"],
  label="did_click",
)
training_df = training_set.load_df()

時系列特徴テーブル上のすべての FeatureLookup はポイントインタイムルックアップである必要があるため、DataFrame で使用する timestamp_lookup_key 列を指定する必要があります。 ポイントインタイムルックアップでは、時系列フィーチャテーブルに格納されている null フィーチャ値を持つ行はスキップされません。

特徴量の履歴への時間制限の設定

Feature Store クライアント v0.13.0 以降、または Unity Catalogでの特徴量エンジニアリングの任意のバージョンでは、古いタイムスタンプを持つ特徴値をトレーニング セットから除外できます。 これを行うには、FeatureLookupのパラメーター lookback_window を使用します。

lookback_window のデータ タイプは datetime.timedeltaである必要があり、デフォルト値は None です (経過時間に関係なく、すべてのフィーチャ値が使用されます)。

たとえば、次のコードでは、7 日以上経過した特徴値を除外します。

from datetime import timedelta

feature_lookups = [
  FeatureLookup(
    table_name="ml.ads_team.user_features",
    feature_names=["purchases_30d", "is_free_trial_active"],
    lookup_key="u_id",
    timestamp_lookup_key="ad_impression_ts",
    lookback_window=timedelta(days=7)
  )
]
from datetime import timedelta

feature_lookups = [
  FeatureLookup(
    table_name="ads_team.user_features",
    feature_names=["purchases_30d", "is_free_trial_active"],
    lookup_key="u_id",
    timestamp_lookup_key="ad_impression_ts",
    lookback_window=timedelta(days=7)
  )
]

上記の FeatureLookupcreate_training_set を呼び出すと、ポイントインタイムジョインが自動的に実行され、7日より古いフィーチャ値が除外されます。

ルックバック ウィンドウは、トレーニングおよびバッチ推論中に適用されます。 オンライン推論中は、ルックバック ウィンドウに関係なく、常に最新の特徴値が使用されます。

時系列特徴量テーブルを使用したモデルのスコア付け

時系列特徴量テーブルの特徴でトレーニングされたモデルをスコア付けすると、Databricks Feature Store は、トレーニング中にモデルと共にパッケージ化されたメタデータを使用して、ポイントインタイム ルックアップを使用して適切な特徴を取得します。 DataFrameFeatureEngineeringClient.score_batchUnity CatalogFeatureStoreClient.score_batchFeature Store( Unity Catalogでの特徴量エンジニアリング) または (ワークスペース DataTypetimestamp_lookup_keyFeatureLookup合) に提供する には、 または に提供される の と同じ名前と のタイムスタンプ列が含まれている必要があFeatureEngineeringClient.create_training_setFeatureStoreClient.create_training_setます。

ヒント

Photonが有効な場合に検索パフォーマンスを高速化するには、 use_spark_native_join=TrueFeatureEngineeringClient.score_batchに渡します。 これには databricks-feature-engineering バージョン0.6.0以降が必要です。

サンプルノートブック: 時系列特徴量テーブル

これらのノートブックの例は、time series 特徴量テーブルのポイントインタイムルックアップを示しています。

このノートブックは、Unity Catalog が有効になっているワークスペースで使用します。

Time series 特徴量テーブル example ノートブック (Unity Catalog)

ノートブックを新しいタブで開く

次のノートブックは、Unity Catalog が有効になっていないワークスペース用に設計されています。 ワークスペース Feature Storeを使用します。

Time series 特徴量テーブル example ノートブック (ワークスペース not enabled for Unity Catalog)

ノートブックを新しいタブで開く