Amazon Forecastで自分の電気代を予測してみる

## はじめに
4月ごろから個人的な興味で機械学習の勉強をはじめました。
普段は本やオンライン教材に出てくるサンプルコードを写経しながら理解を深めつつ、たまにKaggleに挑戦し挫折したりしています。

この記事では、とりあえず何か成果を出してモチベーションを上げたい私が、マネージドの機械学習サービス(Amazon Forecast)にデータの前処理やモデル設計などをお任せして、電気料金の予測モデルを構築、簡単な評価までを記載します。

※1 本文内に記載する学習データ内の数値はサンプルです
※2 初学者のため関連用語の用法が誤っている可能性があります、ご容赦ください

## Amazon Forecastとは
AWS公式ウェブサイト[^1]より抜粋

> Amazon Forecast は、機械学習を使用して精度の高い予測を行うフルマネージドサービスです。
> Amazon.com と同じテクノロジーをベースとし、機械学習を使って時系列データを付加的な変数に結びつけて予測を立てます。
> 必要なのは過去のデータと、予測に影響を与える可能性があるその他の追加データだけです。
> ユーザーがデータを提供すると、それを自動的に精査し、何が重要かを識別して、予測を立てるための予測モデルを作成します。


## 目標
2020年9月の1日ごとの電気料金を予測する
精度が高いともちろん嬉しいですが最低限それっぽい予測ができること

## 学習に使用するデータ
今回は予測したい電気料金の情報に加えて、追加データとして同期間の天候に関する情報を与えます。

- 過去の電気料金
    - 2019年1月1日〜2020年8月31日の電気料金 - elec_data.csv

```elec_data.csv
# CSVサンプル

id,ymd,cost
0,2019-01-01,11
0,2019-01-02,22
0,2019-01-03,33
︙
0,2020-08-29,44
0,2020-08-30,55
0,2020-08-31,66
```

- 自宅付近の過去の天候データ(気象庁公開のデータ[^2]を使用) - weather_data.csv
    - 最高気温、平均気温、最低気温 [℃]
    - 降水量 [mm]
    - 日照時間 [時間]

```weather_data.csv
# CSVサンプル

id,ymd,max_temp,avg_temp,min_temp,precip,day_length
0,2019-01-01,10.0,4.0,-4.0,0.0,7.0
0,2019-01-02,10.5,4.5,-3.0,5.0,7.5
0,2019-01-03,11.0,5.0,-2.0,10.0,7.2
︙
0,2020-08-29,34.0,30.0,25.0,5.0,10.0
0,2020-08-30,34.5,30.5,25.5,10.0,7.3
0,2020-08-31,35.0,31.0,26.0,15.0,8.5
```

## 学習
ここから上記データを使用して実際にモデル構築のための学習に入ります。
インポートの際はS3上のパスで指定するため、事前にCSVファイルをアップロードしておきます。

### データセットグループの作成
データをインポートする際、データセットグループに対して使用データを指定する形となります。
電気料金の予測モデル構築がゴールのため、`Forecasting domain`は`Custom`としました。
（上記設定についての詳細は [こちら](https://docs.aws.amazon.com/ja_jp/forecast/latest/dg/howitworks-domains-ds-types.html) をご覧ください）

### データセットのインポート
予測対象データのインポート画面に移るので、一部設定を更新します

- `Frequency of your data` - **1 day**
- `Data schema` - CSVのスキーマに合わせて修正
- `Timestamp format` - **yyyy-MM-dd**
- `Data location` - S3上の`elec_data.csv`のパスを入力

続けて、Related time series data > Import から天候データのインポートをします

- `Data location`にS3上の`weather_data.csv`のパスを入力

以上でデータセットのインポートが完了します。

### 学習の開始
両方のデータセットの状態が Active になったのを確認し、Predictor training > Start から学習を開始します。
要件が `2020年9月の1日ごとの電気料金を予測する` であることを考慮し、30日分のデータ返却する予測器を作成します。
- `Forecast horizon` - **30**
- `Forecast frequency` - **1 day**
- `Algorithm selection` - **AutoML**
- `Country for holidays` - **Japan**


各項目の詳細は、これまたAWSの公式サイト[^1]を参照ください
（なおAutoMLについては 数種類のアルゴリズムの中から最適なものを選定してモデル構築してくれる くらいの理解しかありません）

![image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/59182ce6-b105-009d-1d2b-99b153c46747.png)

## 予測の作成と取得
### 予測の作成
少し待つと学習が完了し、Predictor trainingの状態が Active となります
AutoMLによって作成されたモデルを使用し、予測結果を取得します。

Forecast generation > Start

- `Predictor` - 前のステップで作成した予測器を選択

上記設定後 Create Forecast を選択し、予測結果を出力できるようになるまで待ちます
（`Lookup forecast`と`Create a forecast`が選択できるようになっていればOK）
![スクリーンショット 2020-09-22 21.31.27（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/ac843fbd-0b84-0345-b2ad-438d722ed5a3.png)

### 予測の取得
実際に予測結果を見てみます
`Lookup forecast`から必要な情報を入力し、1ヶ月分の予測結果を表示します（`Get Forecast`）

- `Forecast` - 前のステップで作成した予測
- `Start date` - 2020/08/31 00:00:00
- `End date` - 2020/09/30 00:00:00
- `Forecast key` - item_id:0

![ap-northeast-1.console.aws.amazon.com_forecast_home_region=ap-northeast-1 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/e16e3fc1-35fd-a08a-3cc0-04caf0cdd503.png)
出ました

## 評価
最後、上記の予測と実際の電気料金(~9/15)を比較してみたいと思います
![example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463957/f49b69cf-465f-4677-3987-f7f8a06c0123.png)
Oh... 軸名を書くのすら面倒になるほど外れてました…


## 一旦まとめ
- 管理画面上でポチポチするだけ、（とりあえず）ノンコーディングで回帰モデルが作れました

## 反省
**前提条件の異なるデータが訓練データに含まれていた**
3月以降、在宅勤務がメインとなり、その分自宅にいる時間が大幅に増えました
それ以前は平日には出社していたので、データを準備しながらうすうす 去年のデータ全然参考にならないんじゃ… と思ってましたが、少なくとも曜日による重みはほぼ無意味になっているはず…

**予測対象とは別に与えた関連データ（天候データ）が不足していた**
[こちら](https://dev.classmethod.jp/articles/amazon-forecast-improvement-by-option-dataset/)の記事にありますが、予測する期間も含めたデータが必要だったようです、ウワー
上のよりこちらのほうが影響大きそう

[^1]: [Amazon Forecast](https://aws.amazon.com/jp/forecast/)
[^2]: [気象庁 過去の気象データ](https://www.data.jma.go.jp/gmd/risk/obsdl/index.php)