LoginSignup
41
70

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-01-15

はじめに

以前、同名のタイトルで投稿してからずいぶんと日数が経過し、少し熟れてきたので再度投稿してみます。

追記

2017/12/22に以下の記事を作成したので、あわせてご参照下さい。
TensorFlowで電力使用量予測 with Keras

データ収集

電力需要

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

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

また、URLを変更すると2014年のデータも入手できました。

http://www.tepco.co.jp/forecast/html/images/juyo-2014.csv
※2017/1/14現在、2015年のデータはからっぽでデータが入っていませんでした。

ダウンロードしたデータは日付、時刻、電力実績のCSVとなっています。

ちなみに以下のコマンドで取得することもできそうです。

$ curl -O http://www.tepco.co.jp/forecast/html/images/juyo-2014.csv
$ curl -O http://www.tepco.co.jp/forecast/html/images/juyo-2016.csv

気温

前回同様に、気象庁から過去の気象データをダウンロードします。

地点は「東京」、項目は「時別値」「気温」、期間は2013/12/31〜2015/1/1と2015/12/31〜2017/1/1とし、data-2014.csv、data-2016.csvという名前で保存します。
ここで、少し長めの期間を選択しているのは、後で期間を絞って取り込むためです。

ダウンロードしたデータは日時、気温、品質情報、均質番号というデータの入ったCSVです。

ちなみにこれは普通にサイトからダウンロードするのが早そうです。

データ読込

ライブラリ

import pandas as pd
import numpy as np
import datetime as dt
import math

電力需要

まず、2014年の電力データを読み込みます。

filename = "juyo-2014.csv"

# 文字コードがシフトJISで、不要な行を飛ばして読み込む
df = pd.read_csv(filename,encoding="SHIFT-JIS",skiprows=2)

# 列名を変換
df.columns = ["DATE","TIME","KW"]

# 日付と時間のデータが分かれているので、一つにつなげて日時型に変換し、インデックスに指定
df.index = df.index.map(lambda x: dt.datetime.strptime(df.loc[x].DATE + " " + df.loc[x].TIME,"%Y/%m/%d %H:%M"))

# 月データの取得
df["MONTH"] = df.index.month

# 曜日データの取得
df["WEEK"] = df.index.weekday

# 時間データの取得
df["HOUR"] = df.index.hour

df_kw = df

気温

次に、2014年の気温データを読み込みます。

filename = "data-2014.csv"

# 文字コードがシフトJISで、不要な行を飛ばし、必要な2列のみ取得
df = pd.read_csv(filename,encoding="SHIFT-JIS",skiprows=4)[[0,1]]

# 列名を変換
df.columns = ["DATE","TEMP"]

# 日時データを日時型に変換してインデックスに指定
df.index = df.index.map(lambda x: dt.datetime.strptime(df.loc[x].DATE,"%Y/%m/%d %H:%M:%S"))

df_temp = df

電力需要と気温のデータを結合

d1 = df_kw.index.min()
d2 = df_kw.index.max()

df_kw["TEMP"] = df_temp.ix[d1:d2].TEMP

データの加工

機械学習に用いる入力データと出力データを取得します。
予測するのは電力需要なので、出力はKW列、入力はMONTH、WEEK、HOUR、TEMP列とします。

# 入力に使用するデータ列の指定
X_cols = ["MONTH","WEEK","HOUR","TEMP"]

# 出力に使用するデータ列の指定
y_cols = ["KW"]

# 入力・出力データの取得
X = df_kw[X_cols].as_matrix().astype('float')
y = df_kw[y_cols].as_matrix().astype('int').flatten()

学習データと検証データに分割します。

from sklearn import cross_validation

X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=.1, 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)

学習

回帰モデルで学習します。

from sklearn.ensemble import RandomForestRegressor

model = RandomForestRegressor()
model.fit(X_train, y_train)

予測

分割したテストデータを使ってスコアを計算します。

print(model.score(X_test,y_test))

スコアは「0.91601162513664502」でした(^-^)

予測結果の確認

予測結果と実データをグラフ化し、確認してみます。

# 予測結果
result = model.predict(X_test)

# データフレームに変換
df_result = pd.DataFrame({
    "y_test":y_test,
    "result":result
})

# グラフライブラリ
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt

# グラフ描画
df_result.plot(figsize=(15, 3))

Unknown.png

当たってるようなんだけど、どうなのかいまいちよくわからない。

データ数を減らして再確認。

# グラフ描画
df_result[:20].plot(figsize=(15, 3))

Unknown.png

いい感じじゃないですか!

2016年のデータを使って予測

データ読込

2014年のデータと同じ手順で2016年のデータを読み込みます。

# 電力需要
filename = "juyo-2016.csv"

df = pd.read_csv(filename,encoding="SHIFT-JIS",skiprows=2)
df.columns = ["DATE","TIME","KW"]
df.index = df.index.map(lambda x: dt.datetime.strptime(df.loc[x].DATE + " " + df.loc[x].TIME,"%Y/%m/%d %H:%M"))
df["MONTH"] = df.index.month
df["WEEK"] = df.index.weekday
df["HOUR"] = df.index.hour

# 4月分に限定して利用
df_kw = df[df.index.month == 4]

# 気温
filename = "data-2016.csv"

df = pd.read_csv(filename,encoding="SHIFT-JIS",skiprows=4)[[0,1]]
df.columns = ["DATE","TEMP"]
df.index = df.index.map(lambda x: dt.datetime.strptime(df.loc[x].DATE,"%Y/%m/%d %H:%M:%S"))

df_temp = df

# データ結合
d1 = df_kw.index.min()
d2 = df_kw.index.max()
df_kw["TEMP"] = df_temp.ix[d1:d2].TEMP

データ加工

# 入力・出力データの取得
X = df_kw[X_cols].as_matrix().astype('float')
y = df_kw[y_cols].as_matrix().astype('int').flatten()

X_test = scaler.transform(X)
y_test = y

予測

2014年のデータで学習したモデルを使用して予測し、スコアを計算します。

model.score(X_test,y_test)

結果は、少し落ちて「0.82435418225963963」でした。

予測結果の確認

# 予測結果
result = model.predict(X_test)

# データフレームに変換
df_result = pd.DataFrame({
    "y_test":y_test,
    "result":result
})

# グラフ描画
df_result.plot(figsize=(15, 3))

Unknown.png

もう少し工夫が必要ですね(-_-;)

41
70
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
70