"BOKU"のITな日常

62歳・文系システムエンジニアの”BOKU”は日々勉強を楽しんでます

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

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

f:id:arakan_no_boku:20190808232239p:plain

 

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

 

前回の結果はこちらです。 

arakan-pgm-ai.hatenablog.co

あまり、良い結果ではありませんでした。

f:id:arakan_no_boku:20190809221047p:plain

 

そこで、今回は

  • 1年間のデータではなく夏場だけのデータで学習させる
  • 重要度の低かった降水量などの特徴量を省く

という対策を施して、再チャレンジします。

 

今回やってみたこと

 

データを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です。

今回、一番成績のよかったものがこれです。

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

おそらく、学習データの期間をもっと絞り込んで過去のさかのぼり年数を増やすとか、電力消費に影響をあたえそうなほかの要素(例えば、平日・休日フラグとか)を付け加えていくと、もう少し精度があげられるかな?という気はしましたが、今回はこのへんでとめておきます。

ではでは。