はじめに
前回PyTorchでGluonTSのDeepARモデルが使用できることを紹介しました。touch-sp.hatenablog.com
今回は同じモデルで「feat_dynamic_real」を使ってみようと思います。
「feat_dynamic_real」とは?
時系列予測をする時に求めたい値はターゲット変数と言います。そのターゲット変数に影響を及ぼす変数を説明変数と言います。その説明変数のうち将来まで値がわかっているものをGluonTSでは「feat_dynamic_real」と言っています。これだけでは何のことかわからないと思いますので具体例で説明します。今回使用させて頂くデータはUCI Machine Learning Repositoryの「Bike Sharing Dateset」です。archive.ics.uci.edu
レンタル自転車の貸し出し数のデータになります。
自転車の貸し出し数をターゲット変数とした時にそれに影響を及ぼす説明変数はどんなものがあるか?
例えば季節、曜日、天気、気温などです。ざっくり言うとそれが「feat_dynamic_real」です。
天気、気温などは将来の値がわからないので本来であれば「feat_dynamic_real」としては扱えません。しかし今回は天気予報の精度が100%として、すべて「feat_dynamic_real」として扱いました。
「feat_dynamic_real」についてなんとなく理解できたでしょうか?
使用するには注意点があります。曜日、天気などはカテゴリーデータなので「feat_dynamic_real」として扱う場合にはOne-Hotベクトル化する必要があります。
One-Hotベクトル化はPandasのget_dummiesを使えば簡単です。
touch-sp.hatenablog.com
Pythonスクリプト
import warnings warnings.simplefilter('ignore') import numpy as np import pandas as pd from matplotlib import pyplot as plt from gluonts.dataset.common import ListDataset from gluonts.torch.model.deepar import DeepAREstimator from gluonts.evaluation.backtest import make_evaluation_predictions from gluonts.dataset.util import to_pandas from autogluon.core.utils.loaders import load_zip url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00275/Bike-Sharing-Dataset.zip' load_zip.unzip(url, unzip_dir = '.') df = pd.read_csv('day.csv',index_col=1) feat1 = np.array(df.hum).reshape((1,-1)) feat2 = np.array(df.temp).reshape((1,-1)) feat3 = np.array(df.windspeed).reshape((1,-1)) feat4 = np.array(pd.get_dummies(df.weekday)).transpose((1,0)) feat5 = np.array(df.workingday).reshape((1,-1)) feat6 = np.array(pd.get_dummies(df.weathersit)).transpose((1,0)) feat7 = np.array(pd.get_dummies(df.season)).transpose((1,0)) features_real = np.concatenate([feat1, feat2, feat3, feat4, feat5, feat6, feat7], axis=0) training_data = ListDataset( [{"start": df.index[0], "target": df.cnt[:-14], "feat_dynamic_real": features_real[:,:-14], }], freq = "1D") test_data = ListDataset( [{"start": df.index[0], "target": df.cnt, 'feat_dynamic_real': features_real, }], freq = "1D") estimator = DeepAREstimator( freq='1D', prediction_length=14, context_length=28, num_feat_dynamic_real = 18, trainer_kwargs=dict(max_epochs=50), ) predictor = estimator.train(training_data=training_data) forecast_it, ts_it = make_evaluation_predictions( dataset=test_data, # test dataset predictor=predictor, # predictor num_samples=100, # number of sample paths we want for evaluation ) plot_length = 50 prediction_intervals = (50.0, 90.0) legend = ["observations", "median prediction"] + [f"{k}% prediction interval" for k in prediction_intervals][::-1] for x, y in zip(test_data, forecast_it): to_pandas(x)[-plot_length:].plot() y.samples = y.samples.clip(min=0) y.plot(color='g', prediction_intervals=prediction_intervals) plt.grid(which='both') plt.legend(legend, loc='upper left') plt.show()
結果
MXNetを使った場合
今回の記事は過去のMXNet用のスクリプトをPyTorch用に書き換えただけです。MXNet用のスクリプトはこちらを参照して下さい。
touch-sp.hatenablog.com
その他
ZIPファイルのダウンロード、解凍に関してはこちらを参照して下さい。touch-sp.hatenablog.com