[Forecast] 電力使用量のデータで予測と実績を比較してみました

2022.11.05

この記事は公開されてから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 で予測し、実績値と推論値の比較を行ってみました。 このような作業を、いくつか繰り返し、作業要領の勘所を掴めたらと考えています。