1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RNNを用いた気温の予測

Last updated at Posted at 2020-07-21

とある課題でRNNを使った気温の予測をしようと思ったのですが、(詳しくは後述しますが)結果が微妙だったので没になりました。なので、ここで没供養させていただければと思います。

概要

気象庁の観測データを基にRNNを使用して平均気温の将来予測をします。
得られたデータをちょっと考察します
筆者が実行したコードは github においてあります

ライブラリのインポート

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score

from keras.layers.recurrent import SimpleRNN
from keras.models import Sequential
from keras.optimizers import Adam
from keras.layers import Dense, Activation
from tensorflow.keras.callbacks import EarlyStopping

ここは特に言うことはないですかね

データの取得

データは 気象庁のHP からダウンロードできます。ちなみに筆者は諸事情で別に入手しました
ダウンロードしたデータには品質情報と均質番号があると思いますが、これは基本的に無視して大丈夫です。
あと一度にダウンロードできるデータ数に制限があるので、20年ごとに分割してダウンロードしたものをpandasで結合しました。


# 読み込み
tokyo1=pd.read_csv("data/tokyo_1961-1980.csv", header=2,skiprows=[4],encoding="shift-jis",parse_dates=["年月日"])
tokyo2=pd.read_csv("data/tokyo_1981-2000.csv", header=2,skiprows=[4],encoding="shift-jis",parse_dates=["年月日"])
tokyo3=pd.read_csv("data/tokyo_2001-.csv", header=2,skiprows=[4],encoding="shift-jis",parse_dates=["年月日"])
tokyo=pd.concat([tokyo1, tokyo2, tokyo3], ignore_index=True)
tokyo=tokyo.sort_values("date", ignore_index=True)
tokyo["year"]=tokyo["年月日"].dt.year

日時情報をdatetime型にしたいのでparse_dates=["年月日"]としています。なお筆者はこのコードで実行していないのでどっか間違ってたらごめんなさい

データの整形

#整形
tem=tokyo["avtem"]
timesteps = 20

x = np.empty([len(tem)-timesteps, timesteps], dtype=np.float32)
y = np.empty(len(tem)-timesteps, dtype=np.float32)

for i in range(len(x)):
    x[i] = tem[i:i+timesteps].T
    y[i] = tem[i+timesteps]

data_len = timesteps*int(len(x)/timesteps)

x = x[:data_len].reshape(data_len,timesteps,-1)
y = y[:data_len].reshape(data_len,-1)
x_train=x[:21164]
y_train=y[:21164]
x_test=x[21164:21529]
y_test=y[21164:21529]

データの整形は これ を参考にしました。
trainデータは2018年までのもの、testデータは2019年のものを手動で行番号を探して取り出しました(1961年1月1日からのデータを用いると同じ行数になると思います)。

モデルの作成

#モデルの作成
model = Sequential()
model.add(SimpleRNN(50, input_shape=(timesteps, 1), kernel_initializer='random_normal'))
model.add(Dense(1))
model.add(Activation('linear'))

model.compile(loss='mean_squared_error', optimizer=Adam(lr=0.01, beta_1=0.9, beta_2=0.999))
early_stopping = EarlyStopping(monitor='val_loss', mode='auto', patience=3)
model.fit(x_train, y_train, batch_size=1024, epochs=20, validation_split=0.1,callbacks=[early_stopping])

y_pred = model.predict(x_test)
print("RMSE:",np.sqrt(mean_squared_error(y_test, y_pred)))
print("r2  :",r2_score(y_test,y_pred),"\n")

モデルの作成では これ を参考にしました。trainデータ数が2万以上あったので、バッチサイズ512と大きめに設定しています。
これを実行すると、12回ぐらいで精度が上がらくなり、スコアは、

  • RMSE: 2.0795848
  • r^2 : 0.9290615357147783

でした。 気象庁の予測精度 が最高気温でRMSE1.5強なので精度があまりよくないことがわかります。
特にちょっと考えてもらえばわかると思いますが平均気温は最高気温に比べてぶれにくいので平均気温でこんだけの誤差が出てしまうのではちょっと使い物にならない感がすごいです。なお、実際にこのプログラムを最高気温でやってみるとRMSE3.2程度でした。

考察(というほどでもないですが)

テストデータ(2019年)の気温予測と実際の値を比較してみました。
pic.png
主に上下に大きく変動しちゃったとこが予測できていないことがわかります。これは過去のデータから傾向で予測しているという都合上しょうがないと思います。
そもそも気温というか天気は気圧配置などに影響されるわけで、それに明確にパターンが決められているのかといえばそうではない気がするので、気象庁は様々な観測データから数値計算して気温を求めてるのでパターンがなくても予測することが可能であることを考えると、RNNでそこまでの精度は出ないのかなという気がします。

ちなみにもっと一部分を拡大してみるとこんな感じでした。
image.png
いや、予測しているというより、前日の観測データの後追いしてるだけやん

参考文献

1
6
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
1
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?