Databricks Feature Storeで時系列特徴量テーブルを取り扱う

[Work with time series feature tables \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/feature-store/time-series.html) [2022/4/7時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

時系列特徴量テーブルを用いることで、Databricks Feature Storeはポイントインタイムの正確性を必要とする時系列およびイベントベースのユースケースをサポートします。特定のカラムを特徴量テーブルのタイムスタンプキーに指定し、異なるタイムスタンプにおける特定のプライマリーキーに対する履歴特徴量の値をベスの業に格納することができます。モデルのトレーニングやスコアリングのために、特定の時点における最新の特徴量の値を取得するために、Databricks Feature Storeは時系列特徴量テーブルに対するポイントインタイムの検索をサポートしています。

:::note info
**注意**
ポイントインタイムの検索機能は時には「タイムトラベル」と呼ばれることもあります。Databricks Feature Storeのポイントインタイム検索機能は[Delta Lakeのタイムトラベル](https://qiita.com/taka_yayoi/items/47b58eb8696b278a3a82#%E9%81%8E%E5%8E%BB%E3%81%AE%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%BC%E3%82%BF%E3%82%A4%E3%83%A0%E3%83%88%E3%83%A9%E3%83%99%E3%83%AB)とは異なります。
:::

ポイントインタイムの検索を用いることで、リアルタイム推論の際には利用できない特徴量の値でモデルがトレーニングされる際に生じるデータリーケージ(漏れ)の問題の回避に役立ちます。データリーケージは、トレーニングとリアルタイム推論の間でのモデルパフォーマンスの大幅な不一致を引き起こすことがあります。時系列特徴量テーブルを用いることで、トレーニングの際に指定したタイムスタンプに基づいて、モデルが最新の特徴量を使用することを保証することができます。

例えば、時系列データ、イベントベースのデータ、時間で集計されたデータなど、時間とともに特徴量が変化する場合、時系列特徴量テーブルの利用を検討してください。

# 要件

Databricksランタイム10.3 ML以降が必要です。

# Databricks Feature Storeで時系列特徴量テーブルを作成する

時系列特徴量テーブルを作成するには、タイムスタンプキーとして指定するカラムをデータフレームあるいはスキーマに含める必要があります。

```py:Python
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",
  keys="user_id",
  timestamp_keys="ts",
  features_df=user_features_df,
)
```

時系列特徴量テーブルには、1つのタイムスタンプキーを含めることができ、パーティションカラムを含めることはできません。タイムスタンプキーのカラムは`TimestampType`あるいは`DateType`である必要があり、プライマリーキーを指定することはできません。

高速な書き込み、検索を実現するために、時系列特徴量テーブルには2つ以上のプライマリーキーを含めないことをお勧めします。

# 時系列特徴量テーブルを更新する

時系列特徴量テーブルに特徴量を書き込む際には、通常の特徴量テーブルとは異なり、お使いのデータフレームは特徴量テーブルの全ての特徴量の値を提供しなくてはなりません。この制約によって、時系列特徴量テーブルにおけるタイムスタンプにまたがる特徴量の希薄性を削減することができます。

```py:Python
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"
)
```

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

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

時系列特徴量テーブルからの特徴量に対するポイントインタイム検索を実行するためには、時系列特徴量を検索するために検索対象となるタイムスタンプを含むデータフレームのカラム名を、特徴量の`FeatureLookup`の`timestamp_lookup_key`で指定する必要があります。Databricks Feature Storeは、プライマリーキーがデータフレームの`lookup_key`カラムの値とマッチし、データフレームの`timestamp_lookup_key`カラムで指定されるタイムスタンプ以前で最新の特徴量を取得します。そのような特徴量の値が存在しない場合には`null`となります。

```py:Python
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(
  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`はポイントインタイム検索である必要があるため、お使いのデータフレームで使用する`timestamp_lookup_key`カラムを指定する必要があります。ポイントインタイム検索は、時系列特徴量テーブルに格納されている`null`の特徴量の行をスキップしません。

# 時系列特徴量テーブルでモデルのスコアリングを行う

時系列特徴量テーブルからの特徴量を用いてトレーニングしたモデルをスコアリングする際、Databricks Feature Storeはトレーニングの際にモデルにパッケージングされたメタデータによるポイントインタイム検索を用いて適切な特徴量を取得します。`FeatureStoreClient.score_batch`に指定するデータフレームには、`FeatureStoreClient.create_training_set`に指定された`FeatureLookup`の`timestamp_lookup_key`と同じ名前の`DataType`のカラムが含まれている必要があります。

# オンラインストアに時系列特徴量を公開する

オンラインストアに時系列特徴量テーブルを公開するために`FeatureStoreClient.publish_table`を用いることができます。Databricks Feature Storeには、オンラインストアを作成する際に指定する`OnlineStoreSpec`に応じて、オンラインストアにスナップショットあるいは時系列データのウィンドウのどちらかを公開する機能を提供しています。以下の表ではそれぞれの公開モードの詳細を示しています。

| オンラインストアプロバイダー | スナップショット公開モード | ウィンドウ公開モード |
|:--|:--|:--|
|Amazon DynamoDB (Databricksランタイム10.4 ML以降)   |X   |X   |
| MySQL   |  X |   |
| Microsoft SQL Server  |X   |   |

## 時系列スナップショットを公開する

特徴量テーブルのそれぞれのプライマリーキーごとに最新の特徴量を公開します。オンラインストアは、プライマリーキーによる検索をサポートしており、ポイントインタイム検索はサポートしていません。

持続時間(TTL:Time to Live)をサポートしていないオンラインストアに対しては、Databricks Feature Storeはスナップショット公開モードのみをサポートします。持続時間をサポートするオンラインストアに対しては、作成時に`OnlineStoreSpec`に持続時間(`ttl`)が指定されない限り、デフォルトではスナップショット公開モードとなります。

## 時系列ウィンドウを公開する

オンラインストアに特徴量テーブルのプライマリーキーごとの全ての特徴量を公開し、期限が切れたレコードを自動で削除します。レコードのタイムスタンプ(UTC)が指定された持続時間よりも大きくなった際にレコードは期限切れとみなされます。持続時間(TTL:Time to Live)の詳細に関してはクラウドごとのドキュメントを参照ください。

オンラインストアはプライマリーキーによる検索をサポートしており、自動で最新タイムスタンプの特徴量を取得します。

この公開モードを使用するには、オンラインストアを作成する際に`OnlineStoreSpec`で持続時間(`ttl`)を指定します。設定した後に`ttl`を変更することはできません。後続の公開のコールは`ttl`を継承するので、明示的に`OnlineStoreSpec`で定義する必要はありません。

# サンプルノートブック

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

https://github.com/taka-yayoi/public_repo/tree/main/time_series_feature_table

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)