この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
CX 事業本部デリバリー部の平内(SIN)です。
Amazon Forecast は、統計アルゴリズムと機械学習アルゴリズムによる、時系列予測を実現するフルマネージドサービスですが、初めて利用する方などを対象とした、非常に分かりやすいハンズオンが公開されています。
Amazon Forecast ハンズオン
ハンズオンでは、1 年分の電力使用量データを使用して、次の 36 時間の使用量を予測しています。
https://pages.awscloud.com/rs/112-TZM-766/images/201912-AmazonForecastHandson.pdf
上記を進めることで、手順を理解するのは、十分なのですが、最後に、予測された結果を見て、これは、実際の結果と比較してどうなんだろう?って少し気になってしまいました。
そこで、今回は、同じ手順になりますが、11 ヶ月分をデータセットとして学習し、残りの 1 ヶ月分で、推論結果と比較してみました。
2 電力使用量データ
ハンズオンで使用されている電力使用量データは、400 家庭分(client_0 から client_399)の 2014/01/01 00:00 から 2015/01/01 00:00 までの1年分のデータとなっています。
400 種類のデータだと、ちょっと分かりにくいので、一部抜粋してみると次のようになります。
- 2014/12/01〜2014/12/09
- 1h 間隔
- client_0, client_1, client_2, client_3, client_4, client_5
上記では、client_0 と client_2 が、比較的小さな数字でよく見えないので、大きなデータを外してみるとこんな感じです。
- 2014/12/01〜2014/12/09
- 1h 間隔
- client_0, client_1, client_2
client_0 は、cleint_2 は、他のデータに比較して、非常に値が小さいことが分かります。実は、やってみての実感なのですが、値 0 が多数存在したり、変化量が小さい場合、予測が難しいと思いました。
ちなみに、1年を通してみると季節性のあるデータもあるようです。
- 2014/12/01〜2014/12/09
- 1w 間隔
- client_103, client_113
client_103 は、夏場(8 月を中心)に多く、逆に、client_113 は、少なくなっています。
この後の作業は、client_1,client_3,client_4,clinet_5 の 4 種類をターゲットにしてみます。(ハンズオンで最後にグラフを表示しているのは、client_1)
3 データの抽出
最初に、2014 年(1 年分)のデータから 11 ヶ月分を切り出します。 プログラムでは、単純に日時カラムの日付部分を文字列比較しているだけです。
date_filter.py
def main():
start_date = '2014-01-01'
end_date = '2014-11-30'
input_filename = 'electricityusagedata.csv'
output_filename = 'electricityusagedata_{}_{}.csv'.format(start_date.replace('-',''), end_date.replace('-',''))
output_text = ''
with open(input_filename) as f:
lines = f.readlines()
for line in lines:
tmp = line.replace('\n','').split(',')
date_str = tmp[0][0:10] # 日時のカラムから日付部分を抽出
# 条件にマッチした(期間内)ものだけ出力対象にする
if(start_date <= date_str and date_str<= end_date):
output_text += line
with open(output_filename, mode='w') as f:
f.write(output_text)
if __name__ == "__main__":
main()
electricityusagedata.csv(元データ)
157.2M byte
2014-01-01 01:00:00,2.53807106598985,client_0
2014-01-01 01:00:00,23.648648648648624,client_1
2014-01-01 01:00:00,0.0,client_2
・・・略・・・
2015-01-01 00:00:00,150.25041736227024,client_367
2015-01-01 00:00:00,664.7727272727273,client_368
2015-01-01 00:00:00,6810.81081081081,client_369
electricityusagedata_20140101_20141130.csv(切り出したデータ)
137.2M byte
2014-01-01 01:00:00,2.53807106598985,client_0
2014-01-01 01:00:00,23.648648648648624,client_1
2014-01-01 01:00:00,0.0,client_2
・・・略・・・
2014-11-30 23:00:00,51.75292153589315,client_367
2014-11-30 23:00:00,661.6568914956013,client_368
2014-11-30 23:00:00,17702.7027027027,client_369
4 データセット
切り出した、electricityusagedata_20140101_20141130.csvを S3 に置いて、データセットグループを作成します。
ドメインは、Customとしています。
スキーマーをデータのカラムに一致させ、周期を 1 時間としました。
格納先の S3 バケットを指定して、データセットを作成しています。
5 学習
AWS コンソールから学習を進めると、自動的にAutoMLとなります。(以前は、アルゴリズムの選択が可能でした)
AutoML だと、少し時間とお金ががかかってしまうので、今回は、SDK を使用して、機械学習(Deep_AR_Plus)で PHO オフとしています。
また、予測タイプは、0.5 のみ、予測間隔 1 時間、予測数は9日分です。
import boto3
session = boto3.Session(region_name='ap-northeast-1')
forecast = session.client(service_name='forecast')
# Setting
freq = "1H" # 予測間隔
forecast_horizon = 216 # 予測数(データセットの1/3以内) 24*9=216
performAutoML = False # AutoMLの有効化
performHPO = False # ハイパーパラメータ最適化
algorithm = 'Deep_AR_Plus'
forecastTypes = ["0.50"] # 予測タイプ(分位数) 0.01から0.99 まで最大5つ
account = "xxxxxxxxxxxx"
dataset_group_name = "electricityusagedata_20140101_20141130"
predictor_name = "train_{}_{}_{}".format(dataset_group_name, forecast_horizon, algorithm)
predictor_arn = "arn:aws:forecast:ap-northeast-1:{}:predictor/{}".format(
account, predictor_name)
dataset_group_arn = "arn:aws:forecast:ap-northeast-1:{}:dataset-group/{}".format(
account, dataset_group_name)
# Traning
create_predictor_response = forecast.create_predictor(PredictorName=predictor_name,
AlgorithmArn="arn:aws:forecast:::algorithm/{}".format(
algorithm),
ForecastHorizon=forecast_horizon,
ForecastTypes=forecastTypes,
PerformAutoML=performAutoML,
PerformHPO=performHPO,
InputDataConfig={
"DatasetGroupArn": dataset_group_arn,
},
FeaturizationConfig={"ForecastFrequency": freq})
status = forecast.describe_predictor(PredictorArn=predictor_arn)
print(status["Status"])
6 予測
予測は、対象をSelected Itemsとして、下記のselected_items.csvを指定しています。(All Items とすると、400 個(client_0〜cleint_399)全てのポイント出力となり利用費が上がってしまうので、注意が必要です)
selected_items.csv
client_1
client_3
client_4
clinet_5
結果をダウンロードして元のデータと比較してみました。
以下が凡例の意になります。
client_1 元のデータ
P_client_1 予測データ
- client_1 では、予測結果が、全体に大きな値になっていますが、増減については、殆ど追従しているように見えます。
- client_3,client_4,client_5 は、要求される精度にもよりますが、十分に予測できているように思えます。
7 最後に
今回は、すでに結果の分かっているデータを Forecast で予測し、実績値と推論値の比較を行ってみました。 このような作業を、いくつか繰り返し、作業要領の勘所を掴めたらと考えています。