snovaのブログ

主にプログラミングやデジタルコンテンツについて書きます。最近はPython, Flutter, VRに興味があります。

日付データと気象データから使用電力を予測(PyCaret)

はじめに

地震の影響により関東東北で停電の可能性があるというニュースの中で、使用電力と供給電力の予測値が出ていました。 比較的簡単にできると思ったので、機械学習の再勉強も兼ねて、実際に自分で東京電力管内の使用電力の予測をしてみました。

また、個人的にこれまでしたことないことにチャレンジしたいと思ったのでAutoMLのPyCaretGoogle Colab上で実行しました。

データの種類について

使用される電力は一般的に以下の特徴があります。

  • 季節性がある(夏や冬は冷暖房の影響で電力使用量が比較的高くなる)
  • 時間依存性がある(昼は夜に比べ電力使用量が高くなる)
  • 天候や気温に依存する
  • 政治や経済の状況に依存する

長期的には、技術革新によっても電力が変化します。

上記のデータのうち、今回は取得しやすい日付時間データ気象データを使って、使用電力の予測をしました。

開発環境

ハード or ソフト バージョン 備考
macbook air m1 2020
macOS Monterey 12.2.1
Google Colab アクセラレータはCPU
python 3.7.13
pycaret 2.3.8 機械学習のため
jpholiday 0.1.8 祝日取得のため

データの取得

使用電力の過去のデータは東京電力 - 過去の電力使用実績データのダウンロードより入手します。 電力使用実績は2016年から入手可能でしたので、2016/04/01から2021/12/31までのデータを取得しました。

過去の天気情報は気象庁 - 過去の気象データ・ダウンロードより入手します。 今回は代表地点の東京の気象データを取得しました。

余談ですが、いずれのサイトもAPIが整備されていないので、データの取得は手動またはwebスクレイピングでデータを取得する必要があります。 (気象庁のデータについては一度にダウンロードできるデータが少ないです。) 公共で使用できるオープンデータはAPIが使えると便利なのですが。。。

取得したデータの確認

取得したデータの確認をします。 2021年のある夏の日の電力データです。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

filename = 'elec_data.csv'
csvreader = pd.read_csv(filename, delimiter=',', dtype='str', skiprows=1)
csvreader_datetime = np.array(csvreader.values[0:24, 1], dtype='object')
csvreader_val = np.array(csvreader.values[0:24, 2], dtype='int')

plt.plot(csvreader_datetime, csvreader_val)
plt.xticks(rotation=45)
plt.xlabel('Time')
plt.ylabel('Used Electrocity(x10MW)')
plt.show()

夏の場合、昼間に冷房を使用するので、1日の中でも画像のような使用電力の差が出ます。

続いて、2021年の気温データを表形式で確認してみます。

filename = 'Tmp_data.csv'
csvreader = pd.read_csv(filename, encoding='Shift-JIS' ,delimiter=',', dtype='str', skiprows=1)
print(csvreader)

天気や気温の数値の意味は気象庁のHPを参照ください。

学習用データの作成

今回、学習とテストで使用する変数をまとめます。

目的変数(1変数)

変数名 備考
使用電力 float 東京電力の1時間データ

説明変数(9変数)

変数名 備考
int
int
int
曜日 int
祝日 int 祝日なら1、平日や土日なら0
時間 int 24時間表記
気温 float
風速 float
天気 int 気象庁のデータ表現に準ずる

学習データ作成のためpandasでデータを整形します。 欠損値の補完はpandasinterpolatebfillffillを使用します。

曜日の情報取得はpandasto_datetimeを利用しました。

データの結合はpandasDataFrame形式から、concatで結合します。 pandasmergeは同じ要素を持っていないとできないので少し時間を取られました。

Google Colabの無料版は制限がありますので、データは一度Google Driveに保存しておきます。 個人的にtsvが好みなので、pandasto_csvを使ってtsvで保存します。

学習モデルの作成

学習と評価にはPyCaretを使用します。 今回は回帰問題を解くので、pycaret.regressionを使用します。

from pycaret.regression import *

setup関数は訓練環境の初期化を行うもので、dataにはpandasDataFrameを入れ込み、targetには目的変数の名称を入れます。

exp = setup(tsvreader_data, target='Used Elec (x10 MW)')

compare_models関数はPyCaretで使用できる回帰分析手法(線形回帰、LightGBMなど)で学習と評価を行い、比較することができます。

compare_models()

どの手法を使用するか決定したら、create_model関数で学習モデルを作成します。 このとき、引数にcreate_model(‘lr’)などのようにモデルのIDを入れますが、何がどのモデルを示しているかは公式ドキュメントを参照ください。 今回はlightGBMを選択しました。

pycaret_create_model = create_model('lightgbm')

モデルを調整したい場合は、tune_model関数を使用します。

pycaret_tune_model = tune_model(pycaret_create_model)

なお、finalize_model関数というのがありますが、いまいちなぜ使用するのか分かりませんでした。。。

学習モデルの評価

モデルが作成できたら、evaluate_modelで学習結果を可視化します。 学習データに対するMAE(平均絶対誤差)は60前後で、今回のレンジが3000-4000あたりなので、だいたい誤差の平均割合が1-2%程度となっています。

evaluate_model(pycaret_tune_model)

特徴量の重要度も簡単に確認できるので、見てみます。

また、事前に抜き出しておいたデータと予測データを比較してみます。 predict_model関数は学習モデルとテスト用データ(pandasDataFrame形式)を渡すことで、予測値を計算してくれます。

同時に、matplotlibで可視化してみます。 概ね傾向は出ていますが、日時データと気象データだけでは細かいところが合ってきませんね。

pred_ = predict_model(pycaret_final_model, data = test_data)
fig, ax = plt.subplots()
ax.plot(pred_['Used Elec (x10 MW)'], color='red', label='Prediction Value')
ax.plot(pred_['Label'], color='blue', label='True Value')
ax.axes.xaxis.set_visible(False)
ax.legend()

なお、Google Colab上では学習と評価で2分程度の時間がかかりました。

モデルの保存と読込

pycaret.regressionにはsaveloadが用意されています。

# モデルの保存
lr = create_model('lr')
save_model(lr, 'saved_lr_model')

# モデルの読込
saved_lr = load_model('saved_lr_model')

なお、PyCaretに依存せずにデータを保存する方法として、pickelを使う方法があります。

import pickle

# モデルの保存
lr = create_model('lr')
pickle.dump(lr, open('saved_lr_model', 'wb'))

# モデルの読込
saved_lr = pickle.load(open('saved_lr_model'), 'rb'))

プログラム全体

Githubで共有します。

github.com

まとめ

日付データと気象データから東電管内の電力需要を予測しました。 PyCaretを使用することで、機械学習部分は数行で完結しました。 概ね傾向は出ていますが、細かい部分でズレが生じています。

今後は、以下のことに取り組みたいです。

  • 政治や経済に関するデータ(コロナ発生状況や株価など)も説明変数に入れて学習
  • FirebaseやFlutterと連携できないか考える(現時点ではちょっと難しそう?)

最後に、今回の感想ですが、、、PyCaretはとても簡単で驚きました。

参考サイト

Google Play and the Google Play logo are trademarks of Google LLC.