Last Updated on August 28, 2019
Time series forecast models can both make predictions and provide a prediction interval for those predictions.
Prediction intervals provide an upper and lower expectation for the real observation. These can be useful for assessing the range of real possible outcomes for a prediction and for better understanding the skill of the model
In this tutorial, you will discover how to calculate and interpret prediction intervals for time series forecasts with Python.
Specifically, you will learn:
- How to make a forecast with an ARIMA model and gather forecast diagnostic information.
- How to interpret a prediction interval for a forecast and configure different intervals.
- How to plot the prediction interval in the context of recent observations.
Discover how to prepare and visualize time series data and develop autoregressive forecasting models in my new book, with 28 step-by-step tutorials, and full python code.
Let’s dive in.
- Updated Apr/2019: Updated the link to dataset.
- Updated Jun/2019: Changed from prediction intervals to prediction intervals.
- Updated Aug/2019: Updated data loading to use new API.
What You Will Learn
ARIMA Forecast
The ARIMA implementation in the statsmodels Python library can be used to fit an ARIMA model.
It returns an ARIMAResults object. This object provides the forecast() function that can be used to make predictions about future time steps and default to predicting the value at the next time step after the end of the training data.
Assuming we are predicting just the next time step, the forecast() method returns three values:
- Forecast. The forecasted value in the units of the training time series.
- Standard error. The standard error for the model.
- Prediction interval. The 95% prediction interval for the forecast.
In this tutorial, we will better understand the prediction interval provided with an ARIMA forecast.
Before we dive in, let’s first look at the Daily Female Births dataset that we will use as the context for this tutorial.
Stop learning Time Series Forecasting the slow way!
Take my free 7-day email course and discover how to get started (with sample code).
Click to sign-up and also get a free PDF Ebook version of the course.
Start Your FREE Mini-Course Now!
Daily Female Births Dataset
This dataset describes the number of daily female births in California in 1959.
The units are a count and there are 365 observations. The source of the dataset is credited to Newton (1988).
Download the dataset and save it in your current working directory with the filename “daily-total-female-births.csv“.
The example below loads and graphs the dataset.
from pandas import read_csv
from matplotlib import pyplot
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
series.plot()
pyplot.show()
from pandas import read_csv
from matplotlib import pyplot
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
series.plot()
pyplot.show()
Running the example loads the dataset and graphs it as a line plot.
Forecast Prediction Interval
In this section, we will train an ARIMA model, use it to make a prediction, and inspect the prediction interval.
First, we will split the training dataset into a training and test dataset. Almost all observations will be used for training and we will hold back the last single observation as a test dataset for which we will make a prediction.
An ARIMA(5,1,1) model is trained. This is not the optimal model for this problem, just a good model for demonstration purposes.
The trained model is then used to make a prediction by calling the forecast() function. The results of the forecast are then printed.
The complete example is listed below.
from pandas import read_csv
from statsmodels.tsa.arima_model import ARIMA
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
X = series.values
X = X.astype(‘float32’)
size = len(X) – 1
train, test = X[0:size], X[size:]
model = ARIMA(train, order=(5,1,1))
model_fit = model.fit(disp=False)
forecast, stderr, conf = model_fit.forecast()
print(‘Expected: %.3f’ % test[0])
print(‘Forecast: %.3f’ % forecast)
print(‘Standard Error: %.3f’ % stderr)
print(‘95%% Prediction Interval: %.3f to %.3f’ % (conf[0][0], conf[0][1]))
from pandas import read_csv
from statsmodels.tsa.arima_model import ARIMA
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
X = series.values
X = X.astype(‘float32’)
size = len(X) – 1
train, test = X[0:size], X[size:]
model = ARIMA(train, order=(5,1,1))
model_fit = model.fit(disp=False)
forecast, stderr, conf = model_fit.forecast()
print(‘Expected: %.3f’ % test[0])
print(‘Forecast: %.3f’ % forecast)
print(‘Standard Error: %.3f’ % stderr)
print(‘95%% Prediction Interval: %.3f to %.3f’ % (conf[0][0], conf[0][1]))
Running the example prints the expected value from the test set followed by the predicted value, standard error, and prediction interval for the forecast.
Expected: 50.000
Forecast: 45.878
Standard Error: 6.996
95% Prediction Interval: 32.167 to 59.590
Expected: 50.000
Forecast: 45.878
Standard Error: 6.996
95% Prediction Interval: 32.167 to 59.590
Interpreting the Prediction Interval
The forecast() function allows the prediction interval to be specified.
The alpha argument on the forecast() function specifies the prediction level. It is set by default to alpha=0.05, which is a 95% prediction interval. This is a sensible and widely used prediction interval.
An alpha of 0.05 means that the ARIMA model will estimate the upper and lower values around the forecast where there is a only a 5% chance that the real value will not be in that range.
Put another way, the 95% prediction interval suggests that there is a high likelihood that the real observation will be within the range.
In the above example, the forecast was 45.878. The 95% prediction interval suggested that the real observation was highly likely to fall within the range of values between 32.167 and 59.590.
The real observation was 50.0 and was well within this range.
We can tighten the range of likely values a few ways:
- We can ask for a range that is narrower but increases the statistical likelihood of a real observation falling outside of the range.
- We can develop a model that has more predictive power and in turn makes more accurate predictions.
Further, the prediction interval is also limited by the assumptions made by the model, such as the distribution of errors made by the model fit a Gaussian distribution with a zero mean value (e.g. white noise).
Extending the example above, we can report our forecast with a few different commonly used prediction intervals of 80%, 90%, 95% and 99%.
The complete example is listed below.
from pandas import read_csv
from statsmodels.tsa.arima_model import ARIMA
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
X = series.values
X = X.astype(‘float32’)
size = len(X) – 1
train, test = X[0:size], X[size:]
model = ARIMA(train, order=(5,1,1))
model_fit = model.fit(disp=False)
intervals = [0.2, 0.1, 0.05, 0.01]
for a in intervals:
forecast, stderr, conf = model_fit.forecast(alpha=a)
print(‘%.1f%% Prediction Interval: %.3f between %.3f and %.3f’ % ((1-a)*100, forecast, conf[0][0], conf[0][1]))
from pandas import read_csv
from statsmodels.tsa.arima_model import ARIMA
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
X = series.values
X = X.astype(‘float32’)
size = len(X) – 1
train, test = X[0:size], X[size:]
model = ARIMA(train, order=(5,1,1))
model_fit = model.fit(disp=False)
intervals = [0.2, 0.1, 0.05, 0.01]
for a in intervals:
forecast, stderr, conf = model_fit.forecast(alpha=a)
print(‘%.1f%% Prediction Interval: %.3f between %.3f and %.3f’ % ((1-a)*100, forecast, conf[0][0], conf[0][1]))
Running the example prints the forecasts and prediction intervals for each alpha value.
We can see that we get the same forecast value each time and an interval that expands as our desire for a ‘safer’ interval increases. We can see that an 80% captures our actual value just fine in this specific case.
80.0% Prediction Interval: 45.878 between 36.913 and 54.844
90.0% Prediction Interval: 45.878 between 34.371 and 57.386
95.0% Prediction Interval: 45.878 between 32.167 and 59.590
99.0% Prediction Interval: 45.878 between 27.858 and 63.898
80.0% Prediction Interval: 45.878 between 36.913 and 54.844
90.0% Prediction Interval: 45.878 between 34.371 and 57.386
95.0% Prediction Interval: 45.878 between 32.167 and 59.590
99.0% Prediction Interval: 45.878 between 27.858 and 63.898
Plotting the Prediction Interval
The prediction interval can be plotted directly.
The ARIMAResults object provides the plot_predict() function that can be used to make a forecast and plot the results showing recent observations, the forecast, and prediction interval.
As with the forecast() function, the prediction interval can be configured by specifying the alpha argument. The default is 0.05 (95%), which is a sensible default.
The example below shows the same forecast from above plotted using this function.
from pandas import read_csv
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
X = series.values
X = X.astype(‘float32’)
size = len(X) – 1
train, test = X[0:size], X[size:]
model = ARIMA(train, order=(5,1,1))
model_fit = model.fit(disp=False)
model_fit.plot_predict(len(train)-10, len(train)+1)
pyplot.show()
from pandas import read_csv
from matplotlib import pyplot
from statsmodels.tsa.arima_model import ARIMA
series = read_csv(‘daily-total-female-births.csv’, header=0, index_col=0)
X = series.values
X = X.astype(‘float32’)
size = len(X) – 1
train, test = X[0:size], X[size:]
model = ARIMA(train, order=(5,1,1))
model_fit = model.fit(disp=False)
model_fit.plot_predict(len(train)-10, len(train)+1)
pyplot.show()
The plot_predict() will plot the observed y values if the prediction interval covers the training data.
In this case, we predict the previous 10 days and the next 1 day. This is useful to see the prediction carry on from in sample to out of sample time indexes (blue). This is contracted with the actual observations from the last 10 days (green).
Finally, we can see the prediction interval as a gray cone around the predicted value (called a confidence interval, but is actually a prediction interval). This is useful to get a spatial feeling for the range of possible values that an observation in the next time step may take.
Summary
In this tutorial, you discovered how to calculate and interpret the prediction interval for a time series forecast with Python.
Specifically, you learned:
- How to report forecast diagnostic statistics when making a point forecast.
- How to interpret and configure the prediction interval for a time series forecast.
- How to plot a forecast and prediction interval in the context of recent observations.
Do you have any questions about forecast prediction intervals, or about this tutorial?
Ask your questions in the comments below and I will do my best to answer.
Want to Develop Time Series Forecasts with Python?
Develop Your Own Forecasts in Minutes
…with just a few lines of python code
Discover how in my new Ebook:
Introduction to Time Series Forecasting With Python
It covers self-study tutorials and end-to-end projects on topics like:
Loading data, visualization, modeling, algorithm tuning, and much more…
Finally Bring Time Series Forecasting to
Your Own Projects
Skip the Academics. Just Results.
See What’s Inside