Time-Series Forecasting Using Conv1D-LSTM - Multiple Timesteps Into Future
Time-Series Forecasting Using Conv1D-LSTM - Multiple Timesteps Into Future
The Conv1D layers smoothens out the input time-series so we don’t have
to add the rolling mean or rolling standard deviation values in the input
features.
This adds a great benefit in time series forecasting, where classical linear
methods can be difficult to adapt to multivariate or multiple input
forecasting problems (A side note here for multivariate forecasting —
keep in mind that when we use multivariate data for forecasting, then
we also need “future multi-variate” input data to predict the future
outcome!…to mitigate this we have two methods discussed below.)
In this post, I would like to focus on many to many model. In this case we
can solve the problem in two different ways.
The core idea and the mathematical equation has been taken from this
research paper. I have tried to implement this Direct forecasting technique
to predict the Global active power values into the future for 30 days. The
dataset is taken from UCI machine learning repository and can be accessed
from here.
dataset_train = dataset_train.reset_index()
cols = list(dataset_train)[1:8]
# Extract dates (will be used in visualization)
datelist_train = list(dataset_train['dt'])
datelist_train = [date for date in datelist_train]
training_set = dataset_train.values
Create two scalers one for input features and the other for target that has to
be predicted. Note that “Global active power” collumn is present in input
features too.
# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
training_set_scaled = sc.fit_transform(training_set)
sc_predict = StandardScaler()
sc_predict.fit_transform(training_set[:, 0:1])
X_train = []
y_train = []
n_future = 30 # Number of days we want to predict into the future.
n_past = 72 # Number of past days we want to use to predict future.
Explanation:
If the input feature values from [0:72] rows and all input columns then the
target value that is learned is [72+30–1:72+30] row and one target
column of the data. Since we predicting 30 values directly into future, we
are making our model learn in such a way that for every block of input
features(our lookback value is 72) the target is 30 timesteps ahead.
model = tf.keras.models.Sequential([
tf.keras.layers.Conv1D(filters=32, kernel_size=3,
strides=1, padding="causal",
activation="relu",
input_shape=[None, 7]),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32,
return_sequences=True)),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32,
return_sequences=False)),
tf.keras.layers.Dense(1),
tf.keras.layers.Lambda(lambda x: x * 200)])
# lr_schedule = tf.keras.callbacks.LearningRateScheduler(
# lambda epoch: 1e-8 * 10**(epoch / 20))
I have taken the learning_rate=1e-5, after running the above model using
lr_schedule and plotting the plot (learning_rate vs loss) as in below.
# Perform predictions
predictions_future = model.predict(X_train[-n_future:])
predictions_train = model.predict(X_train[n_past:])
y_pred_future = sc_predict.inverse_transform(predictions_future)
y_pred_train = sc_predict.inverse_transform(predictions_train)
plt.plot(PREDICTIONS_FUTURE.index,
PREDICTIONS_FUTURE['Global_active_power'], color='r',
label='Predicted Global Active power')
plt.plot(PREDICTION_TRAIN.loc[START_DATE_FOR_PLOTTING:].index,
PREDICTION_TRAIN.loc[START_DATE_FOR_PLOTTING['Global_active_power'],
color='orange', label='Training predictions')
plt.plot(dataset_train_actual.loc[START_DATE_FOR_PLOTTING:].index,
dataset_train_actual.loc[START_DATE_FOR_PLOTTING:]
['Global_active_power'], color='b', label='Actual Global Active
power')
plt.legend(shadow=True)