A better first-cut forecast on time series data with a seasonal component is to persist the observation for the same time in the previous season. This is called seasonal persistence.

In this tutorial, you will discover how to implement seasonal persistence for time series forecasting in Python.

After completing this tutorial, you will know:

How to use point observations from prior seasons for a persistence forecast.

How to use mean observations across a sliding window of prior seasons for a persistence forecast.

How to apply and evaluate seasonal persistence on monthly and daily time series data.

Let’s get started.

Seasonal Persistence

It is critical to have a useful first-cut forecast on time series problems to provide a lower-bound on skill before moving on to more sophisticated methods.

This is to ensure we are not wasting time on models or datasets that are not predictive.

It is common to use a persistence or a naive forecast as a first-cut forecast model when time series forecasting.

This does not make sense with time series data that has an obvious seasonal component. A better first cut model for seasonal data is to use the observation at the same time in the previous seasonal cycle as the prediction.

We can call this “seasonal persistence” and it is a simple model that can result in an effective first cut model.

One step better is to use a simple function of the last few observations at the same time in previous seasonal cycles. For example, the mean of the observations. This can often provide a small additional benefit.

In this tutorial, we will demonstrate this simple seasonal persistence forecasting method for providing a lower bound on forecast skill on three different real-world time series datasets.

Seasonal Persistence with Sliding Window

In this tutorial, we will use a sliding window seasonal persistence model to make forecasts.

Within a sliding window, observations at the same time in previous one-year seasons will be collected and the mean of those observations can be used as the persisted forecast.

Different window sizes can be evaluated to find a combination that minimizes error.

As an example, if the data is monthly and the month to be predicted is February, then with a window of size 1 (w=1) the observation last February will be used to make the forecast.

A window of size 2 (w=2) would involve taking observations for the last two Februaries to be averaged and used as a forecast.

An alternate interpretation might seek to use point observations from prior years (e.g. t-12, t-24, etc. for monthly data) rather than taking the mean of the cumulative point observations. Perhaps try both methods on your dataset and see what works best as a good starting point model.

Experimental Test Harness

It is important to evaluate time series forecasting models consistently.

In this section, we will define how we will evaluate forecast models in this tutorial.

First, we will hold the last two years of data back and evaluate forecasts on this data. This works for both monthly and daily data we will look at.

We will use a walk-forward validation to evaluate model performance. This means that each time step in the test dataset will be enumerated, a model constructed on historical data, and the forecast compared to the expected value. The observation will then be added to the training dataset and the process repeated.

Walk-forward validation is a realistic way to evaluate time series forecast models as one would expect models to be updated as new observations are made available.

Finally, forecasts will be evaluated using root mean squared error, or RMSE. The benefit of RMSE is that it penalizes large errors and the scores are in the same units as the forecast values (car sales per month).

In summary, the test harness involves:

The last 2 years of data used as a test set.

Walk-forward validation for model evaluation.

Root mean squared error used to report model skill.

Case Study 1: Monthly Car Sales Dataset

The Monthly Car Sales dataset describes the number of car sales in Quebec, Canada between 1960 and 1968.

The units are a count of the number of sales and there are 108 observations. The source of the data is credited to Abraham and Ledolter (1983).

Case Study 2: Monthly Writing Paper Sales Dataset

The units are a type of count of the number of sales and there are 147 months of observations (just over 12 years). The counts are fractional, suggesting the data may in fact be in the units of hundreds of thousands of sales. The source of the data is credited to Makridakis and Wheelwright (1989).

Download the dataset and save it into your current working directory with the filename “writing-paper-sales.csv“. Note, you may need to delete the footer information from the file.

The date-time stamps only contain the year number and month. Therefore, a custom date-time parsing function is required to load the data and base the data in an arbitrary year. The year 1900 was chosen as the starting point, which should not affect this case study.

Running the example prints the size of the sliding window and the resulting seasonal persistence model error.

The results suggest that a window size of 5 years is optimal, with an RMSE of 554.660 monthly writing paper sales.

1

2

3

4

5

6

7

8

9

10

Years=1, RMSE: 606.089

Years=2, RMSE: 557.653

Years=3, RMSE: 555.777

Years=4, RMSE: 544.251

Years=5, RMSE: 540.317

Years=6, RMSE: 554.660

Years=7, RMSE: 569.032

Years=8, RMSE: 581.405

Years=9, RMSE: 602.279

Years=10, RMSE: 624.756

The relationship between window size and error is graphed on a line plot showing a similar trend in error to the previous scenario. Error drops to an inflection point (in this case 5 years) before increasing again.

Sliding Window Size to RMSE for Monthly Writing Paper Sales

Case Study 3: Daily Maximum Melbourne Temperatures Dataset

The Daily Maximum Melbourne Temperatures dataset describes the daily temperatures in the city Melbourne, Australia from 1981 to 1990.

The units are in degrees Celsius and there 3,650 observations, or 10 years of data. The source of the data is credited to the Australian Bureau of Meteorology.

Thank you for this tutorial, and tying together data models from previous posts. Providing a means to evaluate seasonal persistence with a sliding windows, and then graphing the results is dynamite mate.

I really like the format of Introduction, Test Harness, Case Studies, and Summary. It helps me draw a real world connection with the data set.

First of all, I’ve learned a lot from your tutorials. I’d like to say “thank you”.

As to the examples in this tutorial, there was a comment made back in April by “x” who didn’t elaborate where he thought the programs had mistakes as requested. I think the mistake is in line 22 of the complete code of the 1st example:

obs.append(history[-(y*12)])

I think this line should be:

obs.append(history[-(y*12 + i)])

because we want to collect the figures of the ith month over the last few years represented by y.