時系列データをRNNで扱うサンプルです。過去の気温から未来の気温予想を予測します。
以下のサンプルはGoogle Colaboratory上で実行しています。
気象データセットのダウンロードします。
ちなみに !<command>
のようにするとnotebook上でコマンドが使えます。
!wget https://s3.amazonaws.com/keras-datasets/jena_climate_2009_2016.csv.zip !unzip jena_climate_2009_2016.csv.zip
ロードしてヘッダーとデータ数を確認します。
import os fname = 'jena_climate_2009_2016.csv' f = open(fname) data = f.read() f.close() lines = data.split('\n') header = lines[0].split(',') lines = lines[1:] print(header) print(len(lines))
import numpy as np float_data = np.zeros((len(lines), len(header) - 1)) for i, line in enumerate(lines): values = [float(x) for x in line.split(',')[1:]] float_data[i, :] = values
とりあえずプロットしてみます。縦軸は摂氏温度、横軸は10分ごとの時系列です。
from matplotlib import pyplot as plt temp = float_data[:, 1] plt.plot(range(len(temp)), temp)
過去の期間(lookback)を見て、先のポイント(delay)を予測します。
def generator(data, lookback, delay, min_index, max_index, shuffle=False, batch_size=128, step=6): if max_index is None: max_index = len(data) - delay - 1 i = min_index + lookback while 1: if shuffle: rows = np.random.randint(min_index + lookback, max_index, size=batch_size) else: if i + batch_size >= max_index: i = min_index + lookback rows = np.arange(i, min(i + batch_size, max_index)) i += len(rows) samples = np.zeros((len(rows), lookback // step, data.shape[-1])) targets = np.zeros((len(rows),)) for j, row in enumerate(rows): indices = range(rows[j] - lookback, rows[j], step) samples[j] = data[indices] targets[j] = data[rows[j] + delay][1] yield samples, targets
元のデータセットから学習、検証、テスト用のデータに分けます。
lookback = 1440 step = 6 delay = 144 batch_size = 128 train_gen = generator(float_data, lookback=lookback, delay=delay, min_index=0, max_index=200000, shuffle=True, step=step, batch_size=batch_size) val_gen = generator(float_data, lookback=lookback, delay=delay, min_index=200001, max_index=300000, step=step, batch_size=batch_size) test_gen = generator(float_data, lookback=lookback, delay=delay, min_index=300001, max_index=None, step=step, batch_size=batch_size) val_steps = (300000 - 200001 - lookback) test_steps = (len(float_data) - 300001 - lookback)
Sequential
を使ってRNNを構築して学習させます。
from tensorflow.keras.models import Sequential from tensorflow.keras import layers from tensorflow.keras.optimizers import RMSprop model = Sequential() model.add(layers.Flatten(input_shape=(lookback // step, float_data.shape[-1]))) model.add(layers.Dense(32, activation='relu')) model.add(layers.Dense(1)) model.compile(optimizer=RMSprop(), loss='mae') history = model.fit_generator(train_gen, steps_per_epoch=500, epochs=20, validation_data=val_gen, validation_steps=batch_size)
Epoch 1/20 500/500 [==============================] - 9s 19ms/step - loss: 1.5980 - val_loss: 0.4938 Epoch 2/20 500/500 [==============================] - 9s 17ms/step - loss: 0.5903 - val_loss: 0.3942
予測するには predict
を使います。
d = next(train_gen) x = d[0] print(x[0:2].shape) b = np.array(x[0:2]) model.predict(b)
参考
時系列データの扱い方はKeras作者のCholletさんの本に詳しく紹介されています。
- 作者: Francois Chollet
- 出版社/メーカー: Manning Publications
- 発売日: 2017/12/22
- メディア: ペーパーバック
- この商品を含むブログを見る
日本語
- 作者: Francois Chollet,巣籠悠輔,株式会社クイープ
- 出版社/メーカー: マイナビ出版
- 発売日: 2018/05/28
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る