"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

ランダムフォレストで回帰してみる/気象情報と電力データその2

気象実績と、関西電力の使用量という現実のデータでランダムフォレストで予測をやってみた前回の結果をもとに、もう少し精度があがらないかやってみます。

f:id:arakan_no_boku:20190808232239p:plain

 

前回のおさらいと残った課題

 

善回は、以下の学習とテスト用データを用意しました。

  •  学習データ:2018/6/1~2019/6/30の1年分の気象+電力使用量
  • テストデータ:2019/7/1~2019/7/31の1月分の気象+電力使用量

実行してみた結果はこんな感じでした。

まず決定係数

0.46765316988936834

実績(青線)と予測値(赤線)の比較グラフ。 

f:id:arakan_no_boku:20190809221047p:plain

特徴量の重要度。

f:id:arakan_no_boku:20190809221547p:plain

この結果から。

  • 1年間のデータではなく夏場だけのデータで学習させたほうが良いのでは?
  • 重要度の低かった降水量などの特徴量を省いた方が結果が良いのでは?

こういう仮説をたててみました・・ってのが前回です。

arakan-pgm-ai.hatenablog.com

 

今回やってみたこと

 

まず、データを2016年から2018年の6月から9月にしました。

期間を選ぶ方法でがそれに対応しているので一発でおとせます。

f:id:arakan_no_boku:20190810133317p:plain

4か月×3で丁度12月(1年分)です。

ほんとは、12年分の7月度でやった方がよいのかもしれないですが、まあ、あまり変わらないだろうという判断で(手抜き・・)しました。

それにあわせて、関西電力のデータも該当する期間分おとしなおしました。

データをまとめる方法は、以下の記事のとおりです。

arakan-pgm-ai.hatenablog.com

arakan-pgm-ai.hatenablog.com

 

特徴量を増減させながらやってみます

 

あとは、特徴量を増減させながら、いろいろ試します。

ベースにするソースはほぼ前回と同じで、学習データのCSVファイルの名前と、ドロップする列のヘダー名を変更しているだけです。

sk_rf_summer_kansai.py

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import r2_score


# 学習データCSVファイル読み込み
df_train_all = pd.read_csv('train_summer_kanden.csv')
# 最大電力量を目的変数(ターゲット)にする
y_train = df_train_all[u'電力量(最大)'].values.tolist()
# 不要な列を切り落として説明変数にする
data_train = df_train_all.drop(
    [u'年月日', u'電力量(最大)', u'降水量の合計(mm)', u'電力量(最小)', u'平均風速(m/s)'], axis=1)
x_train = data_train.values.tolist()
# テスト用データCSV読み込み
df_test_all = pd.read_csv('test_kanden.csv')
# 最大電力量を目的変数(ターゲット)にする
y_test = df_test_all[u'電力量(最大)'].values.tolist()
# 不要な列を切り落として説明変数にする
data_test = df_test_all.drop(
    [u'年月日', u'電力量(最大)', u'降水量の合計(mm)', u'電力量(最小)', u'平均風速(m/s)'], axis=1)
x_test = data_test.values.tolist()
# ランダムフォレスト回帰オブジェクト生成
rfr = RandomForestRegressor(n_estimators=100)
# 学習の実行
rfr.fit(x_train, y_train)
# テストデータで予測実行
predict_y = rfr.predict(x_test)
# R2決定係数で評価
r2_score = r2_score(y_test, predict_y)
print(r2_score)
# 特徴量の重要度を取得
feature = rfr.feature_importances_
# 特徴量の名前ラベルを取得
label = data_train.columns[0:]
# 特徴量の重要度順(降順)に並べて表示
indices = np.argsort(feature)[::-1]
for i in range(len(feature)):
    print(str(i + 1) + "   " +
          str(label[indices[i]]) + "   " + str(feature[indices[i]]))

# 最大電力量の実績と予測値の比較グラフ
plt.subplot(121, facecolor='white')
plt.title('7月の電力量')
plt_label = [i for i in range(1, 32)]
plt.plot(plt_label, y_test, color='blue')
plt.plot(plt_label, predict_y, color='red')
# 特徴量の重要度の棒グラフ
plt.subplot(122, facecolor='white')
plt.title('特徴量の重要度')
plt.bar(
    range(
        len(feature)),
    feature[indices],
    color='blue',
    align='center')
plt.xticks(range(len(feature)), label[indices], rotation=45)
plt.xlim([-1, len(feature)])
plt.tight_layout()
# グラフの表示
plt.show()
 

さて。 

前回とほぼ同じなので、ソースの補足はしません。

特徴量を入れ替えながら、いろいろ試した結果だけを書いていきます

 

特徴量を入れ替えてみた結果など

 

まず、降水量のみはぶいてみました。

f:id:arakan_no_boku:20190810135457p:plain

決定係数は、0.4861939505909959 でした。

次に平均湿度を省いてみます。

f:id:arakan_no_boku:20190810135823p:plain

決定係数は0.39635172053967527、

下がってしまいました。

今度は、最低気温と最高気温だけにしてみます。

f:id:arakan_no_boku:20190810140206p:plain

決定係数は0.5295154777376303。

今まででは一番高いですけどね・・。

まあ。

わかったことは、最大電力消費量は、気象情報だけの要素では、なかなか予測精度を高くするのは難しそうだ・・ということですかね。

たぶん、曜日や休日か否か・・、工場なんかの稼働状況など、もっと説明変数を増やしていかないとな・・って感じです。

最後に。

説明変数に「最小電力量」を追加してやってみます。

ドロップ列は「[u'年月日', u'電力量(最大)', u'降水量の合計(mm)', u'平均湿度(%)', u'平均風速(m/s)']」てな感じ。

f:id:arakan_no_boku:20190810152343p:plain

決定係数は0.5985709419346581です。

あまり大したことはありません。

でも、グラフだと、かなり予測できてる感じになりました。

考えてみれば。

最小電力量ってその日の0:00から3:00くらいの真夜中に来ることがほとんどなので、それと気象予報データを使って、その日のピーク電力量を予測する・・ってのも、まあ、それっぽいですし、これもありかもしれません。

今回はこんなところで。

ではでは。