Teradata VantageとFEASTで拡張性の高いフィーチャーストアを実現

著者 Mohammmad Taha Wahab 、Mohammad Harris Mansur 、Will Fleury
最終更新日 2023年1月5日

:::note warn
警告
本記事はTeradata Corporationのサイト[Getting Started](https://quickstarts.teradata.com/index.html#getting-access-to-vantage)に掲載された内容を抄訳したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::

## はじめに
FeastのTeradata用コネクタは、すべての機能をサポートし、Teradataをオンラインおよびオフラインのストアとして使用する完全な実装です。

## 前提条件
Teradata Vantageインスタンスにアクセスする必要があります。
Vantageをご利用でない場合は、開発者向けの無償版である[Teradata Vantageのお試し環境の構築方法（まとめ）](https://qiita.com/ykswi/items/ac06fe8b4fef48582e37)をご覧ください。

## 概要
このハウツーでは、feastの用語をご存知であることを前提に説明しています。復習が必要な場合は、[FEASTの公式ドキュメント](https://docs.feast.dev/)をご覧ください。

このドキュメントは、開発者がTeradataのオフラインおよびオンラインストアをFeastに統合する方法を説明します。Teradataのオフラインストアにより、ユーザーは任意のデータストアをオフラインフィーチャーストアとして使用することができます。モデル学習のためにオフラインストアからフィーチャーを取得し、モデル推論時に使用するためにオンラインフィーチャーストアに実体化させることができます。

一方、オンラインストアは、低レイテンシーで機能を提供するために使用されます。materializeコマンドは、データソース（またはオフラインストア）からオンラインストアに特徴量をロードするために使用されます。

feast-teradataライブラリは、Teradataのサポートを以下のように追加します。

・オフラインストア

・オンラインストア

さらに、レジストリ(カタログ)としてTeradataを使用することは、registry_type: sqlを介して既にサポートされており、我々のサンプルに含まれています。これは、すべてがTeradataに配置されることを意味します。しかし、要件やインストールなどによっては、他のシステムと適宜混在させることが可能です。

## はじめに
まず、feast-teradata ライブラリをインストールします。

```:InstallFeastLibrary.sh
pip install feast-teradata
```

標準ドライバーのデータセットを使用して、Teradataとの簡単なfeast設定を作成してみましょう。feast initは、feastコアライブラリの一部であるテンプレートに対してのみ機能するため、使用できないことに注意してください。このライブラリはいずれfeast coreにマージされる予定ですが、今のところ、この特定のタスクには次のcliコマンドを使用する必要があります。その他のfeast cliコマンドは期待通りに動作します。

```:InitFeast.sh
feast-td init-repo
```

すると、Teradataシステムの必要な情報を入力するプロンプトが表示され、サンプルデータセットがアップロードされます。上記のコマンドを実行する際に、レポ名demoを使用したと仮定します。リポジトリファイルと、test_workflow.pyというファイルが表示されます。このtest_workflow.pyを実行すると、Teradataをレジストリ、OfflineStore、OnlineStoreとして、饗宴のための完全なワークフローが実行されます。

```:files
demo/
    feature_repo/
        driver_repo.py
        feature_store.yml
    test_workflow.py
```
demo/feature_repo ディレクトリから、以下の feast コマンドを実行して、レポ定義をレジストリに適用（import/update）してください。このコマンドを実行すると、teradataデータベースのレジストリのメタデータテーブルを確認することができます。

```:ApplyFeast.sh
feast apply
```
レジストリ情報をfeast UIで見るには、以下のコマンドを実行します。デフォルトでは5秒ごとにポーリングするので、--registry_ttl_secが重要であることに注意してください。

```:SeeRegistory.sh
feast ui --registry_ttl_sec=120
```

## オフラインストア設定

```:PrametersForOfflineStore
project: <name of project>
registry: <registry>
provider: local
offline_store:
   type: feast_teradata.offline.teradata.TeradataOfflineStore
   host: <db host>
   database: <db name>
   user: <username>
   password: <password>
   log_mech: <connection mechanism>
```

## レポの定義

以下はdefinition.pyの例で、エンティティ、ソースコネクタ、フィーチャービューの設定方法を詳しく説明しています。

次に、それぞれのコンポーネントを説明します：


・TeradataSource。Teradata (Enterprise または Lake) に格納された機能、または Teradata (NOS, QueryGrid) からの外部テーブルを介してアクセス可能な機能のデータソース。

・エンティティ。意味的に関連するフィーチャーの集合体

・フィーチャー・ビュー。フィーチャー・ビューは、特定のデータソースからのフィーチャーデータのグループである。フィーチャー・ビューにより、フィーチャーとそのデータソースを一貫して定義できるため、プロジェクト全体でフィーチャー・グループを再利用できる。

```:Feature1
driver = Entity(name="driver", join_keys=["driver_id"])
project_name = yaml.safe_load(open("feature_store.yaml"))["project"]

driver_stats_source = TeradataSource(
    database=yaml.safe_load(open("feature_store.yaml"))["offline_store"]["database"],
    table=f"{project_name}_feast_driver_hourly_stats",
    timestamp_field="event_timestamp",
    created_timestamp_column="created",
)

driver_stats_fv = FeatureView(
    name="driver_hourly_stats",
    entities=[driver],
    ttl=timedelta(weeks=52 * 10),
    schema=[
        Field(name="driver_id", dtype=Int64),
        Field(name="conv_rate", dtype=Float32),
        Field(name="acc_rate", dtype=Float32),
        Field(name="avg_daily_trips", dtype=Int64),
    ],
    source=driver_stats_source,
    tags={"team": "driver_performance"},
)
```

## オフラインストア利用状況
オフラインストアのテストには、以下に説明するように2種類の方法があります。しかし、その前に、いくつかの必須ステップがあります：

では、過去60日間にイベントを見たことのあるエンティティ（母集団）のみを使って、学習用の素性を一括して読み込んでみましょう。使用する述語（フィルタ）は、与えられた学習用データセットのエンティティ（母集団）選択に関連するものであれば何でもよい。event_timestampはあくまで例示である。

```:Testing
from feast import FeatureStore
store = FeatureStore(repo_path="feature_repo")
training_df = store.get_historical_features(
    entity_df=f"""
            SELECT
                driver_id,
                event_timestamp
            FROM demo_feast_driver_hourly_stats
            WHERE event_timestamp BETWEEN (CURRENT_TIMESTAMP - INTERVAL '60' DAY) AND CURRENT_TIMESTAMP
        """,
    features=[
        "driver_hourly_stats:conv_rate",
        "driver_hourly_stats:acc_rate",
        "driver_hourly_stats:avg_daily_trips"
    ],
).to_df()
print(training_df.head())
```

feast-teradataライブラリを使用すると、feastのAPIと機能一式を使用することができます。できることの詳細については、公式の feast [クイックスタート](https://docs.feast.dev/getting-started/quickstart) を参照してください。

## オンラインストア

Feastは、モデル推論時に低レイテンシーで検索できるように、データをオンラインストアに実体化します。一般に、オンラインストアにはKey-Valueストアが使用されますが、リレーショナルデータベースもこの目的に使用することができます。

OnlineStoreクラスのコントラクトを実装したクラスを作成することで、ユーザは独自のオンラインストアを開発することができる。

## オンラインストアコンフィグ

```:Config
project: <name of project>
registry: <registry>
provider: local
offline_store:
   type: feast_teradata.offline.teradata.TeradataOfflineStore
   host: <db host>
   database: <db name>
   user: <username>
   password: <password>
   log_mech: <connection mechanism>
```

## オンラインストア利用状況

オンラインストアをテストする前に、いくつか必須の手順があります。

materialize_incremental コマンドは、オンラインストアの機能を徐々に具体化するために使用されます。追加する新しい機能がない場合、このコマンドは基本的に何も行いません。materialize_incrementalでは、開始時刻は、now - ttl（機能ビューで定義したttl）または最新のマテリアライズの時刻のいずれかになります。少なくとも一度でも機能をマテリアライズしていれば、それ以降のマテリアライズは、前回のマテリアライズの時点でストアに存在しなかった機能のみをフェッチすることになります。

```:SetTime
CURRENT_TIME=$(date +'%Y-%m-%dT%H:%M:%S')
feast materialize-incremental $CURRENT_TIME
```

次に、オンライン機能を取得する際に、featuresとentity_rowsの2つのパラメータを用意します。featuresパラメータはリストで、df_feature_viewに存在する特徴を任意の数だけ取ることができます。上の例では、4つの特徴しかありませんが、4つ以下でもかまいません。次に、entity_rowsパラメータもリストで、{feature_identifier_column: value_to_be_fetched}という形式のディクショナリーを取ります。この場合、driver_idカラムは、エンティティドライバの異なる行を一意に識別するために使用されます。現在、driver_idが5に等しいフィーチャーの値をフェッチしています。また、このような行を複数取得することもできます：[{driver_id: val_1}, {driver_id: val_2}, .., {driver_id: val_n}] [{driver_id: val_1}, {driver_id: val_2}, .., {driver_id: val_n}]

```:GetEntity
entity_rows = [
        {
            "driver_id": 1001,
        },
        {
            "driver_id": 1002,
        },
    ]
features_to_fetch = [
            "driver_hourly_stats:acc_rate",
            "driver_hourly_stats:conv_rate",
            "driver_hourly_stats:avg_daily_trips"
        ]
returned_features = store.get_online_features(
    features=features_to_fetch,
    entity_rows=entity_rows,
).to_dict()
for key, value in sorted(returned_features.items()):
    print(key, " : ", value)
```

## SQLレジストリの設定方法
もう一つ重要なのは、SQLレジストリです。まず、ユーザー名、パスワード、データベース名などを使って接続文字列を作るパス変数を作り、それを使ってTeradataのDatabaseへの接続を確立しています。

```:Pathes
path = 'teradatasql://'+ teradata_user +':' + teradata_password + '@'+host + '/?database=' + teradata_database + '&LOGMECH=' + teradata_log_mech
```

これにより、データベースに以下のようなテーブルが作成されます：

・エンティティ (エンティティ名,プロジェクトID,最終更新日,エンティティプロト)

・データソース (データソース名,プロジェクトID,最終更新日,データソースプロト)

・機能ビュー (機能ビュー名、プロジェクトID、最終更新日時、マテリアライズド間隔、機能ビュープロト、ユーザーメターデータ)

・Request_feature_views (機能ビュー名,project_id,last_updated_timestamp,feature_view_proto,user_metadata)

・Stream_feature_views (機能ビュー名、project_id、last_updated_timestamp、feature_view_proto、user_metadata)

・マネージドインフラ (インフラ名, project_id, last_updated_timestamp, infra_proto)

・validation_references (validation_reference_name、project_id、last_updated_timestamp、validation_reference_proto)

・saved_datasets (saved_dataset_name、project_id、last_updated_timestamp、saved_dataset_proto)

・feature_services (feature_service_name、project_id、last_updated_timestamp、feature_service_proto)

・on_demand_feature_views (feature_view_name, project_id, last_updated_timestamp, feature_view_proto, user_metadata)



さらに、完全な（しかし実世界ではない）、エンドツーエンドのワークフローの例を見たい場合は、demo/test_workflow.py スクリプトを参照してください。これは、完全な饗宴の機能をテストするために使用されます。

Enterprise Feature Storeは、データ解析の重要な段階における価値創造プロセスを加速させます。生産性を向上させ、製品を市場に投入するまでの時間を短縮することができます。Teradataとfeastを統合することで、Teradataの高効率な並列処理をFeature Store内で利用できるようになり、パフォーマンスの向上が期待されます。

## さらに詳しく

・FEAST上の記事（英語）: [Feast Scalable Registry](https://docs.feast.dev/tutorials/using-scalable-registry)

・Medium上の記事（英語）: [Enabling highly scalable feature store with Teradata Vantage and FEAST](https://medium.com/teradata/enabling-highly-scalable-feature-store-with-teradata-vantage-and-feast-e01008fa8fdb)


#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)