Time-Series Forecasting Using GRU: A Step-by-Step Guide
Time-series forecasting is an essential task in many real-world applications, such as predicting stock prices, weather forecasting, and sales projections. In this blog, we will explore how to build a time-series forecasting model using Gated Recurrent Units (GRUs), a type of recurrent neural network (RNN) well-suited for sequential data. We’ll use Python, TensorFlow, and Keras to implement the model and predict airline passenger numbers using the classic Airline Passenger Dataset.
What is GRU?
Gated Recurrent Units (GRUs) are a simplified version of LSTMs (Long Short-Term Memory networks), designed to capture temporal dependencies in sequential data. GRUs are especially effective for time-series forecasting because:
- They can retain long-term dependencies in sequences, which is crucial for predicting future values based on historical data.
- GRUs are less computationally expensive than LSTMs, making them faster to train without compromising much on performance.
Step-by-Step Guide to Time-Series Forecasting with GRU
Step 1: Import Libraries
We’ll start by importing the necessary libraries, including Pandas, NumPy, Matplotlib, and TensorFlow. The Keras library within TensorFlow will be used to build and train the GRU model.
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import GRU, Dense
- Pandas and NumPy: For data handling and manipulation.
- Matplotlib: For plotting the results.
- TensorFlow: For building and training the GRU model.
- MinMaxScaler: To normalize the data for better performance during training.
Step 2: Load and Preprocess the Data
We’ll use the Airline Passenger Dataset, which contains the monthly number of passengers from 1949 to 1960. The dataset is accessible via a URL, and we use pandas.read_csv
to load it. The dataset contains two columns, but we only focus on the second column, which holds the passenger numbers.
# Load Airline Passenger dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv'
data = pd.read_csv(url, usecols=[1])
data = data.values.astype('float32')
Step 3: Normalize the Data
Since neural networks work better with normalized data, we’ll use the MinMaxScaler
to scale the values between 0 and 1. This ensures that all values are on the same scale, which accelerates the learning process and prevents some features from dominating others.
# Normalize the data
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data)
Step 4: Prepare Data for GRU Model
To train the GRU, we need to prepare the dataset using a sliding window approach. This method creates input-output pairs, where the input is a sequence of previous time steps, and the output is the next time step’s value. For example, if the look_back
parameter is 10, the model will predict the 11th value using the previous 10 values.
# Prepare data for GRU (sliding window approach)
def create_dataset(data, look_back=1):
X, y = [], []
for i in range(len(data)-look_back-1):
a = data[i:(i+look_back), 0]
X.append(a)
y.append(data[i + look_back, 0])
return np.array(X), np.array(y)
look_back = 10
X, y = create_dataset(data, look_back)
Step 5: Reshape Input Data for GRU
GRUs expect a 3D input of the form [samples, time steps, features]
. The sliding window data created in the previous step needs to be reshaped accordingly.
# Reshape input to be [samples, time steps, features]
X = np.reshape(X, (X.shape[0], X.shape[1], 1))
Here:
- Samples: The number of training instances.
- Time steps: The
look_back
value, representing how many past observations the model considers when making predictions. - Features: The number of variables (in this case, only 1 because we are working with a univariate time series).
Step 6: Build the GRU Model
Now we will define a Sequential model in Keras with two GRU layers followed by a Dense output layer.
- First GRU layer: Returns the sequences (
return_sequences=True
) because we are stacking multiple GRU layers. - Second GRU layer: Returns the final state, which is passed to the Dense layer to make predictions.
- Dense layer: Outputs the predicted number of passengers.
# Build GRU model
model_gru_ts = Sequential()
model_gru_ts.add(GRU(50, return_sequences=True, input_shape=(look_back, 1)))
model_gru_ts.add(GRU(50))
model_gru_ts.add(Dense(1))
Step 7: Compile the Model
Next, we compile the model using the Adam optimizer and mean squared error (MSE) as the loss function. MSE is commonly used for regression tasks like time-series forecasting.
# Compile model
model_gru_ts.compile(optimizer='adam', loss='mean_squared_error')
Step 8: Train the Model
We train the model for 100 epochs with a batch size of 32. Each epoch allows the model to see the entire dataset, helping it learn the patterns in the data. Training for a larger number of epochs is often necessary for models to capture time-series patterns effectively.
# Train the model
model_gru_ts.fit(X, y, epochs=100, batch_size=32, verbose=1)
- Epochs: Number of times the model sees the entire dataset.
- Batch size: Number of samples the model sees before updating weights.
Step 9: Make Predictions
Once the model is trained, we can use it to make predictions. The predictions will be on the same scale as the normalized input data, so we must apply the inverse transformation to bring the predicted values back to their original scale.
# Make predictions
predictions = model_gru_ts.predict(X)
# Inverse transform the predictions
predictions = scaler.inverse_transform(predictions)
y_actual = scaler.inverse_transform([y])
scaler.inverse_transform()
: This function converts the normalized data back to the original scale, allowing us to compare predictions with the actual values.
Step 10: Plot the Results
Finally, we can visualize the model’s performance by plotting the original data and the model’s predictions. This gives us an insight into how well the model has captured the trends and patterns in the time series.
# Plot original data vs predictions
plt.figure(figsize=(12,6))
plt.plot(data[look_back+1:], label='Original Data')
plt.plot(predictions, label='Predicted Data', color='r')
plt.xlabel('Time')
plt.ylabel('Number of Passengers')
plt.title('Time-Series Forecasting using GRU')
plt.legend()
plt.show()
- Original Data: This represents the actual number of passengers from the dataset.
- Predicted Data: The GRU model’s predicted values for the same time points.
Key Considerations:
- Data Normalization: Normalizing the data significantly improves the model’s ability to learn patterns, especially in time-series data where the values can vary across different magnitudes.
- Sliding Window: The size of the
look_back
window (i.e., the number of past observations the model uses to predict the next value) can be tuned based on the specific problem. - GRU Layers: Using multiple GRU layers allows the model to learn complex temporal dependencies. You can experiment with the number of units and layers.
- Training Time: The model is trained for 100 epochs, but this can be adjusted. Training for too many epochs may lead to overfitting, where the model performs well on training data but poorly on new, unseen data.
Conclusion
In this blog, we demonstrated how to implement a time-series forecasting model using GRU in Python. We covered the entire process, from loading and normalizing the data, creating input-output pairs using a sliding window approach, building and training a GRU model, and visualizing the predictions.
This framework can be extended to other time-series datasets, and you can experiment with different model architectures, hyperparameters (like look-back window and number of GRU units), and additional preprocessing steps to improve performance. Time-series forecasting is a powerful tool, and GRU provides a robust method for making accurate predictions in a wide variety of fields.
Stay tuned for more!
I am always happy to connect with my followers and readers on LinkedIn. If you have any questions or just want to say hello, please don’t hesitate to reach out.
https://www.linkedin.com/in/sharmasaravanan/
Happy learning!
Adios, me gusta!! 🤗🤗