I'am trying to fit a multivariate weather data to my GRU model with 3 column input to predict the same 3 column as an output. When i evaluate the model by predicting the test set it gives good result and imply that the model is learning well. but when i try forecasting it gives a straight line
I already try variating the n_past, batch size, learning rate, epoch, different algorithm (LSTM and CNN), and number of neuron but it still gives a straight line
heres my code:
columns = ['MAX_TEMP', 'MIN_TEMP', 'SUNLIGHT', 'AVG_HUM', 'MAX_WINDSPEED', 'WINDIR']
df = df.drop(columns = columns)
df.fillna(round(df.rolling(window=7, min_periods=1).mean(), 2), inplace=True)
length = round(len(df) * 0.9)
train = df[:length]
test = df[length:]
print(len(train))
print(len(test))
scaler = MinMaxScaler()
scaler.fit(train)
train_scaled = scaler.transform(train)
test_scaled = scaler.transform(test)
length = 4 # Length of the output sequences (in number of timesteps)
batch_size = 32 #Number of timeseries samples in each batch
generator = TimeseriesGenerator(train_scaled, train_scaled, length=length, batch_size=batch_size, shuffle=False)
X,y = generator[0]
X.shape (32, 4, 3)
y.shape (32, 3)
validation_generator = TimeseriesGenerator(test_scaled,test_scaled,
length=length, batch_size=8, shuffle=False)
n_features = train_scaled.shape[1]
model = tf.keras.models.Sequential([
tf.keras.layers.GRU(100, activation='relu', input_shape=(length,n_features)),
tf.keras.layers.Dense(n_features)
lr = 0.0001
loss = tf.keras.losses.Huber()
optimizers = tf.keras.optimizers.Adam(learning_rate=lr)
model.compile(loss=loss, optimizer='adam', metrics=['mae'])
history = model.fit(generator, validation_data=validation_generator, epochs=50)
predikksi = model.predict(validation_generator)
y_pred = scaler.inverse_transform(predikksi)
y_test = test_data[length:]
])
above is the code that predicts the test set and it gives good results model.predict()
now this is the code that I use for forecasting:
n_features = train_scaled.shape[1]
test_predictions = []
first_eval_batch = train_scaled[-length:]
current_batch = first_eval_batch.reshape((1, length, n_features))
for i in range(len(test)):
# get prediction 1 time stamp ahead ([0] is for grabbing just the number instead of [array])
current_pred = model.predict(current_batch, verbose=0)[0]
# store prediction
test_predictions.append(current_pred)
# update batch to now include prediction and drop first value
current_batch = np.append(current_batch[:,1:,:],[[current_pred]],axis=1)
predictions = scaler.inverse_transform(test_predictions)
forecasting above is using forecast and it always gives straight line