機械学習で電力需要予測をしてみる

  • 49
    Like
  • 0
    Comment

はじめに

機械学習でどのくらい電力需要を予測できるのか試してみたので、その手順を整理します。

追記

この記事を書いてから半年が経ち、いろいろ新しいこともわかってきたので、パート2の記事を書いてみました。
機械学習で電力需要を予測してみる パート2

使用した環境

機械: MacBook Air Mid 2012
言語: Python 3.5.1
実行: Jupyter notebook 4.2.1
ライブラリ: scikit-learn on Anaconda 4.1.0

データ収集

電力需要

まずは東京電力のサイトから電力需要のデータをダウンロードします。

http://www.tepco.co.jp/forecast/html/download-j.html
※2016/8/12現在、2016/4/1〜8/11の一時間毎のデータをダウンロードできました。

ファイル名は"juyo-2016.csv"でした。
ダウンロードしたデータは日付、時刻、電力実績のCSVですが、少し余計な文字列が入っているので、修正してUTF-8で保存します。

気温

次に何か参考資料ないかな〜と探してみると、気象庁から過去の気象データがダウンロードできたので、電力需要のデータと同じ期間・間隔のデータをダウンロードします。

http://www.data.jma.go.jp/gmd/risk/obsdl/index.php

ファイル名は"data.csv"でした。
ダウンロードしたデータは日時、気温、品質情報、均質番号のCSVですが、少し余計な文字列が入っているので、修正してUTF-8で保存します。

データ取り込み

import pandas as pd
import numpy as np

# 電力データの読み込み
kw_df = pd.read_csv("juyo-2016.csv")

# 気温データの読み込み
temp_df = pd.read_csv("data.csv")

データ加工

機械学習にかけるにあたり、データを結合したり、機械学習用に数値データへ変換する作業を行います。
まず、日付データはそのままでは使い物にならないので、曜日データに変換してみます。

[例]
日曜日 -> 0
月曜日 -> 1
...とか

次に、1時間毎のデータなので、時間をデータに変換します。

[例]
0:00 -> 0
1:00 -> 1
...とか

# データの結合
df = kw_df
df["気温"] = temp_df["気温(℃)"]

# 曜日データの取得

import datetime

pp = df["DATE"]
tmp = []

for i in range(len(pp)):
    d = datetime.datetime.strptime(pp[i], "%Y/%m/%d")
    tmp.append(d.weekday())

df["weekday"] = tmp

# 時間データの取得

pp = df["TIME"]
tmp = []

for i in range(len(pp)):
    d = datetime.datetime.strptime(pp[i], "%H:%M")
    tmp.append(d.hour)

df["hour"] = tmp

学習データとテストデータの作成

加工したデータから学習用のデータとテスト用のデータを作成します。
ここでは、入力に使用するパラメータは"気温","曜日","時刻"として、出力されるパラメータを"電力"とします。
加工したデータの並びは、"DATE","TIME","実績(万kW)","気温","weekday","hour"となっているので、入力パラメータを3,4,5列目から取得し、出力は実績(万kw)の2列目を利用します。
また、機械学習用にデータを正規化します。

# 入力
pp = df[[3, 4, 5]]
X = pp.as_matrix().astype('float')

# 出力
pp = df[[2]]
y = pp.as_matrix().flatten()

# クロスバリデーションのモジュールを読み込む
from sklearn import cross_validation

# ラベル付きデータをトレーニングセット (X_train, y_train)とテストセット (X_test, y_test)に分割
X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=.2, random_state=42)

# 正規化のモジュールを読み込む
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(X_train)

X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

学習

SVMで機械学習してみます。

# モジュールの読み込み
from sklearn import svm
model = svm.SVC()

# 学習
model.fit(X_train, y_train)
# model.score(X,y)を使って予測精度を出す
print(model.score(X_test,y_test))

予測スコアは、何と「0.00312989045383」!!
あまりのスコアの低さにびっくり!!
ダメじゃん!って思うじゃないですか...

予測結果の確認

どんな感じなのか確認するために、グラフを描画して確認してみました。

# 誤差計算
pp = pd.DataFrame({'kw': np.array(y_test), "result": np.array(result)})
pp["err"] = pp["kw"] - pp["result"]

pp.plot()

Unknown.png

何だか、それなりに追従してそうな感じ(^-^)
予測結果を実際の数値で確認。

err_max = 0
err_min = 50000
err_ave = 0

for i in range(len(pp)):
    if err_max < pp["err"][i]:
        err_max = pp["err"][i]
    if err_min > pp["err"][i]:
        err_min = pp["err"][i]
    err_ave += pp["err"][i]

print(err_max)
print(err_min)
print(err_ave / i)

実行結果は、以下のとおり。

1571
-879
114.81661442

うーん、この結果はどうなんだろう。良いのか悪いのか、判断できない...(-_-;)

実際はもっと考えないといけないことあるんだろうけど、過去データの少ない状況で電力需要予測をしないといけないようなことがあったら、そこそこ参考になる結果なのではないかと思ったりしました。

ちなみに、Jupyter Notebookのファイルと加工後のCSVファイルをGitHubに公開したのであわせてご参照下さい。

https://github.com/shinob/predict_kw