"BOKU"のITな日常

BOKUが勉強したり、考えたことを頭の整理を兼ねてまとめてます。

気象情報と電力データを使ったランダムフォレストで回帰するサンプル/その2(改善挑戦版)

f:id:arakan_no_boku:20190808232239p:plain

目次

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

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

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

arakan-pgm-ai.hatenablog.co

まあ、なんというか微妙な結果でした。

f:id:arakan_no_boku:20190809221047p:plain

 

そこで、今回は

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

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

ランダムフォレストのソース

ベースにするソースはほぼ前回と同じです。

学習データの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()
 

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

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

 

対策1: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

対策2:重要度の低かった降水量などの特徴量を省く

上記のデータを使って、かつ、特徴量を調整しながら決定係数を計算します。

決定係数は回帰分析の当てはまりが良い(目的変数が十分に説明されているという表現で書かれていることも多いですが)かどうかを数値化したもので、0以上1以下の値で、値が大きいほうが当てはまりが良いそうです。

正直、目安はよくわかりませんので、0.5を超えると当てはまりが良いと聞いたことがありますので、いったん、それを目安としてやってみます。

前回の決定係数が「0.46765316988936834」だったので、これをまずスタートラインとします。

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

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。

今まででで一番高くなり、かつ、目安の0.5を超えました。

特徴量を「最低気温と最高気温だけ」にするのは、かなり有効です。

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

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

f:id:arakan_no_boku:20190810152343p:plain

決定係数は0.5985709419346581です。

今回、一番成績のよく、目安の0.5を大幅に超えています。

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

おそらく、学習データの期間をもっと絞り込んで過去のさかのぼり年数を増やすとか、すれば、かなり、予想精度をあげられそうな感触はあります。

ですが、まあまあ、良い結果がでたので、今回はこのへんで満足してとめておきます。

ではでは。