Skip to Content
Course content

198: Practice Exercise: Building a Time Series Forecasting Pipeline

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've seen plenty of experienced engineers move from general machine learning into time series and make the same critical mistake: they treat time series data like a standard tabular dataset. They reach for sample() or a standard k-fold cross-validation because that's what worked for their classification models. It feels intuitive, but in the world of forecasting, it's a recipe for disaster.

The Myth of the Random Split

The misconception is that shuffling your data before splitting it into training and testing sets ensures a representative sample. In a standard dataset, this is true. But if you do this with time series, you are committing "data leakage." You end up using data from Tuesday to predict what happened on Monday.

# THE WRONG WAY
# Imagine we have daily energy consumption data for a year
set.seed(123)
train_indices <- sample(1:365, 292) # Randomly picking 80% of days
train_data <- energy_df[train_indices, ]
test_data <- energy_df[-train_indices, ]

When you run a model on this, your accuracy metrics will look incredible. You'll think you've built a miracle model. In reality, the model has simply "seen" the future peaks and troughs of the season, allowing it to interpolate the gaps. In production, where the future is actually unknown, your model will crash and burn because it never learned to actually forecast—it only learned to fill in the blanks.

Respecting the Arrow of Time with Time-Slicing

To build a real pipeline, you have to respect the temporal order. We use a "time-based split" or a "rolling window." You take the first 80% of the data chronologically for training and the final 20% for testing. This mimics exactly how the model will perform in the real world: training on the past to predict an unseen future.

In R, the tsibble and fable packages make this much cleaner than the old ts objects. I prefer tsibble because it treats time as a first-class citizen, allowing us to filter by date ranges rather than worrying about integer indices.

library(tsibble)
library(dplyr)
library(fable)

# THE RIGHT WAY
# Assuming 'energy_ts' is a tsibble with an index column 'Date'
split_date <- as.Date("2023-10-01")

train_data <- energy_ts %>% filter(Date < split_date)
test_data <- energy_ts %>% filter(Date >= split_date)

Gluing the Fable Pipeline Together

Once the data is split correctly, the pipeline follows a predictable flow: Tidy Data → Model Specification → Training → Forecasting → Evaluation. I like the fable approach because it allows you to fit multiple models (like ETS and ARIMA) to the same data simultaneously and compare them using a single framework.

A professional pipeline doesn't just pick one model and hope for the best. It fits a suite of candidates, forecasts them over the test horizon, and selects the one with the lowest MAE (Mean Absolute Error) or RMSE. Here is the structural flow I recommend:

# 1. Fit multiple models
fit <- train_data %>%
  model(
    ets = ETS(demand),
    arima = ARIMA(demand)
  )

# 2. Forecast for the length of the test set
fc <- fit %>%
  forecast(h = nrow(test_data))

# 3. Evaluate against the actuals
accuracy(fc, test_data)

One quick tip: don't obsess over the most complex model. In my experience, a well-tuned ETS (Error, Trend, Seasonality) model often beats a complex neural network for business-cycle forecasting because it's less prone to overfitting the noise in your training window.




📋 Practical Task

Exercise: Building a Demand Forecasting Pipeline for Urban Electricity Usage

Your goal is to build a complete forecasting pipeline to predict electricity demand. You will be provided with a dataset electricity_demand.csv containing two columns: Date and KWh.

Requirements:

  • Data Prep: Convert the dataframe into a tsibble object with a daily index.
  • Chronological Split: Split the data such that the last 30 days are reserved for testing. Do NOT use sample().
  • Pipeline Implementation:
    • Fit both an ETS and an ARIMA model to the training set.
    • Generate a 30-day forecast for both models.
  • Performance Metric: Calculate the RMSE (Root Mean Squared Error) for both models using the test set.
  • Selection: Print the name of the model that performed better on the test set.

Note: You should use the tsibble, fable, and dplyr libraries to complete this task.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.