TensorFlowを用いてLSTMモデルを構築し、ディスク使用量の予測をしてみようとしているのですが、予測部分がうまくいかない状態です。
学習曲線は収束しているのですが、未来のデータに対する予測ができないようです。
初心者のRNN(LSTM) | Kerasで試してみるを参考にしておりますが、未来のデータの生成部分があまり理解できておりません。
ディスク使用量データは四万行強ほどあるデータです。これといって目立つような異常値や欠損値はない状態です。下記はPandasでCSVを読み込んだあとに、describe()
メソッドを呼んだ際の出力です。
count 41280.000000 mean 43.636047 std 15.434929 min 17.000000 25% 30.000000 50% 44.000000 75% 57.000000 max 75.000000
ソースコードは下記のようにしております。
import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler, MinMaxScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Activation from tensorflow.keras.layers import LSTM from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import EarlyStopping import tensorflow as tf df = pd.read_csv("disk.csv", index_col=0, parse_dates=True) df = df.sort_index() df = df.dropna() print(df.describe()) dataset = df.iloc[:, 0].values dataset = np.array(dataset).reshape(len(dataset), -1) scaler = MinMaxScaler() dataset = scaler.fit_transform(dataset) def make_dataset(dataset, lookback=7): data, target = [], [] for i in range(len(dataset) - lookback): data.append(dataset[i:i+lookback]) target.append(dataset[i+lookback]) data = np.array(data) target = np.array(target) re_data = data.reshape(len(data), lookback, 1) re_target = target.reshape(len(data), 1) return re_data, re_target lookback = 1000 X, y = make_dataset(dataset, lookback) print(X.shape) print(y.shape) def model_fit(): model = Sequential() model.add( LSTM(100, batch_input_shape=(None, X.shape[1], 1), return_sequences=False) ) model.add(Dense(1)) model.add(Activation('linear')) optimizer = Adam(lr=0.001) model.compile(loss="mean_squared_error", optimizer=optimizer) early_stopping = EarlyStopping(monitor="val_loss", mode="auto", patience=20) history = model.fit( X, y, batch_size=512, epochs=500, validation_split=0.3, callbacks=[early_stopping] ) model.save("disk_model.h5") loss = history.history["loss"] val_loss = history.history["val_loss"] epochs = range(len(loss)) plt.figure(figsize=(10, 5)) plt.plot(epochs, loss, color="r", label="Training loss") plt.plot(epochs, val_loss, color="b", label="Validation loss") plt.legend(fontsize=20) plt.show() model_fit() model = tf.keras.models.load_model("disk_model.h5") predicted = model.predict(X) future_test = X[-1].T time_length = future_test.shape[1] future_result = np.array((1)) for step2 in range(400): test_data = np.reshape(future_test, (1, time_length, 1)) batch_predicted = model.predict(test_data) future_test = np.delete(future_test, 0) future_test = np.append(future_test, batch_predicted) future_result = np.append(future_result, batch_predicted) plt.figure(figsize=(15, 5)) plt.plot(range(lookback, len(predicted)+lookback), predicted, color="r", label="predicte_data") plt.plot(range(0, len(dataset)), dataset, color="b", label="row_data") plt.plot(range(0+len(dataset), len(future_result)+len(dataset)), future_result, color="g", label="future") plt.legend() plt.show()
上記のコードを実行すると最終的に下記のグラフがプロットされます。
個人的には右端の緑色の予測部分も青色部分と同じ振幅を持っていてほしかったのですが、なぜか0.5未満の値が含まれていないようでした。
こちらのソースコードだと適切に予測できないということでしょうか?
どの辺が問題になっているのかがわからず、調べることさえできない状態です。。。
初歩的なことで申し訳ありませんが、ご教示いただけますと幸いです。よろしくお願いいたします
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/04/13 00:02
2021/04/13 06:01
2021/04/13 07:21
2021/04/15 08:09