Amazon Forecastにwhat-if分析機能が追加:関連する時系列データが変化した際の動きを分析可能になりました

2022.09.14

こんちには。

データアナリティクス事業本部機械学習チームの中村です。

今回はAmazon Forecastの新機能であるwhat-if分析についてご紹介します。

AWS公式ブログでは以下の記事で紹介されています。

Amazon Forecastの概要

まずAmazon Forecastの概要をおさらいします。

Amazon Forecastは時系列データを予測するサービスです。

入力できる情報には以下の3種類があります。

  • TARGET_TIME_SERIES(TTS)
    • 予測対象(ターゲット)となる時系列データ。(例: 需要予測の場合は需要のデータ)
    • 時系列で変化しない情報(例: 店舗ID)を含めることで分析軸を追加可能。
  • RELATED_TIME_SERIES(RTS)
    • 関連する時系列データ。(例: 需要予測の場合は価格など)
    • TTSに付加した分析軸はこちらにも追加が必要。
  • ITEM_METADATA
    • アイテムのメタデータを追加することが可能。(例: 商品のブランドなど)

TTSは全てのケースでおいて必須のデータですが、what-if分析ではRTSも必要となります。

what-if分析とは

what-if分析はRTSが変化した際に、TTSがどのように変化するかを分析する機能であるためです。

例えば需要予測の場合は、価格を過去に遡って下げたと仮定した場合に、

予測した需要がどの程度変化するのかを分析することが可能になります。

また、Amazon Forecastにかかる費用は以下の通りです。

  • データのインポート
  • Predictorのトレーニング
  • 予測したデータポイント数
  • 予測の説明

このうち、What-if分析はデータポイントを予測するため、「予測したデータポイント数」の部分にコストが掛かってくるのでご注意ください。

(実際本記事の通りに実行すると、60ドル程度は必要になりますので留意頂ければと思います)

what-if分析のトライ

今回関連するリソースは以下のような階層構造になっています。

What-if分析に相当するのは、オレンジ部分で、一旦Forecastまで作成した上で構築する必要があります。

S3の準備

事前にバケット作成しておきます。(今回は以下)

  • バケット名: sample-nakamura-2022-09-09-forecast

以下のGitHubに、公開されているデータセットがあります。

ここから以下の2つのファイルをダウンロードします。

  • consumer_electronics_TTS.csv
  • consumer_electronics_RTS.csv

これらをS3のそれぞれアップロードしておきます。(今回は以下)

  • s3://sample-nakamura-2022-09-09-forecast/target/consumer_electronics_TTS.csv
  • s3://sample-nakamura-2022-09-09-forecast/related/consumer_electronics_RTS.csv

Dataset group作成

「View dataset groups」を押下し、データセットグループ一覧を表示します。

「Create dataset group」を押下します。

Dataset groupの情報を以下のように入力し、末尾の「Next」を押下します。

  • Dataset group name: sample_nakamura_what_if_dsg
  • Forecasting domain: Custom

Dataset(ターゲット側)作成

Datasetの情報を以下のように入力します。

  • Dataset name: sample_nakamura_what_if_tts
  • Frequency of your data: 1 months
  • Data schema: JSON builderをチェック

またJSON schemaには以下を設定し、Timestamp formatにはyyyy-MM-ddを設定します。

{
    "Attributes": [
        {
            "AttributeName": "item_id",
            "AttributeType": "string"
        },
        {
            "AttributeName": "store_id",
            "AttributeType": "string"
        },
        {
            "AttributeName": "timestamp",
            "AttributeType": "timestamp"
        },
        {
            "AttributeName": "target_value",
            "AttributeType": "float"
        }
    ]
}

Dataset importの設定は以下とします。

  • Dataset import name: sample_nakamura_what_if_tts_import
  • Select time zone: Do not use time zone
  • Import file type: CSV
  • Data location: s3://sample-nakamura-2022-09-09-forecast/target/consumer_electronics_TTS.csv

IAM roleは、Create a New Roleを選択すると以下のダイアログがでるので、

Specific S3 bucketsを以下のように設定して、「Create role」を押下します。

  • sample-nakamura-2022-09-09-forecast

ちなみに作成されるロールにアタッチされるポリシーは以下のようになります。

(書き込み権限もあるので、後述のエクスポート時もこちらを使用していきます。)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::sample-nakamura-2022-09-09-forecast"
            ]
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::sample-nakamura-2022-09-09-forecast/*"
            ]
        }
    ]
}

ロールが作成されるので、その後「Start」を押下します。

その後Importが開始されます。

Dataset group一覧から作成したDataset groupを選択すると、

直後は「Create pending」となっているため、以下のようにActiveとなるまで待ちます。

Dataset(関連データ側)作成

what-if分析には、Related time series dataが必要となるため、上記の画面で「Import」を押下します。

Datasetの情報を以下で入力します。

  • Dataset name: sample_nakamura_what_if_rts
  • Frequency of your data: 1 months
  • Data schema: JSON builderをチェック

またJSON schemaには以下を設定し、Timestamp formatにはyyyy-MM-ddを設定します。

{
    "Attributes":[
        {
            "AttributeName":"item_id",
            "AttributeType":"string"
        },
        {
            "AttributeName":"store_id",
            "AttributeType":"string"
        },
        {
            "AttributeName":"timestamp",
            "AttributeType":"timestamp"
        },
        {
            "AttributeName":"price",
            "AttributeType":"float"
        },
    ]
}

Dataset importの設定は以下とします。

  • Dataset import name: sample_nakamura_what_if_rts_import
  • Select time zone: Do not use time zone
  • Import file type: CSV
  • Data location: s3://sample-nakamura-2022-09-09-forecast/target/consumer_electronics_RTS.csv

IAM roleは、先ほどと同じロールを指定します。(データ格納先のバケットは同じの場合)

その後「Start」を押下します。

Importが始まるので、先ほどと同様にRelated time series dataが「Active」となるまで待ちます。

Predictor作成

次にPredictorを作成します。先ほどの画面で、Predictor trainingの横にある「Start」を押下します。

Predictor settingsは以下の値で設定します。

  • Predictor name: sample_nakamura_what_if_predictor
  • Forecast frequency: 1 month(s)
  • Forecast horizon: 3
  • Forecast dimensions: store_id
  • Forecast quantiles:
    • Forecast quantile: Forecast quantile 1, Value: 0.10
    • Forecast quantile: Forecast quantile 2, Value: 0.50
    • Forecast quantile: Forecast quantile 3, Value: 0.90

他はデフォルトのまま、ページ下部の「Create」を押下します。

すると、Trainingが開始され、Predictor一覧で残り時間が表示されます。

(今回は2時間程度必要でした)

Forecast作成(予測の実行)

Predictor一覧から作成したPredictorを選択すると、「Create forecast」ボタンがありますので、

そこで予測を実行します。

Forecast detailsは以下の値で設定します。

  • Forecast name: sample_nakamura_what_if_forecast
  • Predictor: sample_nakamura_what_if_predictor
  • Item for generating forecasts: All Items

作成が開始されるので、結果を待ちます。

(残り時間が表示され、今回は40分程度かかりました)

作成が終わったら、forecastを選択し、以下の「Create forecast export」を押下します。

Export detailsで以下を入力します。

  • Export name: sample_nakamura_what_if_forecast_export
  • IAM role: インポート時に作成したものと同じロールを指定
  • Export file type: CSV
  • S3 forecast export location: s3://sample-nakamura-2022-09-09-forecast/export

ページ下部の「Create Export」を押下して完了を待ちます。

what-if分析の作成

ダッシュボード画面からwhat-if分析が作成できます。「Explore what-if analysis」を押下します。

「Create」を押下します。

What-if analysis detailsを以下のように設定します。

  • What-if analysis name: sample_nakamura_what_if_analysis
  • Select forecast: sample_nakamura_what_if_forecast
  • Item selection: Select all items

ページ下部の「Create what-if analysis」を押下します。

しばらく経過すると、What-if analysisのStatusがActiveとなります。

what-if分析のForecast作成(予測の実行)

上記の画面から、What-if forecastの「Create」を押下して進みます。

What-if forecast detailsに以下を入力します。

  • What-if forecast name: sample_nakamura_what_if_analysis_forecast
  • What-if forecast definition method: Use transformation functions
  • Transformation function builder:
    • Action
    • Operation: MULTIPLY, AttributeName: price, Value: 0.90
    • Conditions:
      • AttributeName: timestamp, AttributeValue: 2019-09-01, Condition: GREATER_THAN

上記の設定内容は、2019-09-01以降のpriceデータに0.9を乗算した場合に、

Targetがどのように変化するかを、What-if分析するような記述となっています。

なお、数式で表現できないような値を設定したい場合は、

definition methodに「Define the what-if forecast with a replacement dataset」を選択し、

データを置き換えたRelated Time SeriesデータをS3からImportすることで、What-if分析をすることが可能です。

入力をしたらページ下部の「Create」を押下します。

すると以下のように作成中となるので、しばらく待ちます。

StatusがActiveとなったら、ページ下部に移動し、以下のWhat-if forecast exportで

「Create export」を押下します。

インポート時に作成したものと同じロールを指定

Export detailsで以下を入力します。

  • Export name: sample_nakamura_what_if_analysis_forecast_export
  • What-if forecasts: sample_nakamura_what_if_analysis_forecast
  • S3 forecast export location: s3://sample-nakamura-2022-09-09-forecast/export_what_if
  • IAM role: インポート時に作成したものと同じロールを指定

ページ下部の「Create Export」を押下して完了を待ちます。

結果の比較

エクスポート結果をダウンロードして比較していきます。

aws s3 cp s3://sample-nakamura-2022-09-09-forecast/export ./export --recursive
aws s3 cp s3://sample-nakamura-2022-09-09-forecast/export_what_if ./export --recursive

可視化のため、Pythonのコードを準備しました。

import pathlib
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
sns.set(style='darkgrid')
from datetime import datetime

# 学習データ読み込み
tts_df = pd.read_csv("./consumer_electronics_TTS.csv")

# 推論結果読み込み
def read_csv_files(src_path: str):
    df = pd.DataFrame([])
    for p in pathlib.Path(src_path).glob("*.csv"):
        # print(p)
        _df = pd.read_csv(p)

        if len(df)==0:
            df = _df
        else:
            df = pd.concat([df, _df], axis=0)
    df = df.sort_values(['item_id', 'store_id', 'date']).reset_index(drop=True)
    df['yyyy-mm-dd'] = [i[:10] for i in df['date']]
    return df
base_df = read_csv_files("./export")
whatif_df = read_csv_files("./export_what_if")

# 描画
query_str = 'item_id == "item_001" and store_id == "store_001"'

fig, axes = plt.subplots(2, 1, figsize=(10, 6), dpi=100, sharex="col")
fig.suptitle(query_str)

ax = axes[0]
sns.lineplot(data=tts_df.query(query_str), x='timestamp', y='demand', marker="o", ax=ax, label="train(target)", color=colors[0])
sns.lineplot(data=base_df.query(query_str), x='yyyy-mm-dd', y='p50', marker="o", ax=ax, label="forecast(p50)", color=colors[1])
sns.lineplot(data=whatif_df.query(query_str), x='yyyy-mm-dd', y='sample_nakamura_what_if_analysis_forecast_p50', marker="o", ax=ax, label="what-if-forecast(p50)", color=colors[2])
ax.set_ylim([100, 500])

ax = axes[1]
sns.lineplot(data=rts_df.query(query_str), x='timestamp', y='price', marker="o", ax=ax, label="train(related)", color=colors[0])
sns.lineplot(data=rts_df.query(query_str).query('timestamp > "2019-09-01"'), x='timestamp', y='price_whatif', marker="o", ax=ax, label="what-if", color=colors[2])
[i.set_rotation(90) for i in ax.get_xticklabels()]
ax.set_ylim([40, 150])

plt.tight_layout()

plt.tight_layout()

結果は以下のようになります。(item_id: "item_001", store_id: "store_001"の場合)

上のdemandが予測対象となる時系列データで、下のpriceがRelatedな時系列データとなる情報です。

demand, priceそれぞれ青線で描かれている箇所がPredictorの学習に使用されています。

オレンジ線は、通常のPredictorのForecast結果(p50)で、これがベースラインとなります。

グリーン線がwhat-if分析に関するデータで、priceが0.9掛けだったら、

demandにどのような影響がでるかを確認できます。

影響としては、priceが低下すると、demandが上昇するといったような予測をしているようです。

これは、学習に使用したdemandとpriceが逆相関を持っていることをうまく反映しています。

この結果は、item_id、store_idごとにそれぞれ影響度を確認することが可能です。

興味のある方は他のケースも確認してみてください。

まとめ

いかがでしたでしょうか?

what-if分析で、過去を振り返って様々な仮説を検証することができるので、分析の幅が広がりそうですね。

Amazon Forecastをご利用の方は是非お試しください。

こちらの記事がAmazon Forecastを活用する際の参考になれば幸いです。