add FPP3 (Hyndman & Athanasopoulos) scraped to markdown, 13 chapters + appendices

This commit is contained in:
wassname
2026-07-26 10:21:48 +08:00
parent 4fcea49ebb
commit a9b154fc6d
18 changed files with 11169 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
Source: https://otexts.com/fpp3/index.html (chapter index, 1 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 00-preface
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Forecasting: Principles and Practice (3rd ed)
*Rob J Hyndman and George Athanasopoulos*
Monash University, Australia
# Preface
![](https://otexts.com/fpp3/figs/fpp3_front_cover.jpg)
[Buy a print version](https://otexts.com/fpp3/buy-a-print-version.html)
Welcome to our online textbook on forecasting.
This textbook is intended to provide a comprehensive introduction to forecasting methods and to present enough information about each method for readers to be able to use them sensibly. We dont attempt to give a thorough discussion of the theoretical details behind each method, although the references at the end of each chapter will fill in many of those details.
The book is written for three audiences: (1) people finding themselves doing forecasting in business when they may not have had any formal training in the area; (2) undergraduate students studying business; (3) MBA students doing a forecasting elective. We use it ourselves for masters students and third-year undergraduate students at Monash University, Australia.
For most sections, we only assume that readers are familiar with introductory statistics, and with high-school algebra. There are a couple of sections that also require knowledge of matrices, but these are flagged.
At the end of each chapter we provide a list of “further reading”. In general, these lists comprise suggested textbooks that provide a more advanced or detailed treatment of the subject. Where there is no suitable textbook, we suggest journal articles that provide more information.
We use R throughout the book and we intend students to learn how to forecast with R. R is free and available on almost every operating system. It is a wonderful tool for all statistical analysis, not just for forecasting. See the [Using R appendix](https://otexts.com/fpp3/appendix-using-r.html#appendix-using-r) for instructions on installing and using R.
All R examples in the book assume you have loaded the `fpp3` package first:
```
library(fpp3)
```
```
#> ── Attaching packages ──────────────────────────────── fpp3 1.0.3 ──
#> ✔ tibble 3.3.1 ✔ tsibble 1.2.0
#> ✔ dplyr 1.2.1 ✔ tsibbledata 0.4.1
#> ✔ tidyr 1.3.2 ✔ ggtime 0.2.0
#> ✔ lubridate 1.9.5 ✔ feasts 0.5.0
#> ✔ ggplot2 4.0.3 ✔ fable 0.5.0
#> ── Conflicts ───────────────────────────────────── fpp3_conflicts ──
#> ✖ lubridate::date() masks base::date()
#> ✖ dplyr::filter() masks stats::filter()
#> ✖ tsibble::intersect() masks base::intersect()
#> ✖ tsibble::interval() masks lubridate::interval()
#> ✖ dplyr::lag() masks stats::lag()
#> ✖ tsibble::setdiff() masks base::setdiff()
#> ✖ tsibble::union() masks base::union()
```
This will load the relevant data sets, and attach several packages as listed above. These include several [`tidyverse`](https://tidyverse.org) packages, and packages to handle time series and forecasting in a “tidy” framework.
The above output also shows the package versions we have used in compiling this edition of the book. Some examples in the book will not work with earlier versions of the packages.
Finally, the output lists some conflicts showing which function will be preferenced when a function of the same name is in multiple packages.
The book is different from other forecasting textbooks in several ways.
* It is free and online, making it accessible to a wide audience.
* It uses R, which is free, open-source, and extremely powerful software.
* The online version is continuously updated. You dont have to wait until the next edition for errors to be removed or new methods to be discussed. We will update the book frequently.
* There are dozens of real data examples taken from our own consulting practice. We have worked with hundreds of businesses and organisations helping them with forecasting issues, and this experience has contributed directly to many of the examples given here, as well as guiding our general philosophy of forecasting.
* We emphasise graphical methods more than most forecasters. We use graphs to explore the data, analyse the validity of the models fitted and present the forecasting results.
### Changes in the third edition
The most important change in edition 3 of the book is that we use the `tsibble` and `fable` packages rather than the `forecast` package. This allows us to integrate closely with the `tidyverse` collection of packages. As a consequence, we have replaced many examples to take advantage of the new facilities.
We have also added some new material on time series features, and reorganised the content so Chapters [2](https://otexts.com/fpp3/graphics.html#graphics)[4](https://otexts.com/fpp3/features.html#features) discuss exploratory analysis of time series, before we introduce any forecasting methods. This is because we should first have a good understanding of our time series, their patterns and characteristics, before we attempt to build any models and produce any forecasts.
In the online version of the book, we have included some videos at the start of most sections. These are intended to complement the written material in each section. You can view the [entire playlist on YouTube](https://www.youtube.com/playlist?list=PLyCNZ_xXGzpm7W9jLqbIyBAiSO5jDwJeE).
Helpful readers of the earlier versions of the book let us know of any typos or errors they had found. These were updated immediately online. No doubt we have introduced some new mistakes, and we will correct them online as soon as they are spotted. Please continue to [let us know](https://github.com/orgs/OTexts/discussions/categories/error-report?discussions_q=) about such things.
If you have questions about using the R packages discussed in this book, or about forecasting in general, please ask on the [OTexts discussion forum](https://github.com/orgs/OTexts/discussions?discussions_q=).
Happy forecasting!
Rob J Hyndman and George Athanasopoulos
May 2021
---
To cite the online version of this book, please use the following:
> Hyndman, R.J., & Athanasopoulos, G. (2021) *Forecasting: principles and practice*, 3rd edition, OTexts: Melbourne, Australia. OTexts.com/fpp3. Accessed on `<current date>`.
> This online version of the book was last updated on 23 July 2026.
>
> The print version of the book ([available from Amazon](https://otexts.com/fpp3/fpp3/buy-a-print-version.html)) was last updated on 31 May 2021.
+266
View File
@@ -0,0 +1,266 @@
Source: https://otexts.com/fpp3/intro.html (chapter intro, 10 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 01-getting-started
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 1 Getting started
Forecasting has fascinated people for thousands of years, sometimes being considered a sign of divine inspiration, and sometimes being seen as a criminal activity. The Jewish prophet Isaiah wrote in about 700 BC
> *Tell us what the future holds, so we may know that you are gods.*
> (Isaiah 41:23)
One hundred years later, in ancient Babylon, forecasters would foretell the future based on the appearance of a sheeps liver. Around the same time, people wanting forecasts would journey to Delphi in Greece to consult the Oracle, who would provide her predictions while intoxicated by ethylene vapours. Forecasters had a tougher time under the emperor Constantius II, who issued a decree in AD357 forbidding anyone “to consult a soothsayer, a mathematician, or a forecaster … May curiosity to foretell the future be silenced forever.”[1](#fn1) A similar ban on forecasting occurred in England in 1824[2](#fn2) when “every person pretending or professing to tell fortunes” was “deemed a rogue and vagabond”. The punishment was up to three months imprisonment with hard labour!
The varying fortunes of forecasters arise because good forecasts can seem almost magical, while bad forecasts may be dangerous. Consider the following famous predictions about computing.
* *I think there is a world market for maybe five computers.*
(Chairman of IBM, 1943)
* *Computers in the future may weigh no more than 1.5 tons.*
(Popular Mechanics, 1949)
* *There is no reason anyone would want a computer in their home.*
(President, DEC, 1977)
The last of these was made only three years before IBM produced the first personal computer. Not surprisingly, you can no longer buy a DEC computer. Forecasting is obviously a difficult activity, and businesses that do it well have a big advantage over those whose forecasts fail.
In this book, we will explore the most reliable methods for producing forecasts. The emphasis will be on methods that are replicable and testable, and have been shown to work.
---
1. [Codex Theodosianus 9.16.4](https://www.thelatinlibrary.com/theodosius/theod09.shtml)[↩︎](https://otexts.com/fpp3/intro.html#fnref1)
2. [Vagrancy Act, 1824, Section 4](https://statutes.org.uk/site/the-statutes/nineteenth-century/5-geo-iv-c-83-vagrancy-act-1824/), [repealed in 1989](https://www.legislation.gov.uk/ukpga/Geo4/5/83#commentary-c554743).[↩︎](https://otexts.com/fpp3/intro.html#fnref2)
## 1.1 What can be forecast?
Forecasting is required in many situations: deciding whether to build another power generation plant in the next five years requires forecasts of future demand; scheduling staff in a call centre next week requires forecasts of call volumes; stocking an inventory requires forecasts of stock requirements. Forecasts can be required several years in advance (for the case of capital investments), or only a few minutes beforehand (for telecommunication routing). Whatever the circumstances or time horizons involved, forecasting is an important aid to effective and efficient planning.
Some things are easier to forecast than others. The time of the sunrise tomorrow morning can be forecast precisely. On the other hand, tomorrows lotto numbers cannot be forecast with any accuracy. The predictability of an event or a quantity depends on several factors including:
1. how well we understand the factors that contribute to it;
2. how much data is available;
3. how similar the future is to the past;
4. whether the forecasts can affect the thing we are trying to forecast.
For example, short-term forecasts of residential electricity demand can be highly accurate because all four conditions are usually satisfied.
1. We have a good idea of the contributing factors: electricity demand is driven largely by temperatures, with smaller effects for calendar variation such as holidays, and economic conditions.
2. Several years of data on electricity demand are usually available, and many decades of data on weather conditions.
3. For short-term forecasting (up to a few weeks), it is safe to assume that demand behaviour will be similar to what has been seen in the past.
4. For most residential users, the price of electricity is not dependent on demand, and so the demand forecasts have little or no effect on consumer behaviour.
Provided we have the skills to develop a good model linking electricity demand and the key driver variables, the forecasts can be remarkably accurate.
On the other hand, when forecasting currency exchange rates, only one of the conditions is satisfied: there is plenty of available data. However, we have a limited understanding of the factors that affect exchange rates, the future may well be different to the past if there is a financial or political crisis in one of the countries, and forecasts of the exchange rate have a direct effect on the rates themselves. If there are well-publicised forecasts that the exchange rate will increase, then people will immediately adjust the price they are willing to pay and so the forecasts are self-fulfilling. In a sense, the exchange rates become their own forecasts. This is an example of the “efficient market hypothesis”. Consequently, forecasting whether the exchange rate will rise or fall tomorrow is about as predictable as forecasting whether a tossed coin will come down as a head or a tail. In both situations, you will be correct about 50% of the time, whatever you forecast. In situations like this, forecasters need to be aware of their own limitations, and not claim more than is possible.
Often in forecasting, a key step is knowing when something can be forecast accurately, and when forecasts will be no better than tossing a coin. Good forecasts capture the genuine patterns and relationships which exist in the historical data, but do not replicate past events that will not occur again. In this book, we will learn how to tell the difference between a random fluctuation in the past data that should be ignored, and a genuine pattern that should be modelled and extrapolated.
Many people wrongly assume that forecasts are not possible in a changing environment. Every environment is changing, and a good forecasting model captures the way in which things are changing. Forecasts rarely assume that the environment is unchanging. What is normally assumed is that *the way in which the environment is changing* will continue into the future. That is, a highly volatile environment will continue to be highly volatile; a business with fluctuating sales will continue to have fluctuating sales; and an economy that has gone through booms and busts will continue to go through booms and busts. A forecasting model is intended to capture the way things move, not just where things are. As Abraham Lincoln said, “If we could first know where we are and whither we are tending, we could better judge what to do and how to do it”.
Forecasting situations vary widely in their time horizons, factors determining actual outcomes, types of data patterns, and many other aspects. Forecasting methods can be simple, such as using the most recent observation as a forecast (which is called the **naïve method**), or highly complex, such as neural nets and econometric systems of simultaneous equations. Sometimes, there will be no data available at all. For example, we may wish to forecast the sales of a new product in its first year, but there are obviously no data to work with. In situations like this, we use judgmental forecasting, discussed in Chapter [6](https://otexts.com/fpp3/judgmental.html#judgmental). The choice of method depends on what data are available and the predictability of the quantity to be forecast.
## 1.2 Forecasting, goals and planning
Forecasting is a common statistical task in business, where it helps to inform decisions about the scheduling of production, transportation and personnel, and provides a guide to long-term strategic planning. However, business forecasting is often done poorly, and is frequently confused with planning and goals. They are three different things.
Forecasting
: is about predicting the future as accurately as possible, given all of the information available, including historical data and knowledge of any future events that might impact the forecasts.
Goals
: are what you would like to have happen. Goals should be linked to forecasts and plans, but this does not always occur. Too often, goals are set without any plan for how to achieve them, and no forecasts for whether they are realistic.
Planning
: is a response to forecasts and goals. Planning involves determining the appropriate actions that are required to make your forecasts match your goals.
Forecasting should be an integral part of the decision-making activities of management, as it can play an important role in many areas of a company. Modern organisations require short-term, medium-term and long-term forecasts, depending on the specific application.
Short-term forecasts
: are needed for the scheduling of personnel, production and transportation. As part of the scheduling process, forecasts of demand are often also required.
Medium-term forecasts
: are needed to determine future resource requirements, in order to purchase raw materials, hire personnel, or buy machinery and equipment.
Long-term forecasts
: are used in strategic planning. Such decisions must take account of market opportunities, environmental factors and internal resources.
An organisation needs to develop a forecasting system that involves several approaches to predicting uncertain events. Such forecasting systems require the development of expertise in identifying forecasting problems, applying a range of forecasting methods, selecting appropriate methods for each problem, and evaluating and refining forecasting methods over time. It is also important to have strong organisational support for the use of formal forecasting methods if they are to be used successfully.
## 1.3 Determining what to forecast
In the early stages of a forecasting project, decisions need to be made about what should be forecast. For example, if forecasts are required for items in a manufacturing environment, it is necessary to ask whether forecasts are needed for:
1. every product line, or for groups of products?
2. every sales outlet, or for outlets grouped by region, or only for total sales?
3. weekly data, monthly data or annual data?
It is also necessary to consider the forecasting horizon. Will forecasts be required for one month in advance, for 6 months, or for ten years? Different types of models will be necessary, depending on what forecast horizon is most important.
How frequently are forecasts required? Forecasts that need to be produced frequently are better done using an automated system than with methods that require careful manual work.
It is worth spending time talking to the people who will use the forecasts to ensure that you understand their needs, and how the forecasts are to be used, before embarking on extensive work in producing the forecasts.
Once it has been determined what forecasts are required, it is then necessary to find or collect the data on which the forecasts will be based. The data required for forecasting may already exist. These days, a lot of data are recorded, and the forecasters task is often to identify where and how the required data are stored. The data may include sales records of a company, the historical demand for a product, or the unemployment rate for a geographic region. A large part of a forecasters time can be spent in locating and collating the available data prior to developing suitable forecasting methods.
## 1.4 Forecasting data and methods
The appropriate forecasting methods depend largely on what data are available.
If there are no data available, or if the data available are not relevant to the forecasts, then **qualitative forecasting** methods must be used. These methods are not purely guesswork—there are well-developed structured approaches to obtaining good forecasts without using historical data. These methods are discussed in Chapter [6](https://otexts.com/fpp3/judgmental.html#judgmental).
**Quantitative forecasting** can be applied when two conditions are satisfied:
1. numerical information about the past is available;
2. it is reasonable to assume that some aspects of the past patterns will continue into the future.
There is a wide range of quantitative forecasting methods, often developed within specific disciplines for specific purposes. Each method has its own properties, accuracies, and costs that must be considered when choosing a specific method.
Most quantitative prediction problems use either time series data (collected at regular intervals over time) or cross-sectional data (collected at a single point in time). In this book we are concerned with forecasting future data, and we concentrate on the time series domain.
### Time series forecasting
Examples of time series data include:
* Annual Google profits
* Quarterly sales results for Amazon
* Monthly rainfall
* Weekly retail sales
* Daily IBM stock prices
* Hourly electricity demand
* 5-minute freeway traffic counts
* Time-stamped stock transaction data
Anything that is observed sequentially over time is a time series. In this book, we will only consider time series that are observed at regular intervals of time (e.g., hourly, daily, weekly, monthly, quarterly, annually). Irregularly spaced time series can also occur, but are beyond the scope of this book.
When forecasting time series data, the aim is to estimate how the sequence of observations will continue into the future. Figure [1.1](https://otexts.com/fpp3/data-methods.html#fig:beer) shows the quarterly Australian beer production from 2000 to the second quarter of 2010.
![Australian quarterly beer production: 2000Q12010Q2, with two years of forecasts.](https://otexts.com/fpp3/fpp_files/figure-html/beer-1.png)
Figure 1.1: Australian quarterly beer production: 2000Q12010Q2, with two years of forecasts.
The blue lines show forecasts for the next two years. Notice how the forecasts have captured the seasonal pattern seen in the historical data and replicated it for the next two years. The dark shaded region shows 80% prediction intervals. That is, each future value is expected to lie in the dark shaded region with a probability of 80%. The light shaded region shows 95% prediction intervals. These prediction intervals are a useful way of displaying the uncertainty in forecasts. In this case the forecasts are expected to be accurate, and hence the prediction intervals are quite narrow.
The simplest time series forecasting methods use only information on the variable to be forecast, and make no attempt to discover the factors that affect its behaviour. Therefore they will extrapolate trend and seasonal patterns, but they ignore all other information such as marketing initiatives, competitor activity, changes in economic conditions, and so on.
Decomposition methods are helpful for studying the trend and seasonal patterns in a time series; these are discussed in Chapter [3](https://otexts.com/fpp3/decomposition.html#decomposition). Popular time series models used for forecasting include exponential smoothing models and ARIMA models, discussed in Chapters [8](https://otexts.com/fpp3/expsmooth.html#expsmooth) and [9](https://otexts.com/fpp3/arima.html#arima) respectively.
### Predictor variables and time series forecasting
Predictor variables are often useful in time series forecasting. For example, suppose we wish to forecast the hourly electricity demand (ED) of a hot region during the summer period. A model with predictor variables might be of the form
\[\begin{align\*}
\text{ED} = & f(\text{current temperature, strength of economy, population,}\\
& \qquad\text{time of day, day of week, error}).
\end{align\*}\]
The relationship is not exact — there will always be changes in electricity demand that cannot be accounted for by the predictor variables. The “error” term on the right allows for random variation and the effects of relevant variables that are not included in the model. We call this an **explanatory model** because it helps explain what causes the variation in electricity demand.
Because the electricity demand data form a time series, we could also use a **time series model** for forecasting. In this case, a suitable time series forecasting equation is of the form
\[
\text{ED}_{t+1} = f(\text{ED}_{t}, \text{ED}_{t-1}, \text{ED}_{t-2}, \text{ED}_{t-3},\dots, \text{error}),
\]
where \(t\) is the present hour, \(t+1\) is the next hour, \(t-1\) is the previous hour, \(t-2\) is two hours ago, and so on. Here, prediction of the future is based on past values of a variable, but not on external variables that may affect the system. Again, the “error” term on the right allows for random variation and the effects of relevant variables that are not included in the model.
There is also a third type of model which combines the features of the above two models. For example, it might be given by
\[
\text{ED}_{t+1} = f(\text{ED}_{t}, \text{current temperature, time of day, day of week, error}).
\]
These types of **mixed models** have been given various names in different disciplines. They are known as dynamic regression models, panel data models, longitudinal models, transfer function models, and linear system models (assuming that \(f\) is linear). These models are discussed in Chapter [10](https://otexts.com/fpp3/dynamic.html#dynamic).
An explanatory model is useful because it incorporates information about other variables, rather than only historical values of the variable to be forecast. However, there are several reasons a forecaster might select a time series model rather than an explanatory or mixed model. First, the system may not be understood, and even if it was understood it may be extremely difficult to measure the relationships that are assumed to govern its behaviour. Second, it is necessary to know or forecast the future values of the various predictors in order to be able to forecast the variable of interest, and this may be too difficult. Third, the main concern may be only to predict what will happen, not to know why it happens. Finally, the time series model may give more accurate forecasts than an explanatory or mixed model.
The model to be used in forecasting depends on the resources and data available, the accuracy of the competing models, and the way in which the forecasting model is to be used.
## 1.5 Some case studies
The following four cases are from our consulting practice and demonstrate different types of forecasting situations and the associated challenges that often arise.
#### Case 1
The client was a large company manufacturing disposable tableware such as napkins and paper plates. They needed forecasts of each of hundreds of items every month. The time series data showed a range of patterns, some with trends, some seasonal, and some with neither. At the time, they were using their own software, written in-house, but it often produced forecasts that did not seem sensible. The methods that were being used were the following:
1. average of the last 12 months data;
2. average of the last 6 months data;
3. prediction from a straight line regression over the last 12 months;
4. prediction from a straight line regression over the last 6 months;
5. prediction obtained by a straight line through the last observation with slope equal to the average slope of the lines connecting last years and this years values;
6. prediction obtained by a straight line through the last observation with slope equal to the average slope of the lines connecting last years and this years values, where the average is taken only over the last 6 months.
They required us to tell them what was going wrong and to modify the software to provide more accurate forecasts. The software was written in COBOL, making it difficult to do any sophisticated numerical computation.
#### Case 2
In this case, the client was the Australian federal government, which needed to forecast the annual budget for the Pharmaceutical Benefit Scheme (PBS). The PBS provides a subsidy for many pharmaceutical products sold in Australia, and the expenditure depends on what people purchase during the year. The total expenditure was around A$7 billion in 2009, and had been underestimated by nearly $1 billion in each of the two years before we were asked to assist in developing a more accurate forecasting approach.
In order to forecast the total expenditure, it is necessary to forecast the sales volumes of hundreds of groups of pharmaceutical products using monthly data. Almost all of the groups have trends and seasonal patterns. The sales volumes for many groups have sudden jumps up or down due to changes in what drugs are subsidised. The expenditures for many groups also have sudden changes due to cheaper competitor drugs becoming available.
Thus we needed to find a forecasting method that allowed for trend and seasonality if they were present, and at the same time was robust to sudden changes in the underlying patterns. It also needed to be able to be applied automatically to a large number of time series.
#### Case 3
A large car fleet company asked us to help them forecast vehicle resale values. They purchase new vehicles, lease them out for three years, and then sell them. Better forecasts of vehicle sales values would mean better control of profits; understanding what affects resale values may allow leasing and sales policies to be developed in order to maximise profits.
At the time, the resale values were being forecast by a group of specialists. Unfortunately, they saw any statistical model as a threat to their jobs, and were uncooperative in providing information. Nevertheless, the company provided a large amount of data on previous vehicles and their eventual resale values.
#### Case 4
In this project, we needed to develop a model for forecasting weekly air passenger traffic on major domestic routes for one of Australias leading airlines. The company required forecasts of passenger numbers for each major domestic route and for each class of passenger (economy class, business class and first class). The company provided weekly traffic data from the previous six years.
Air passenger numbers are affected by school holidays, major sporting events, advertising campaigns, competition behaviour, etc. School holidays often do not coincide in different Australian cities, and sporting events sometimes move from one city to another. During the period of the historical data, there was a major pilots strike during which there was no traffic for several months. A new cut-price airline also launched and folded. Towards the end of the historical data, the airline had trialled a redistribution of some economy class seats to business class, and some business class seats to first class. After several months, however, the seat classifications reverted to the original distribution.
## 1.6 The basic steps in a forecasting task
A forecasting task usually involves five basic steps.
Step 1: Problem definition.
: Often this is the most difficult part of forecasting. Defining the problem carefully requires an understanding of the way the forecasts will be used, who requires the forecasts, and how the forecasting function fits within the organisation requiring the forecasts. A forecaster needs to spend time talking to everyone who will be involved in collecting data, maintaining databases, and using the forecasts for future planning.
Step 2: Gathering information.
: There are always at least two kinds of information required: (a) statistical data, and (b) the accumulated expertise of the people who collect the data and use the forecasts. Often, it will be difficult to obtain enough historical data to be able to fit a good statistical model. In that case, the judgmental forecasting methods of Chapter [6](https://otexts.com/fpp3/judgmental.html#judgmental) can be used. Occasionally, old data will be less useful due to structural changes in the system being forecast; then we may choose to use only the most recent data. However, remember that good statistical models will handle evolutionary changes in the system; dont throw away good data unnecessarily.
Step 3: Preliminary (exploratory) analysis.
: Always start by graphing the data. Are there consistent patterns? Is there a significant trend? Is seasonality important? Is there evidence of the presence of business cycles? Are there any outliers in the data that need to be explained by those with expert knowledge? How strong are the relationships among the variables available for analysis? Various tools have been developed to help with this analysis. These are discussed in Chapters [2](https://otexts.com/fpp3/graphics.html#graphics) and [3](https://otexts.com/fpp3/decomposition.html#decomposition).
Step 4: Choosing and fitting models.
: The best model to use depends on the availability of historical data, the strength of relationships between the forecast variable and any explanatory variables, and the way in which the forecasts are to be used. It is common to compare two or three potential models. Each model is itself an artificial construct that is based on a set of assumptions (explicit and implicit) and usually involves one or more parameters which must be estimated using the known historical data. We will discuss regression models (Chapter [7](https://otexts.com/fpp3/regression.html#regression)), exponential smoothing methods (Chapter [8](https://otexts.com/fpp3/expsmooth.html#expsmooth)), Box-Jenkins ARIMA models (Chapter [9](https://otexts.com/fpp3/arima.html#arima)), Dynamic regression models (Chapter [10](https://otexts.com/fpp3/dynamic.html#dynamic)), Hierarchical forecasting (Chapter [11](https://otexts.com/fpp3/hierarchical.html#hierarchical)), and several advanced methods including neural networks and vector autoregression (Chapter [12](https://otexts.com/fpp3/advanced.html#advanced)).
Step 5: Using and evaluating a forecasting model.
: Once a model has been selected and its parameters estimated, the model is used to make forecasts. The performance of the model can only be properly evaluated after the data for the forecast period have become available. A number of methods have been developed to help in assessing the accuracy of forecasts. There are also organisational issues in using and acting on the forecasts. A brief discussion of some of these issues is given in Chapter [5](https://otexts.com/fpp3/toolbox.html#toolbox). When using a forecasting model in practice, numerous practical issues arise such as how to handle missing values and outliers, or how to deal with short time series. These are discussed in Chapter [13](https://otexts.com/fpp3/practical.html#practical).
## 1.7 The statistical forecasting perspective
The thing we are trying to forecast is unknown (or we would not be forecasting it), and so we can think of it as a *random variable*. For example, the total sales for next month could take a range of possible values, and until we add up the actual sales at the end of the month, we dont know what the value will be. So until we know the sales for next month, it is a random quantity.
Because next month is relatively close, we usually have a good idea what the likely sales values could be. On the other hand, if we are forecasting the sales for the same month next year, the possible values it could take are much more variable. In most forecasting situations, the variation associated with the thing we are forecasting will shrink as the event approaches. In other words, the further ahead we forecast, the more uncertain we are.
We can imagine many possible futures, each yielding a different value for the thing we wish to forecast. Plotted in black in Figure [1.2](https://otexts.com/fpp3/perspective.html#fig:austa1) are the total international arrivals to Australia from 1980 to 2015. Also shown are ten possible futures from 20162025.
![Total international visitors to Australia (1980-2015) along with ten possible futures.](https://otexts.com/fpp3/fpp_files/figure-html/austa1-1.png)
Figure 1.2: Total international visitors to Australia (1980-2015) along with ten possible futures.
When we obtain a forecast, we are estimating the *middle* of the range of possible values the random variable could take. Often, a forecast is accompanied by a **prediction interval** giving a *range* of values the random variable could take with relatively high probability. For example, a 95% prediction interval contains a range of values which should include the actual future value with probability 95%.
Rather than plotting individual possible futures as shown in Figure [1.2](https://otexts.com/fpp3/perspective.html#fig:austa1), we usually show these prediction intervals instead. Figure [1.3](https://otexts.com/fpp3/perspective.html#fig:austa2) shows 80% and 95% intervals for the future Australian international visitors. The blue line is the average of the possible future values, which we call the **point forecasts**.
![Total international visitors to Australia (19802015) along with 10-year forecasts and 80% and 95% prediction intervals.](https://otexts.com/fpp3/fpp_files/figure-html/austa2-1.png)
Figure 1.3: Total international visitors to Australia (19802015) along with 10-year forecasts and 80% and 95% prediction intervals.
We will use the subscript \(t\) for time. For example, \(y_t\) will denote the observation at time \(t\). Suppose we denote all the information we have observed as \(\mathcal{I}\) and we want to forecast \(y_t\). We then write \(y_{t} | \mathcal{I}\) meaning “the random variable \(y_{t}\) given what we know in \(\mathcal{I}\)”. The set of values that this random variable could take, along with their relative probabilities, is known as the “probability distribution” of \(y_{t} |\mathcal{I}\). In forecasting, we call this the **forecast distribution**.
When we talk about the “forecast”, we usually mean the average value of the forecast distribution, and we put a “hat” over \(y\) to show this. Thus, we write the forecast of \(y_t\) as \(\hat{y}_t\), meaning the average of the possible values that \(y_t\) could take given everything we know.
It is often useful to specify exactly what information we have used in calculating the forecast. Then we will write, for example, \(\hat{y}_{t|t-1}\) to mean the forecast of \(y_t\) taking account of all previous observations \((y_1,\dots,y_{t-1})\). Similarly, \(\hat{y}_{T+h|T}\) means the forecast of \(y_{T+h}\) taking account of \(y_1,\dots,y_T\) (i.e., an \(h\)-step forecast taking account of all observations up to time \(T\)).
## 1.8 Exercises
1. For cases 3 and 4 in Section [1.5](https://otexts.com/fpp3/case-studies.html#case-studies), list the possible predictor variables that might be useful, assuming that the relevant data are available.
2. For case 3 in Section [1.5](https://otexts.com/fpp3/case-studies.html#case-studies), describe the five steps of forecasting in the context of this project.
## 1.9 Further reading
* Armstrong ([2001](#ref-Armstrong01)) covers the whole field of forecasting, with each chapter written by different experts. It is highly opinionated at times (and we dont agree with everything in it), but it is full of excellent general advice on tackling forecasting problems.
* Ord et al. ([2017](#ref-Ord2017)) is a forecasting textbook covering some of the same areas as this book, but with a different emphasis and not focused around any particular software environment. It is written by three highly respected forecasters, with many decades of experience between them.
### Bibliography
Armstrong, J. S. (Ed.). (2001). *Principles of forecasting: A handbook for researchers and practitioners*. Kluwer Academic Publishers.
Ord, J. K., Fildes, R., & Kourentzes, N. (2017). *Principles of business forecasting* (2nd ed.). Wessex Press Publishing Co.
@@ -0,0 +1,862 @@
Source: https://otexts.com/fpp3/graphics.html (chapter graphics, 12 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 02-time-series-graphics
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 2 Time series graphics
The first thing to do in any data analysis task is to plot the data. Graphs enable many features of the data to be visualised, including patterns, unusual observations, changes over time, and relationships between variables. The features that are seen in plots of the data must then be incorporated, as much as possible, into the forecasting methods to be used. Just as the type of data determines what forecasting method to use, it also determines what graphs are appropriate. But before we produce graphs, we need to set up our time series in R.
## 2.1 `tsibble` objects
A time series can be thought of as a list of numbers (the observations), along with some information about what times those numbers were recorded (the index). This information can be stored as a `tsibble` object in R.
### The index variable
Suppose you have annual observations for the last few years:
| Year | Observation |
| --- | --- |
| 2015 | 123 |
| 2016 | 39 |
| 2017 | 78 |
| 2018 | 52 |
| 2019 | 110 |
We turn this into a `tsibble` object using the `tsibble()` function:
```
y <- tsibble(
Year = 2015:2019,
Observation = c(123, 39, 78, 52, 110),
index = Year
)
```
`tsibble` objects extend tidy data frames (`tibble` objects) by introducing temporal structure. We have set the time series `index` to be the `Year` column, which associates the measurements (`Observation`) with the time of recording (`Year`).
For observations that are more frequent than once per year, we need to use a time class function on the index. For example, suppose we have a monthly dataset `z`:
```
z
#> # A tibble: 5 × 2
#> Month Observation
#> <chr> <dbl>
#> 1 2019 Jan 50
#> 2 2019 Feb 23
#> 3 2019 Mar 34
#> 4 2019 Apr 30
#> 5 2019 May 25
```
This can be converted to a `tsibble` object using the following code:
```
z |>
mutate(Month = yearmonth(Month)) |>
as_tsibble(index = Month)
#> # A tsibble: 5 x 2 [1M]
#> Month Observation
#> <mth> <dbl>
#> 1 2019 Jan 50
#> 2 2019 Feb 23
#> 3 2019 Mar 34
#> 4 2019 Apr 30
#> 5 2019 May 25
```
First, the `Month` column is being converted from text to a monthly time object with `yearmonth()`. We then convert the data frame to a `tsibble` by identifying the `index` variable using `as_tsibble()`. Note the addition of “[1M]” on the first line indicating this is monthly data.
Other time class functions can be used depending on the frequency of the observations.
| Frequency | Function |
| --- | --- |
| Annual | `start:end` |
| Quarterly | `yearquarter()` |
| Monthly | `yearmonth()` |
| Weekly | `yearweek()` |
| Daily | `as_date()`, `ymd()` |
| Sub-daily | `as_datetime()`, `ymd_hms()` |
### The key variables
A `tsibble` also allows multiple time series to be stored in a single object. Suppose you are interested in a dataset containing the fastest running times for womens and mens track races at the Olympics, from 100m to 10000m:
```
olympic_running
#> # A tsibble: 312 x 4 [4Y]
#> # Key: Length, Sex [14]
#> Year Length Sex Time
#> <int> <int> <chr> <dbl>
#> 1 1896 100 men 12
#> 2 1900 100 men 11
#> 3 1904 100 men 11
#> 4 1908 100 men 10.8
#> 5 1912 100 men 10.8
#> 6 1916 100 men NA
#> 7 1920 100 men 10.8
#> 8 1924 100 men 10.6
#> 9 1928 100 men 10.8
#> 10 1932 100 men 10.3
#> # 302 more rows
```
The summary above shows that this is a `tsibble` object, which contains 312 rows and 4 columns. Alongside this, “[4Y]” informs us that the interval of these observations is every four years. Below this is the key structure, which informs us that there are 14 separate time series in the `tsibble`. A preview of the first 10 observations is also shown, in which we can see a missing value occurs in 1916. This is because the Olympics were not held during World War I.
The 14 time series in this object are uniquely identified by the keys: the `Length` and `Sex` variables. The `distinct()` function can be used to show the categories of each variable or even combinations of variables:
```
olympic_running |> distinct(Sex)
#> # A tibble: 2 × 1
#> Sex
#> <chr>
#> 1 men
#> 2 women
```
### Working with `tsibble` objects
We can use `dplyr` functions such as `mutate()`, `filter()`, `select()` and `summarise()` to work with `tsibble` objects. To illustrate these, we will use the `PBS` tsibble containing sales data on pharmaceutical products in Australia.
```
PBS
#> # A tsibble: 67,596 x 9 [1M]
#> # Key: Concession, Type, ATC1, ATC2 [336]
#> Month Concession Type ATC1 ATC1_desc ATC2 ATC2_desc Scripts Cost
#> <mth> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
#> 1 1991 Jul Concessional Co-pay… A Alimenta… A01 STOMATOL… 18228 67877
#> 2 1991 Aug Concessional Co-pay… A Alimenta… A01 STOMATOL… 15327 57011
#> 3 1991 Sep Concessional Co-pay… A Alimenta… A01 STOMATOL… 14775 55020
#> 4 1991 Oct Concessional Co-pay… A Alimenta… A01 STOMATOL… 15380 57222
#> 5 1991 Nov Concessional Co-pay… A Alimenta… A01 STOMATOL… 14371 52120
#> 6 1991 Dec Concessional Co-pay… A Alimenta… A01 STOMATOL… 15028 54299
#> 7 1992 Jan Concessional Co-pay… A Alimenta… A01 STOMATOL… 11040 39753
#> 8 1992 Feb Concessional Co-pay… A Alimenta… A01 STOMATOL… 15165 54405
#> 9 1992 Mar Concessional Co-pay… A Alimenta… A01 STOMATOL… 16898 61108
#> 10 1992 Apr Concessional Co-pay… A Alimenta… A01 STOMATOL… 18141 65356
#> # 67,586 more rows
```
This contains monthly data on Medicare Australia prescription data from July 1991 to June 2008. These are classified according to various concession types, and Anatomical Therapeutic Chemical (ATC) indexes. For this example, we are interested in the `Cost` time series (total cost of scripts in Australian dollars).
We can use the `filter()` function to extract the A10 scripts:
```
PBS |>
filter(ATC2 == "A10")
#> # A tsibble: 816 x 9 [1M]
#> # Key: Concession, Type, ATC1, ATC2 [4]
#> Month Concession Type ATC1 ATC1_desc ATC2 ATC2_desc Scripts Cost
#> <mth> <chr> <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
#> 1 1991 Jul Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 89733 2.09e6
#> 2 1991 Aug Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 77101 1.80e6
#> 3 1991 Sep Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 76255 1.78e6
#> 4 1991 Oct Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 78681 1.85e6
#> 5 1991 Nov Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 70554 1.69e6
#> 6 1991 Dec Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 75814 1.84e6
#> 7 1992 Jan Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 64186 1.56e6
#> 8 1992 Feb Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 75899 1.73e6
#> 9 1992 Mar Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 89445 2.05e6
#> 10 1992 Apr Concessional Co-pa… A Alimenta… A10 ANTIDIAB… 97315 2.23e6
#> # 806 more rows
```
This allows rows of the tsibble to be selected. Next we can simplify the resulting object by selecting the columns we will need in subsequent analysis.
```
PBS |>
filter(ATC2 == "A10") |>
select(Month, Concession, Type, Cost)
#> # A tsibble: 816 x 4 [1M]
#> # Key: Concession, Type [4]
#> Month Concession Type Cost
#> <mth> <chr> <chr> <dbl>
#> 1 1991 Jul Concessional Co-payments 2092878
#> 2 1991 Aug Concessional Co-payments 1795733
#> 3 1991 Sep Concessional Co-payments 1777231
#> 4 1991 Oct Concessional Co-payments 1848507
#> 5 1991 Nov Concessional Co-payments 1686458
#> 6 1991 Dec Concessional Co-payments 1843079
#> 7 1992 Jan Concessional Co-payments 1564702
#> 8 1992 Feb Concessional Co-payments 1732508
#> 9 1992 Mar Concessional Co-payments 2046102
#> 10 1992 Apr Concessional Co-payments 2225977
#> # 806 more rows
```
The `select()` function allows us to select particular columns, while `filter()` allows us to keep particular rows.
Note that the index variable `Month`, and the keys `Concession` and `Type`, would be returned even if they were not explicitly selected as they are required for a tsibble (to ensure each row contains a unique combination of keys and index).
Another useful function is `summarise()` which allows us to combine data across keys. For example, we may wish to compute total cost per month regardless of the `Concession` or `Type` keys.
```
PBS |>
filter(ATC2 == "A10") |>
select(Month, Concession, Type, Cost) |>
summarise(TotalC = sum(Cost))
#> # A tsibble: 204 x 2 [1M]
#> Month TotalC
#> <mth> <dbl>
#> 1 1991 Jul 3526591
#> 2 1991 Aug 3180891
#> 3 1991 Sep 3252221
#> 4 1991 Oct 3611003
#> 5 1991 Nov 3565869
#> 6 1991 Dec 4306371
#> 7 1992 Jan 5088335
#> 8 1992 Feb 2814520
#> 9 1992 Mar 2985811
#> 10 1992 Apr 3204780
#> # 194 more rows
```
The new variable `TotalC` is the sum of all `Cost` values for each month.
We can create new variables using the `mutate()` function. Here we change the units from dollars to millions of dollars:
```
PBS |>
filter(ATC2 == "A10") |>
select(Month, Concession, Type, Cost) |>
summarise(TotalC = sum(Cost)) |>
mutate(Cost = TotalC/1e6)
#> # A tsibble: 204 x 3 [1M]
#> Month TotalC Cost
#> <mth> <dbl> <dbl>
#> 1 1991 Jul 3526591 3.53
#> 2 1991 Aug 3180891 3.18
#> 3 1991 Sep 3252221 3.25
#> 4 1991 Oct 3611003 3.61
#> 5 1991 Nov 3565869 3.57
#> 6 1991 Dec 4306371 4.31
#> 7 1992 Jan 5088335 5.09
#> 8 1992 Feb 2814520 2.81
#> 9 1992 Mar 2985811 2.99
#> 10 1992 Apr 3204780 3.20
#> # 194 more rows
```
Finally, we will save the resulting tsibble for examples later in this chapter.
```
PBS |>
filter(ATC2 == "A10") |>
select(Month, Concession, Type, Cost) |>
summarise(TotalC = sum(Cost)) |>
mutate(Cost = TotalC / 1e6) -> a10
```
At the end of this series of piped functions, we have used a right assignment (`->`), which is not common in R code, but is convenient at the end of a long series of commands as it continues the flow of the code.
### Read a csv file and convert to a tsibble
Almost all of the data used in this book is already stored as `tsibble` objects. But most data lives in databases, MS-Excel files or csv files, before it is imported into R. So often the first step in creating a tsibble is to read in the data, and then identify the index and key variables.
For example, suppose we have the following quarterly data stored in a csv file (only the first 10 rows are shown). This data set provides information on the size of the prison population in Australia, disaggregated by state, gender, legal status and indigenous status. (Here, ATSI stands for Aboriginal or Torres Strait Islander.)
| Date | State | Gender | Legal | Indigenous | Count |
| --- | --- | --- | --- | --- | --- |
| 2005-03-01 | ACT | Female | Remanded | ATSI | 0 |
| 2005-03-01 | ACT | Female | Remanded | Non-ATSI | 2 |
| 2005-03-01 | ACT | Female | Sentenced | ATSI | 0 |
| 2005-03-01 | ACT | Female | Sentenced | Non-ATSI | 5 |
| 2005-03-01 | ACT | Male | Remanded | ATSI | 7 |
| 2005-03-01 | ACT | Male | Remanded | Non-ATSI | 58 |
| 2005-03-01 | ACT | Male | Sentenced | ATSI | 5 |
| 2005-03-01 | ACT | Male | Sentenced | Non-ATSI | 101 |
| 2005-03-01 | NSW | Female | Remanded | ATSI | 51 |
| 2005-03-01 | NSW | Female | Remanded | Non-ATSI | 131 |
We can read it into R, and create a tsibble object, by simply identifying which column contains the time index, and which columns are keys. The remaining columns are values — there can be many value columns, although in this case there is only one (`Count`). The original csv file stored the dates as individual days, although the data is actually quarterly, so we need to convert the `Date` variable to quarters.
```
prison <- readr::read_csv("https://OTexts.com/fpp3/extrafiles/prison_population.csv")
```
```
prison <- prison |>
mutate(Quarter = yearquarter(Date)) |>
select(-Date) |>
as_tsibble(key = c(State, Gender, Legal, Indigenous),
index = Quarter)
prison
#> # A tsibble: 3,072 x 6 [1Q]
#> # Key: State, Gender, Legal, Indigenous [64]
#> State Gender Legal Indigenous Count Quarter
#> <chr> <chr> <chr> <chr> <dbl> <qtr>
#> 1 ACT Female Remanded ATSI 0 2005 Q1
#> 2 ACT Female Remanded ATSI 1 2005 Q2
#> 3 ACT Female Remanded ATSI 0 2005 Q3
#> 4 ACT Female Remanded ATSI 0 2005 Q4
#> 5 ACT Female Remanded ATSI 1 2006 Q1
#> 6 ACT Female Remanded ATSI 1 2006 Q2
#> 7 ACT Female Remanded ATSI 1 2006 Q3
#> 8 ACT Female Remanded ATSI 0 2006 Q4
#> 9 ACT Female Remanded ATSI 0 2007 Q1
#> 10 ACT Female Remanded ATSI 1 2007 Q2
#> # 3,062 more rows
```
This tsibble contains 64 separate time series corresponding to the combinations of the 8 states, 2 genders, 2 legal statuses and 2 indigenous statuses. Each of these series is 48 observations in length, from 2005 Q1 to 2016 Q4.
For a tsibble to be valid, it requires a unique index for each combination of keys. The `tsibble()` or `as_tsibble()` function will return an error if this is not true.
### The seasonal period
Some graphics and some models will use the seasonal period of the data. The seasonal period is the number of observations before the seasonal pattern repeats. In most cases, this will be automatically detected using the time index variable.
Some common periods for different time intervals are shown in the table below:
| Data | Minute | Hour | Day | Week | Year |
| --- | --- | --- | --- | --- | --- |
| Quarters | | | | | 4 |
| Months | | | | | 12 |
| Weeks | | | | | 52 |
| Days | | | | 7 | 365.25 |
| Hours | | | 24 | 168 | 8766 |
| Minutes | | 60 | 1440 | 10080 | 525960 |
| Seconds | 60 | 3600 | 86400 | 604800 | 31557600 |
For quarterly, monthly and weekly data, there is only one seasonal period — the number of observations within each year. Actually, there are not \(52\) weeks in a year, but \(365.25/7 = 52.18\) on average, allowing for a leap year every fourth year. Approximating seasonal periods to integers can be useful as many seasonal terms in models only support integer seasonal periods.
If the data is observed more than once per week, then there is often more than one seasonal pattern in the data. For example, data with daily observations might have weekly (period\(=7\)) or annual (period\(=365.25\)) seasonal patterns. Similarly, data that are observed every minute might have hourly (period\(=60\)), daily (period\(=24\times60=1440\)), weekly (period\(=24\times60\times7=10080\)) and annual seasonality (period\(=24\times60\times365.25=525960\)).
More complicated (and unusual) seasonal patterns can be specified using the `period()` function in the `lubridate` package.
## 2.2 Time plots
For time series data, the obvious graph to start with is a time plot. That is, the observations are plotted against the time of observation, with consecutive observations joined by straight lines. Figure [2.1](https://otexts.com/fpp3/time-plots.html#fig:ansett) shows the weekly economy passenger load on Ansett airlines between Australias two largest cities.
```
melsyd_economy <- ansett |>
filter(Airports == "MEL-SYD", Class == "Economy") |>
mutate(Passengers = Passengers/1000)
autoplot(melsyd_economy, Passengers) +
labs(title = "Ansett airlines economy class",
subtitle = "Melbourne-Sydney",
y = "Passengers ('000)")
```
![Weekly economy passenger load on Ansett Airlines.](https://otexts.com/fpp3/fpp_files/figure-html/ansett-1.png)
Figure 2.1: Weekly economy passenger load on Ansett Airlines.
We will use the `autoplot()` command frequently. It automatically produces an appropriate plot of whatever you pass to it in the first argument. In this case, it recognises `melsyd_economy` as a time series and produces a time plot.
The time plot immediately reveals some interesting features.
* There was a period in 1989 when no passengers were carried — this was due to an industrial dispute.
* There was a period of reduced load in 1992. This was due to a trial in which some economy class seats were replaced by business class seats.
* A large increase in passenger load occurred in the second half of 1991.
* There are some large dips in load around the start of each year. These are due to holiday effects.
* There is a long-term fluctuation in the level of the series which increases during 1987, decreases in 1989, and increases again through 1990 and 1991.
Any model will need to take all these features into account in order to effectively forecast the passenger load into the future.
A simpler time series is shown in Figure [2.2](https://otexts.com/fpp3/time-plots.html#fig:a10plot), using the `a10` data saved earlier.
```
autoplot(a10, Cost) +
labs(y = "$ (millions)",
title = "Australian antidiabetic drug sales")
```
![Monthly sales of antidiabetic drugs in Australia.](https://otexts.com/fpp3/fpp_files/figure-html/a10plot-1.png)
Figure 2.2: Monthly sales of antidiabetic drugs in Australia.
Here, there is a clear and increasing trend. There is also a strong seasonal pattern that increases in size as the level of the series increases. The sudden drop at the start of each year is caused by a government subsidisation scheme that makes it cost-effective for patients to stockpile drugs at the end of the calendar year. Any forecasts of this series would need to capture the seasonal pattern, and the fact that the trend is changing slowly.
## 2.3 Time series patterns
In describing these time series, we have used words such as “trend” and “seasonal” which need to be defined more carefully.
Trend
: A *trend* exists when there is a long-term increase or decrease in the data. It does not have to be linear. Sometimes we will refer to a trend as “changing direction”, when it might go from an increasing trend to a decreasing trend. There is a trend in the antidiabetic drug sales data shown in Figure [2.2](https://otexts.com/fpp3/time-plots.html#fig:a10plot).
Seasonal
: A *seasonal* pattern occurs when a time series is affected by seasonal factors such as the time of the year or the day of the week. Seasonality is always of a fixed and known period. The monthly sales of antidiabetic drugs (Figure [2.2](https://otexts.com/fpp3/time-plots.html#fig:a10plot)) shows seasonality which is induced partly by the change in the cost of the drugs at the end of the calendar year. (Note that one series can have more than one seasonal pattern.)
Cyclic
: A *cycle* occurs when the data exhibit rises and falls that are not of a fixed frequency. These fluctuations are usually due to economic conditions, and are often related to the “business cycle”. The duration of these fluctuations is usually at least 2 years.
Many people confuse cyclic behaviour with seasonal behaviour, but they are really quite different. If the fluctuations are not of a fixed frequency then they are cyclic; if the frequency is unchanging and associated with some aspect of the calendar, then the pattern is seasonal. In general, the average length of cycles is longer than the length of a seasonal pattern, and the magnitudes of cycles tend to be more variable than the magnitudes of seasonal patterns.
Many time series include trend, cycles and seasonality. When choosing a forecasting method, we will first need to identify the time series patterns in the data, and then choose a method that is able to capture the patterns properly.
The examples in Figure [2.3](https://otexts.com/fpp3/tspatterns.html#fig:fourexamples) show different combinations of these components.
![Four examples of time series showing different patterns.](https://otexts.com/fpp3/fpp_files/figure-html/fourexamples-1.png)
Figure 2.3: Four examples of time series showing different patterns.
1. The monthly housing sales (top left) show strong seasonality within each year, as well as some strong cyclic behaviour with a period of about 610 years. There is no apparent trend in the data over this period.
2. The US treasury bill contracts (top right) show results from the Chicago market for 100 consecutive trading days in 1981. Here there is no seasonality, but an obvious downward trend. Possibly, if we had a much longer series, we would see that this downward trend is actually part of a long cycle, but when viewed over only 100 days it appears to be a trend.
3. The Australian quarterly electricity production (bottom left) shows a strong increasing trend, with strong seasonality. There is no evidence of any cyclic behaviour here.
4. The daily change in the Google closing stock price (bottom right) has no trend, seasonality or cyclic behaviour. There are random fluctuations which do not appear to be very predictable, and no strong patterns that would help with developing a forecasting model.
## 2.4 Seasonal plots
A seasonal plot is similar to a time plot except that the data are plotted against the individual “seasons” in which the data were observed. An example is given in Figure [2.4](https://otexts.com/fpp3/seasonal-plots.html#fig:seasonplot1) showing the antidiabetic drug sales.
```
a10 |>
gg_season(Cost, labels = "both") +
labs(y = "$ (millions)",
title = "Seasonal plot: Antidiabetic drug sales")
```
![Seasonal plot of monthly antidiabetic drug sales in Australia.](https://otexts.com/fpp3/fpp_files/figure-html/seasonplot1-1.png)
Figure 2.4: Seasonal plot of monthly antidiabetic drug sales in Australia.
This is the same data as was shown earlier, but now the data from each year overlap. A seasonal plot allows the underlying seasonal pattern to be seen more clearly, and is especially useful in identifying years in which the pattern changes.
There is a large jump in sales in January each year. These are probably sales in late December as customers stockpile before the end of the calendar year, but the sales are not registered with the government until a week or two later. The graph also shows that there was an unusually small number of sales in March 2008 (most other years show an increase between February and March). The small number of sales in June 2008 is probably due to incomplete counting of sales at the time the data were collected.
### Multiple seasonal periods
Where the data has more than one seasonal pattern, the `period` argument can be used to select which seasonal plot is required. The `vic_elec` data contains half-hourly electricity demand for the state of Victoria, Australia. We can plot the daily pattern, weekly pattern or yearly pattern by specifying the `period` argument as shown in Figures [2.5](https://otexts.com/fpp3/seasonal-plots.html#fig:multipleseasonplots1)[2.7](https://otexts.com/fpp3/seasonal-plots.html#fig:multipleseasonplots3).
In the first plot, the three days with 25 hours are when daylight saving ended in each year and so these days contained an extra hour. There were also three days with only 23 hours each (when daylight saving started) but these are hidden beneath all the other lines on the plot.
```
vic_elec |> gg_season(Demand, period = "day") +
theme(legend.position = "none") +
labs(y="MWh", title="Electricity demand: Victoria")
```
![Seasonal plot showing daily seasonal patterns for Victorian electricity demand.](https://otexts.com/fpp3/fpp_files/figure-html/multipleseasonplots1-1.png)
Figure 2.5: Seasonal plot showing daily seasonal patterns for Victorian electricity demand.
```
vic_elec |> gg_season(Demand, period = "week") +
theme(legend.position = "none") +
labs(y="MWh", title="Electricity demand: Victoria")
```
![Seasonal plot showing weekly seasonal patterns for Victorian electricity demand.](https://otexts.com/fpp3/fpp_files/figure-html/multipleseasonplots2-1.png)
Figure 2.6: Seasonal plot showing weekly seasonal patterns for Victorian electricity demand.
```
vic_elec |> gg_season(Demand, period = "year") +
labs(y="MWh", title="Electricity demand: Victoria")
```
![Seasonal plot showing yearly seasonal patterns for Victorian electricity demand.](https://otexts.com/fpp3/fpp_files/figure-html/multipleseasonplots3-1.png)
Figure 2.7: Seasonal plot showing yearly seasonal patterns for Victorian electricity demand.
## 2.5 Seasonal subseries plots
An alternative plot that emphasises the seasonal patterns is where the data for each season are collected together in separate mini time plots.
```
a10 |>
gg_subseries(Cost) +
labs(
y = "$ (millions)",
title = "Australian antidiabetic drug sales"
)
```
![Seasonal subseries plot of monthly antidiabetic drug sales in Australia.](https://otexts.com/fpp3/fpp_files/figure-html/subseriesplot-1.png)
Figure 2.8: Seasonal subseries plot of monthly antidiabetic drug sales in Australia.
The blue horizontal lines indicate the means for each month. This form of plot enables the underlying seasonal pattern to be seen clearly, and also shows the changes in seasonality over time. It is especially useful in identifying changes within particular seasons. In this example, the plot is not particularly revealing; but in some cases, this is the most useful way of viewing seasonal changes over time.
### Example: Australian holiday tourism
Australian quarterly vacation data provides an interesting example of how these plots can reveal information. First we need to extract the relevant data from the `tourism` tsibble. All the usual `tidyverse` wrangling verbs apply. To get the total visitor nights spent on Holiday by State for each quarter (i.e., ignoring Regions) we can use the following code. Note that we do not have to explicitly group by the time index as this is required in a `tsibble`.
```
holidays <- tourism |>
filter(Purpose == "Holiday") |>
group_by(State) |>
summarise(Trips = sum(Trips))
```
```
holidays
#> # A tsibble: 640 x 3 [1Q]
#> # Key: State [8]
#> State Quarter Trips
#> <chr> <qtr> <dbl>
#> 1 ACT 1998 Q1 196.
#> 2 ACT 1998 Q2 127.
#> 3 ACT 1998 Q3 111.
#> 4 ACT 1998 Q4 170.
#> 5 ACT 1999 Q1 108.
#> 6 ACT 1999 Q2 125.
#> 7 ACT 1999 Q3 178.
#> 8 ACT 1999 Q4 218.
#> 9 ACT 2000 Q1 158.
#> 10 ACT 2000 Q2 155.
#> # 630 more rows
```
Time plots of each series show that there is strong seasonality for most states, but that the seasonal peaks do not coincide.
```
autoplot(holidays, Trips) +
labs(y = "Overnight trips ('000)",
title = "Australian domestic holidays")
```
![Time plots of Australian domestic holidays by state.](https://otexts.com/fpp3/fpp_files/figure-html/holidays-plot-1.png)
Figure 2.9: Time plots of Australian domestic holidays by state.
To see the timing of the seasonal peaks in each state, we can use a season plot. Figure [2.10](https://otexts.com/fpp3/subseries.html#fig:holidaysseason) makes it clear that the southern states of Australia (Tasmania, Victoria and South Australia) have strongest tourism in Q1 (their summer), while the northern states (Queensland and the Northern Territory) have the strongest tourism in Q3 (their dry season).
```
gg_season(holidays, Trips) +
labs(y = "Overnight trips ('000)",
title = "Australian domestic holidays")
```
![Season plots of Australian domestic holidays by state.](https://otexts.com/fpp3/fpp_files/figure-html/holidaysseason-1.png)
Figure 2.10: Season plots of Australian domestic holidays by state.
The corresponding subseries plots are shown in Figure [2.11](https://otexts.com/fpp3/subseries.html#fig:holidayssubseries).
```
holidays |>
gg_subseries(Trips) +
labs(y = "Overnight trips ('000)",
title = "Australian domestic holidays")
```
![Subseries plots of Australian domestic holidays by state.](https://otexts.com/fpp3/fpp_files/figure-html/holidayssubseries-1.png)
Figure 2.11: Subseries plots of Australian domestic holidays by state.
This figure makes it evident that Western Australian tourism has jumped markedly in recent years, while Victorian tourism has increased in Q1 and Q4 but not in the middle of the year.
## 2.6 Scatterplots
The graphs discussed so far are useful for visualising individual time series. It is also useful to explore relationships *between* time series.
Figures [2.12](https://otexts.com/fpp3/scatterplots.html#fig:edemand) and [2.13](https://otexts.com/fpp3/scatterplots.html#fig:victemp) show two time series: half-hourly electricity demand (in Gigawatts) and temperature (in degrees Celsius), for 2014 in Victoria, Australia. The temperatures are for Melbourne, the largest city in Victoria, while the demand values are for the entire state.
```
vic_elec |>
filter(year(Time) == 2014) |>
autoplot(Demand) +
labs(y = "GW",
title = "Half-hourly electricity demand: Victoria")
```
![Half hourly electricity demand in Victoria, Australia, for 2014.](https://otexts.com/fpp3/fpp_files/figure-html/edemand-1.png)
Figure 2.12: Half hourly electricity demand in Victoria, Australia, for 2014.
```
vic_elec |>
filter(year(Time) == 2014) |>
autoplot(Temperature) +
labs(
y = "Degrees Celsius",
title = "Half-hourly temperatures: Melbourne, Australia"
)
```
![Half hourly temperature in Melbourne, Australia, for 2014.](https://otexts.com/fpp3/fpp_files/figure-html/victemp-1.png)
Figure 2.13: Half hourly temperature in Melbourne, Australia, for 2014.
We can study the relationship between demand and temperature by plotting one series against the other.
```
vic_elec |>
filter(year(Time) == 2014) |>
ggplot(aes(x = Temperature, y = Demand)) +
geom_point() +
labs(title="Electricity demand versus Temperature",
x = "Temperature (degrees Celsius)",
y = "Electricity demand (GW)")
```
![Half-hourly electricity demand plotted against temperature for 2014 in Victoria, Australia.](https://otexts.com/fpp3/fpp_files/figure-html/edemand2-1.png)
Figure 2.14: Half-hourly electricity demand plotted against temperature for 2014 in Victoria, Australia.
This scatterplot helps us to visualise the relationship between the variables. It is clear that high demand occurs when temperatures are high due to the effect of air-conditioning. But there is also a heating effect, where demand increases for very low temperatures.
### Correlation
It is common to compute *correlation coefficients* to measure the strength of the linear relationship between two variables. The correlation between variables \(x\) and \(y\) is given by
\[
r = \frac{\sum (x_{t} - \bar{x})(y_{t}-\bar{y})}{\sqrt{\sum(x_{t}-\bar{x})^2}\sqrt{\sum(y_{t}-\bar{y})^2}}.
\]
The value of \(r\) always lies between \(-1\) and \(1\) with negative values indicating a negative relationship and positive values indicating a positive relationship. The graphs in Figure [2.15](https://otexts.com/fpp3/scatterplots.html#fig:corr) show examples of data sets with varying levels of correlation.
![Examples of data sets with different levels of correlation.](https://otexts.com/fpp3/fpp_files/figure-html/corr-1.png)
Figure 2.15: Examples of data sets with different levels of correlation.
The correlation coefficient only measures the strength of the *linear* relationship between two variables, and can sometimes be misleading. For example, the correlation for the electricity demand and temperature data shown in Figure [2.14](https://otexts.com/fpp3/scatterplots.html#fig:edemand2) is 0.28, but the *non-linear* relationship is stronger than that.
![Each of these plots has a correlation coefficient of 0.82. Data from Anscombe (1973).](https://otexts.com/fpp3/fpp_files/figure-html/anscombe-1.png)
Figure 2.16: Each of these plots has a correlation coefficient of 0.82. Data from Anscombe ([1973](#ref-Anscombe1973graphs)).
The plots in Figure [2.16](https://otexts.com/fpp3/scatterplots.html#fig:anscombe) all have correlation coefficients of 0.82, but they have very different relationships. This shows how important it is to look at the plots of the data and not simply rely on correlation values.
### Scatterplot matrices
When there are several potential predictor variables, it is useful to plot each variable against each other variable. Consider the eight time series shown in Figure [2.17](https://otexts.com/fpp3/scatterplots.html#fig:vntimeplots), showing quarterly visitor numbers across states and territories of Australia.
```
visitors <- tourism |>
group_by(State) |>
summarise(Trips = sum(Trips))
visitors |>
ggplot(aes(x = Quarter, y = Trips)) +
geom_line() +
facet_grid(vars(State), scales = "free_y") +
labs(title = "Australian domestic tourism",
y= "Overnight trips ('000)")
```
![Quarterly visitor nights for the states and territories of Australia.](https://otexts.com/fpp3/fpp_files/figure-html/vntimeplots-1.png)
Figure 2.17: Quarterly visitor nights for the states and territories of Australia.
To see the relationships between these eight time series, we can plot each time series against the others. These plots can be arranged in a scatterplot matrix, as shown in Figure [2.18](https://otexts.com/fpp3/scatterplots.html#fig:ScatterMatrixch2). (This plot requires the `GGally` package to be installed.)
```
visitors |>
pivot_wider(values_from=Trips, names_from=State) |>
GGally::ggpairs(columns = 2:9)
```
![A scatterplot matrix of the quarterly visitor nights in the states and territories of Australia.](https://otexts.com/fpp3/fpp_files/figure-html/ScatterMatrixch2-1.png)
Figure 2.18: A scatterplot matrix of the quarterly visitor nights in the states and territories of Australia.
For each panel, the variable on the vertical axis is given by the variable name in that row, and the variable on the horizontal axis is given by the variable name in that column. There are many options available to produce different plots within each panel. In the default version, the correlations are shown in the upper right half of the plot, while the scatterplots are shown in the lower half. On the diagonal are shown density plots.
The value of the scatterplot matrix is that it enables a quick view of the relationships between all pairs of variables. In this example, mostly positive relationships are revealed, with the strongest relationships being between the neighbouring states located in the south and south east coast of Australia, namely, New South Wales, Victoria and South Australia. Some negative relationships are also revealed between the Northern Territory and other regions. The Northern Territory is located in the north of Australia famous for its outback desert landscapes visited mostly in winter. Hence, the peak visitation in the Northern Territory is in the July (winter) quarter in contrast to January (summer) quarter for the rest of the regions.
### Bibliography
Anscombe, F. J. (1973). Graphs in statistical analysis. *The American Statistician*, *27*(1), 1721.
## 2.7 Lag plots
Figure [2.19](https://otexts.com/fpp3/lag-plots.html#fig:beerlagplot) displays scatterplots of quarterly Australian beer production (introduced in Figure [1.1](https://otexts.com/fpp3/data-methods.html#fig:beer)), where the horizontal axis shows lagged values of the time series. Each graph shows \(y_{t}\) plotted against \(y_{t-k}\) for different values of \(k\).
```
recent_production <- aus_production |>
filter(year(Quarter) >= 2000)
recent_production |>
gg_lag(Beer, geom = "point") +
labs(x = "lag(Beer, k)")
```
![Lagged scatterplots for quarterly beer production.](https://otexts.com/fpp3/fpp_files/figure-html/beerlagplot-1.png)
Figure 2.19: Lagged scatterplots for quarterly beer production.
Here the colours indicate the quarter of the variable on the vertical axis. The relationship is strongly positive at lags 4 and 8, reflecting the strong seasonality in the data. The negative relationship seen for lags 2 and 6 occurs because peaks (in Q4) are plotted against troughs (in Q2)
## 2.8 Autocorrelation
Just as correlation measures the extent of a linear relationship between two variables, autocorrelation measures the linear relationship between *lagged values* of a time series.
There are several autocorrelation coefficients, corresponding to each panel in the lag plot. For example, \(r_{1}\) measures the relationship between \(y_{t}\) and \(y_{t-1}\), \(r_{2}\) measures the relationship between \(y_{t}\) and \(y_{t-2}\), and so on.
The value of \(r_{k}\) can be written as
\[
r_{k} = \frac{\sum\limits_{t=k+1}^T (y_{t}-\bar{y})(y_{t-k}-\bar{y})}
{\sum\limits_{t=1}^T (y_{t}-\bar{y})^2},
\]
where \(T\) is the length of the time series. The autocorrelation coefficients make up the *autocorrelation function* or ACF.
The autocorrelation coefficients for the beer production data can be computed using the `ACF()` function.
```
recent_production |> ACF(Beer, lag_max = 9)
#> # A tsibble: 9 x 2 [1Q]
#> lag acf
#> <cf_lag> <dbl>
#> 1 1Q -0.0530
#> 2 2Q -0.758
#> 3 3Q -0.0262
#> 4 4Q 0.802
#> 5 5Q -0.0775
#> 6 6Q -0.657
#> 7 7Q 0.00119
#> 8 8Q 0.707
#> 9 9Q -0.0888
```
The values in the `acf` column are \(r_1,\dots,r_9\), corresponding to the nine scatterplots in Figure [2.19](https://otexts.com/fpp3/lag-plots.html#fig:beerlagplot). We usually plot the ACF to see how the correlations change with the lag \(k\). The plot is sometimes known as a *correlogram*.
```
recent_production |>
ACF(Beer) |>
autoplot() + labs(title="Australian beer production")
```
![Autocorrelation function of quarterly beer production.](https://otexts.com/fpp3/fpp_files/figure-html/beeracf-1.png)
Figure 2.20: Autocorrelation function of quarterly beer production.
In this graph:
* \(r_{4}\) is higher than for the other lags. This is due to the seasonal pattern in the data: the peaks tend to be four quarters apart and the troughs tend to be four quarters apart.
* \(r_{2}\) is more negative than for the other lags because troughs tend to be two quarters behind peaks.
* The dashed blue lines indicate whether the correlations are significantly different from zero (as explained in Section [2.9](https://otexts.com/fpp3/wn.html#wn)).
### Trend and seasonality in ACF plots
When data have a trend, the autocorrelations for small lags tend to be large and positive because observations nearby in time are also nearby in value. So the ACF of a trended time series tends to have positive values that slowly decrease as the lags increase.
When data are seasonal, the autocorrelations will be larger for the seasonal lags (at multiples of the seasonal period) than for other lags.
When data are both trended and seasonal, you see a combination of these effects. The `a10` data plotted in Figure [2.2](https://otexts.com/fpp3/time-plots.html#fig:a10plot) shows both trend and seasonality. Its ACF is shown in Figure [2.21](https://otexts.com/fpp3/acf.html#fig:acfa10). The slow decrease in the ACF as the lags increase is due to the trend, while the “scalloped” shape is due to the seasonality.
```
a10 |>
ACF(Cost, lag_max = 48) |>
autoplot() +
labs(title="Australian antidiabetic drug sales")
```
![ACF of monthly Australian antidiabetic drug sales.](https://otexts.com/fpp3/fpp_files/figure-html/acfa10-1.png)
Figure 2.21: ACF of monthly Australian antidiabetic drug sales.
## 2.9 White noise
Time series that show no autocorrelation are called **white noise**. Figure [2.22](https://otexts.com/fpp3/wn.html#fig:wnoise) gives an example of a white noise series.
```
set.seed(30)
y <- tsibble(sample = 1:50, wn = rnorm(50), index = sample)
y |> autoplot(wn) + labs(title = "White noise", y = "")
```
![A white noise time series.](https://otexts.com/fpp3/fpp_files/figure-html/wnoise-1.png)
Figure 2.22: A white noise time series.
```
y |>
ACF(wn) |>
autoplot() + labs(title = "White noise")
```
![Autocorrelation function for the white noise series.](https://otexts.com/fpp3/fpp_files/figure-html/wnoiseacf-1.png)
Figure 2.23: Autocorrelation function for the white noise series.
For white noise series, we expect each autocorrelation to be close to zero. Of course, they will not be exactly equal to zero as there is some random variation. For a white noise series, we expect 95% of the spikes in the ACF to lie within \(\pm 1.96/\sqrt{T}\) where \(T\) is the length of the time series. It is common to plot these bounds on a graph of the ACF (the blue dashed lines above). If one or more large spikes are outside these bounds, or if substantially more than 5% of spikes are outside these bounds, then the series is probably not white noise.
In this example, \(T=50\) and so the bounds are at \(\pm 1.96/\sqrt{50} = \pm 0.28\). All of the autocorrelation coefficients lie within these limits, confirming that the data are white noise.
## 2.10 Exercises
1. Explore the following four time series: `Bricks` from `aus_production`, `Lynx` from `pelt`, `Close` from `gafa_stock`, `Demand` from `vic_elec`.
* Use `?` (or `help()`) to find out about the data in each series.
* What is the time interval of each series?
* Use `autoplot()` to produce a time plot of each series.
* For the last plot, modify the axis labels and title.
2. Use `filter()` to find what days corresponded to the peak closing price for each of the four stocks in `gafa_stock`.
3. Download the file `tute1.csv` from [the book website](https://bit.ly/fpptute1), open it in Excel (or some other spreadsheet application), and review its contents. You should find four columns of information. Columns B through D each contain a quarterly series, labelled Sales, AdBudget and GDP. Sales contains the quarterly sales for a small company over the period 1981-2005. AdBudget is the advertising budget and GDP is the gross domestic product. All series have been adjusted for inflation.
1. You can read the data into R with the following script:
```
tute1 <- readr::read_csv("tute1.csv")
View(tute1)
```
2. Convert the data to time series
```
mytimeseries <- tute1 |>
mutate(Quarter = yearquarter(Quarter)) |>
as_tsibble(index = Quarter)
```
3. Construct time series plots of each of the three series
```
mytimeseries |>
pivot_longer(-Quarter) |>
ggplot(aes(x = Quarter, y = value, colour = name)) +
geom_line() +
facet_grid(name ~ ., scales = "free_y")
```
Check what happens when you dont include `facet_grid()`.
4. The `USgas` package contains data on the demand for natural gas in the US.
1. Install the `USgas` package.
2. Create a tsibble from `us_total` with year as the index and state as the key.
3. Plot the annual natural gas consumption by state for the New England area (comprising the states of Maine, Vermont, New Hampshire, Massachusetts, Connecticut and Rhode Island).
5. 1. Download `tourism.xlsx` from [the book website](https://bit.ly/fpptourism) and read it into R using `readxl::read_excel()`.
2. Create a tsibble which is identical to the `tourism` tsibble from the `tsibble` package.
3. Find what combination of `Region` and `Purpose` had the maximum number of overnight trips on average.
4. Create a new tsibble which combines the Purposes and Regions, and just has total trips by State.
6. The `aus_arrivals` data set comprises quarterly international arrivals to Australia from Japan, New Zealand, UK and the US.
* Use `autoplot()`, `gg_season()` and `gg_subseries()` to compare the differences between the arrivals from these four countries.
* Can you identify any unusual observations?
7. Monthly Australian retail data is provided in `aus_retail`. Select one of the time series as follows (but choose your own seed value):
```
set.seed(12345678)
myseries <- aus_retail |>
filter(`Series ID` == sample(aus_retail$`Series ID`,1))
```
Explore your chosen retail time series using the following functions:
`autoplot()`, `gg_season()`, `gg_subseries()`, `gg_lag()`,
`ACF() |> autoplot()`
Can you spot any seasonality, cyclicity and trend? What do you learn about the series?
8. Use the following graphics functions: `autoplot()`, `gg_season()`, `gg_subseries()`, `gg_lag()`, `ACF()` and explore features from the following time series: “Total Private” `Employed` from `us_employment`, `Bricks` from `aus_production`, `Hare` from `pelt`, “H02” `Cost` from `PBS`, and `Barrels` from `us_gasoline`.
* Can you spot any seasonality, cyclicity and trend?
* What do you learn about the series?
* What can you say about the seasonal patterns?
* Can you identify any unusual years?
9. The following time plots and ACF plots correspond to four different time series. Your task is to match each time plot in the first row with one of the ACF plots in the second row.
![](https://otexts.com/fpp3/fpp_files/figure-html/acfguess-1.png)
10. The `aus_livestock` data contains the monthly total number of pigs slaughtered in Victoria, Australia, from Jul 1972 to Dec 2018. Use `filter()` to extract pig slaughters in Victoria between 1990 and 1995. Use `autoplot()` and `ACF()` for this data. How do they differ from white noise? If a longer period of data is used, what difference does it make to the ACF?
11. 1. Use the following code to compute the daily changes in Google closing stock prices.
```
dgoog <- gafa_stock |>
filter(Symbol == "GOOG", year(Date) >= 2018) |>
mutate(trading_day = row_number()) |>
update_tsibble(index = trading_day, regular = TRUE) |>
mutate(diff = difference(Close))
```
2. Why was it necessary to re-index the tsibble?
3. Plot these differences and their ACF.
4. Do the changes in the stock prices look like white noise?
## 2.11 Further reading
* W. S. Cleveland ([1993](#ref-Cleveland1993)) is a classic book on the principles of visualisation for data analysis. While it is more than 20 years old, the ideas are timeless.
* Unwin ([2015](#ref-Unwin2015)) is a modern introduction to graphical data analysis using R. It does not have much information on time series graphics, but plenty of excellent general advice on using graphics for data analysis.
### Bibliography
Cleveland, W. S. (1993). *Visualizing data*. Hobart Press.
Unwin, A. (2015). *Graphical data analysis with R*. Chapman; Hall/CRC.
@@ -0,0 +1,679 @@
Source: https://otexts.com/fpp3/decomposition.html (chapter decomposition, 9 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 03-time-series-decomposition
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 3 Time series decomposition
Time series data can exhibit a variety of patterns, and it is often helpful to split a time series into several components, each representing an underlying pattern category.
In Section [2.3](https://otexts.com/fpp3/tspatterns.html#tspatterns) we discussed three types of time series patterns: trend, seasonality and cycles. When we decompose a time series into components, we usually combine the trend and cycle into a single **trend-cycle** component (often just called the **trend** for simplicity). Thus we can think of a time series as comprising three components: a trend-cycle component, a seasonal component, and a remainder component (containing anything else in the time series). For some time series (e.g., those that are observed at least daily), there can be more than one seasonal component, corresponding to the different seasonal periods.
In this chapter, we consider the most common methods for extracting these components from a time series. Often this is done to help improve understanding of the time series, but it can also be used to improve forecast accuracy.
When decomposing a time series, it is sometimes helpful to first transform or adjust the series in order to make the decomposition (and later analysis) as simple as possible. So we will begin by discussing transformations and adjustments.
## 3.1 Transformations and adjustments
Adjusting the historical data can often lead to a simpler time series. Here, we deal with four kinds of adjustments: calendar adjustments, population adjustments, inflation adjustments and mathematical transformations. The purpose of these adjustments and transformations is to simplify the patterns in the historical data by removing known sources of variation, or by making the pattern more consistent across the whole data set. Simpler patterns are usually easier to model and lead to more accurate forecasts.
### Calendar adjustments
Some of the variation seen in seasonal data may be due to simple calendar effects. In such cases, it is usually much easier to remove the variation before doing any further analysis.
For example, if you are studying the total monthly sales in a retail store, there will be variation between the months simply because of the different numbers of trading days in each month, in addition to the seasonal variation across the year. It is easy to remove this variation by computing average sales per trading day in each month, rather than total sales in the month. Then we effectively remove the calendar variation.
### Population adjustments
Any data that are affected by population changes can be adjusted to give per-capita data. That is, consider the data per person (or per thousand people, or per million people) rather than the total. For example, if you are studying the number of hospital beds in a particular region over time, the results are much easier to interpret if you remove the effects of population changes by considering the number of beds per thousand people. Then you can see whether there have been real increases in the number of beds, or whether the increases are due entirely to population increases. It is possible for the total number of beds to increase, but the number of beds per thousand people to decrease. This occurs when the population is increasing faster than the number of hospital beds. For most data that are affected by population changes, it is best to use per-capita data rather than the totals.
This can be seen in the `global_economy` dataset, where a common transformation of GDP is GDP per-capita.
```
global_economy |>
filter(Country == "Australia") |>
autoplot(GDP/Population) +
labs(title= "GDP per capita", y = "$US")
```
![Australian GDP per-capita.](https://otexts.com/fpp3/fpp_files/figure-html/gdp-per-capita-1.png)
Figure 3.1: Australian GDP per-capita.
### Inflation adjustments
Data which are affected by the value of money are best adjusted before modelling. For example, the average cost of a new house will have increased over the last few decades due to inflation. A $200,000 house this year is not the same as a $200,000 house twenty years ago. For this reason, financial time series are usually adjusted so that all values are stated in dollar values from a particular year. For example, the house price data may be stated in year 2000 dollars.
To make these adjustments, a price index is used. If \(z_{t}\) denotes the price index and \(y_{t}\) denotes the original house price in year \(t\), then \(x_{t} = y_{t}/z_{t} \* z_{2000}\) gives the adjusted house price at year 2000 dollar values. Price indexes are often constructed by government agencies. For consumer goods, a common price index is the Consumer Price Index (or CPI).
This allows us to compare the growth or decline of industries relative to a common price value. For example, looking at aggregate annual “newspaper and book” retail turnover from `aus_retail`, and adjusting the data for inflation using CPI from `global_economy` allows us to understand the changes over time.
```
print_retail <- aus_retail |>
filter(Industry == "Newspaper and book retailing") |>
group_by(Industry) |>
index_by(Year = year(Month)) |>
summarise(Turnover = sum(Turnover))
aus_economy <- global_economy |>
filter(Code == "AUS")
```
```
print_retail |>
left_join(aus_economy, by = "Year") |>
mutate(Adjusted_turnover = Turnover / CPI * 100) |>
pivot_longer(c(Turnover, Adjusted_turnover),
values_to = "Turnover") |>
mutate(name = factor(name,
levels=c("Turnover","Adjusted_turnover"))) |>
ggplot(aes(x = Year, y = Turnover)) +
geom_line() +
facet_grid(name ~ ., scales = "free_y") +
labs(title = "Turnover: Australian print media industry",
y = "$AU")
```
![Turnover for the Australian print media industry in Australian dollars. The 'Adjusted' turnover has been adjusted for inflation using the CPI.](https://otexts.com/fpp3/fpp_files/figure-html/printretail-1.png)
Figure 3.2: Turnover for the Australian print media industry in Australian dollars. The Adjusted turnover has been adjusted for inflation using the CPI.
By adjusting for inflation using the CPI, we can see that Australias newspaper and book retailing industry has been in decline much longer than the original data suggests. The adjusted turnover is in 2010 Australian dollars, as CPI is 100 in 2010 in this data set.
### Mathematical transformations
If the data shows variation that increases or decreases with the level of the series, then a transformation can be useful. For example, a logarithmic transformation is often useful. If we denote the original observations as \(y_{1},\dots,y_{T}\) and the transformed observations as \(w_{1}, \dots, w_{T}\), then \(w_t = \log(y_t)\). Logarithms are useful because they are interpretable: changes in a log value are relative (or percentage) changes on the original scale. So if log base 10 is used, then an increase of 1 on the log scale corresponds to a multiplication of 10 on the original scale. If any value of the original series is zero or negative, then logarithms are not possible.
Sometimes other transformations are also used (although they are not so interpretable). For example, square roots and cube roots can be used. These are called **power transformations** because they can be written in the form \(w_{t} = y_{t}^p\).
A useful family of transformations, that includes both logarithms and power transformations, is the family of **Box-Cox transformations** ([Box & Cox, 1964](#ref-BC64)), which depend on the parameter \(\lambda\) and are defined as follows:
\[\begin{equation}
w_t =
\begin{cases}
\log(y_t) & \text{if $\lambda=0$}; \\
(\text{sign}(y_t)|y_t|^\lambda-1)/\lambda & \text{otherwise}.
\end{cases}
\tag{3.1}
\end{equation}\]
This is actually a modified Box-Cox transformation, discussed in Bickel & Doksum ([1981](#ref-Bickel1981)), which allows for negative values of \(y_t\) provided \(\lambda > 0\).
The logarithm in a Box-Cox transformation is always a natural logarithm (i.e., to base \(e\)). So if \(\lambda=0\), natural logarithms are used, but if \(\lambda\ne0\), a power transformation is used, followed by some simple scaling.
If \(\lambda=1\), then \(w_t = y_t-1\), so the transformed data is shifted downwards but there is no change in the shape of the time series. For all other values of \(\lambda\), the time series will change shape.
Use the slider below to see the effect of varying \(\lambda\) to transform Australian quarterly gas production:
Figure 3.3: Box-Cox transformations applied to Australian quarterly gas production.
A good value of \(\lambda\) is one which makes the size of the seasonal variation about the same across the whole series, as that makes the forecasting model simpler. In this case, \(\lambda=0.10\) works quite well, although any value of \(\lambda\) between 0.0 and 0.2 would give similar results.
The `guerrero` feature ([Guerrero, 1993](#ref-Guerrero93)) can be used to choose a value of lambda for you. In this case it chooses \(\lambda=0.11\). (See the next chapter for discussion of the `features()` function.)
```
lambda <- aus_production |>
features(Gas, features = guerrero) |>
pull(lambda_guerrero)
aus_production |>
autoplot(box_cox(Gas, lambda)) +
labs(y = "",
title = latex2exp::TeX(paste0(
"Transformed gas production with $\\lambda$ = ",
round(lambda,2))))
```
![Transformed Australian quarterly gas production with the $\lambda$ parameter chosen using the Guerrero method.](https://otexts.com/fpp3/fpp_files/figure-html/BoxCoxlambda-1.png)
Figure 3.4: Transformed Australian quarterly gas production with the \(\lambda\) parameter chosen using the Guerrero method.
### Bibliography
Bickel, P. J., & Doksum, K. A. (1981). An analysis of transformations revisited. *Journal of the American Statistical Association*, *76*(374), 296311.
Box, G. E. P., & Cox, D. R. (1964). An analysis of transformations. *Journal of the Royal Statistical Society. Series B, Statistical Methodology*, *26*(2), 211252.
Guerrero, V. M. (1993). Time-series analysis supported by power transformations. *Journal of Forecasting*, *12*(1), 3748.
## 3.2 Time series components
If we assume an additive decomposition, then we can write
\[
y_{t} = S_{t} + T_{t} + R_t,
\]
where \(y_{t}\) is the data, \(S_{t}\) is the seasonal component, \(T_{t}\) is the trend-cycle component, and \(R_t\) is the remainder component, all at period \(t\). Alternatively, a multiplicative decomposition would be written as
\[
y_{t} = S_{t} \times T_{t} \times R_t.
\]
The additive decomposition is the most appropriate if the magnitude of the seasonal fluctuations, or the variation around the trend-cycle, does not vary with the level of the time series. When the variation in the seasonal pattern, or the variation around the trend-cycle, appears to be proportional to the level of the time series, then a multiplicative decomposition is more appropriate. Multiplicative decompositions are common with economic time series.
An alternative to using a multiplicative decomposition is to first transform the data until the variation in the series appears to be stable over time, then use an additive decomposition. When a log transformation has been used, this is equivalent to using a multiplicative decomposition on the original data because
\[
y_{t} = S_{t} \times T_{t} \times R_t \quad\text{is equivalent to}\quad
\log y_{t} = \log S_{t} + \log T_{t} + \log R_t.
\]
### Example: Employment in the US retail sector
We will look at several methods for obtaining the components \(S_{t}\), \(T_{t}\) and \(R_{t}\) later in this chapter, but first it is helpful to see an example. We will decompose the number of persons employed in retail as shown in Figure [3.5](https://otexts.com/fpp3/components.html#fig:usretailemployment). The data shows the total monthly number of persons in thousands employed in the retail sector across the US since 1990.
```
us_retail_employment <- us_employment |>
filter(year(Month) >= 1990, Title == "Retail Trade") |>
select(-Series_ID)
autoplot(us_retail_employment, Employed) +
labs(y = "Persons (thousands)",
title = "Total employment in US retail")
```
![Total number of persons employed in US retail.](https://otexts.com/fpp3/fpp_files/figure-html/usretailemployment-1.png)
Figure 3.5: Total number of persons employed in US retail.
To illustrate the ideas, we will use the STL decomposition method, which is discussed in Section [3.6](https://otexts.com/fpp3/stl.html#stl).
```
dcmp <- us_retail_employment |>
model(stl = STL(Employed))
components(dcmp)
#> # A dable: 357 x 7 [1M]
#> # Key: .model [1]
#> # : Employed = trend + season_year + remainder
#> .model Month Employed trend season_year remainder season_adjust
#> <chr> <mth> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 stl 1990 Jan 13256. 13288. -33.0 0.836 13289.
#> 2 stl 1990 Feb 12966. 13269. -258. -44.6 13224.
#> 3 stl 1990 Mar 12938. 13250. -290. -22.1 13228.
#> 4 stl 1990 Apr 13012. 13231. -220. 1.05 13232.
#> 5 stl 1990 May 13108. 13211. -114. 11.3 13223.
#> 6 stl 1990 Jun 13183. 13192. -24.3 15.5 13207.
#> 7 stl 1990 Jul 13170. 13172. -23.2 21.6 13193.
#> 8 stl 1990 Aug 13160. 13151. -9.52 17.8 13169.
#> 9 stl 1990 Sep 13113. 13131. -39.5 22.0 13153.
#> 10 stl 1990 Oct 13185. 13110. 61.6 13.2 13124.
#> # 347 more rows
```
The output above shows the components of an STL decomposition. The original data is shown (as `Employed`), followed by the estimated components. This output forms a “dable” or decomposition table. The header to the table shows that the `Employed` series has been decomposed additively.
The `trend` column (containing the trend-cycle \(T_t\)) follows the overall movement of the series, ignoring any seasonality and random fluctuations, as shown in Figure [3.6](https://otexts.com/fpp3/components.html#fig:empltrend).
```
components(dcmp) |>
as_tsibble() |>
autoplot(Employed, colour="gray") +
geom_line(aes(y=trend), colour = "#D55E00") +
labs(
y = "Persons (thousands)",
title = "Total employment in US retail"
)
```
![Total number of persons employed in US retail: the trend-cycle component (orange) and the raw data (grey).](https://otexts.com/fpp3/fpp_files/figure-html/empltrend-1.png)
Figure 3.6: Total number of persons employed in US retail: the trend-cycle component (orange) and the raw data (grey).
We can plot all of the components in a single figure using `autoplot()`, as shown in Figure [3.7](https://otexts.com/fpp3/components.html#fig:emplstl).
```
components(dcmp) |> autoplot()
```
![The total number of persons employed in US retail (top) and its three additive components.](https://otexts.com/fpp3/fpp_files/figure-html/emplstl-1.png)
Figure 3.7: The total number of persons employed in US retail (top) and its three additive components.
The three components are shown separately in the bottom three panels. These components can be added together to reconstruct the data shown in the top panel. Notice that the seasonal component changes over time, so that any two consecutive years have similar patterns, but years far apart may have different seasonal patterns. The remainder component shown in the bottom panel is what is left over when the seasonal and trend-cycle components have been subtracted from the data.
The grey bars to the left of each panel show the relative scales of the components. Each grey bar represents the same length but because the plots are on different scales, the bars vary in size. The large grey bar in the bottom panel shows that the variation in the remainder component is smallest compared to the variation in the data. If we shrank the bottom three panels until their bars became the same size as that in the data panel, then all the panels would be on the same scale.
### Seasonally adjusted data
If the seasonal component is removed from the original data, the resulting values are the “seasonally adjusted” data. For an additive decomposition, the seasonally adjusted data are given by \(y_{t}-S_{t}\), and for multiplicative data, the seasonally adjusted values are obtained using \(y_{t}/S_{t}\).
Figure [3.8](https://otexts.com/fpp3/components.html#fig:empl-retail-sa) shows the seasonally adjusted number of persons employed.
```
components(dcmp) |>
as_tsibble() |>
autoplot(Employed, colour = "gray") +
geom_line(aes(y=season_adjust), colour = "#0072B2") +
labs(y = "Persons (thousands)",
title = "Total employment in US retail")
```
![Seasonally adjusted retail employment data (blue) and the original data (grey).](https://otexts.com/fpp3/fpp_files/figure-html/empl-retail-sa-1.png)
Figure 3.8: Seasonally adjusted retail employment data (blue) and the original data (grey).
If the variation due to seasonality is not of primary interest, the seasonally adjusted series can be useful. For example, monthly unemployment data are usually seasonally adjusted in order to highlight variation due to the underlying state of the economy rather than the seasonal variation. An increase in unemployment due to school leavers seeking work is seasonal variation, while an increase in unemployment due to an economic recession is non-seasonal. Most economic analysts who study unemployment data are more interested in the non-seasonal variation. Consequently, employment data (and many other economic series) are usually seasonally adjusted.
Seasonally adjusted series contain the remainder component as well as the trend-cycle. Therefore, they are not “smooth”, and “downturns” or “upturns” can be misleading. If the purpose is to look for turning points in a series, and interpret any changes in direction, then it is better to use the trend-cycle component rather than the seasonally adjusted data.
## 3.3 Moving averages
The classical method of time series decomposition originated in the 1920s and was widely used until the 1950s. It still forms the basis of many time series decomposition methods, so it is important to understand how it works. The first step in a classical decomposition is to use a moving average method to estimate the trend-cycle, so we begin by discussing moving averages.
### Moving average smoothing
A moving average of order \(m\) can be written as
\[\begin{equation}
\hat{T}_{t} = \frac{1}{m} \sum_{j=-k}^k y_{t+j}, \tag{3.2}
\end{equation}\]
where \(m=2k+1\). That is, the estimate of the trend-cycle at time \(t\) is obtained by averaging values of the time series within \(k\) periods of \(t\). Observations that are nearby in time are also likely to be close in value. Therefore, the average eliminates some of the randomness in the data, leaving a smooth trend-cycle component. We call this an **\(m\)-MA**, meaning a moving average of order \(m\).
For example, consider Figure [3.9](https://otexts.com/fpp3/moving-averages.html#fig:aus-exports) which shows exports of goods and services for Australia as a percentage of GDP from 1960 to 2017. The data are also shown in Table [3.1](https://otexts.com/fpp3/moving-averages.html#tab:aus-exports-tbl).
```
global_economy |>
filter(Country == "Australia") |>
autoplot(Exports) +
labs(y = "% of GDP", title = "Total Australian exports")
```
![Australian exports of goods and services: 1960--2017.](https://otexts.com/fpp3/fpp_files/figure-html/aus-exports-1.png)
Figure 3.9: Australian exports of goods and services: 19602017.
Table 3.1: Annual Australian exports of goods and services: 19602017.
| Year | Exports | 5-MA |
| --- | --- | --- |
| 1960 | 12.99 | |
| 1961 | 12.40 | |
| 1962 | 13.94 | 13.46 |
| 1963 | 13.01 | 13.50 |
| 1964 | 14.94 | 13.61 |
| 1965 | 13.22 | 13.40 |
| 1966 | 12.93 | 13.25 |
| 1967 | 12.88 | 12.66 |
| … | … | … |
| 2010 | 19.84 | 21.21 |
| 2011 | 21.47 | 21.17 |
| 2012 | 21.52 | 20.78 |
| 2013 | 19.99 | 20.81 |
| 2014 | 21.08 | 20.37 |
| 2015 | 20.01 | 20.32 |
| 2016 | 19.25 | |
| 2017 | 21.27 | |
In the last column of this table, a moving average of order 5 is shown, providing an estimate of the trend-cycle. The first value in this column is the average of the first five observations, 19601964; the second value in the 5-MA column is the average of the values for 19611965; and so on. Each value in the 5-MA column is the average of the observations in the five year window centred on the corresponding year. In the notation of Equation [(3.2)](https://otexts.com/fpp3/moving-averages.html#eq:ma), column 5-MA contains the values of \(\hat{T}_{t}\) with \(k=2\) and \(m=2k+1=5\). There are no values for either the first two years or the last two years, because we do not have two observations on either side. Later we will use more sophisticated methods of trend-cycle estimation which do allow estimates near the endpoints.
This is easily computed using `slide_dbl()` from the `slider` package which applies a function to “sliding” time windows. In this case, we use the `mean()` function with a window of size 5.
```
aus_exports <- global_economy |>
filter(Country == "Australia") |>
mutate(
`5-MA` = slider::slide_dbl(Exports, mean,
.before = 2, .after = 2, .complete = TRUE)
)
```
To see what the trend-cycle estimate looks like, we plot it along with the original data in Figure [3.10](https://otexts.com/fpp3/moving-averages.html#fig:aus-exports-plot).
```
aus_exports |>
autoplot(Exports) +
geom_line(aes(y = `5-MA`), colour = "#D55E00") +
labs(y = "% of GDP",
title = "Total Australian exports")
```
![Australian exports (black) along with the 5-MA estimate of the trend-cycle (orange).](https://otexts.com/fpp3/fpp_files/figure-html/aus-exports-plot-1.png)
Figure 3.10: Australian exports (black) along with the 5-MA estimate of the trend-cycle (orange).
Notice that the trend-cycle (in orange) is smoother than the original data and captures the main movement of the time series without all of the minor fluctuations. The order of the moving average determines the smoothness of the trend-cycle estimate. In general, a larger order means a smoother curve. Figure [3.11](https://otexts.com/fpp3/moving-averages.html#fig:aus-exports-compare) shows the effect of changing the order of the moving average for the Australian exports data.
![Different moving averages applied to the Australian exports data.](https://otexts.com/fpp3/fpp_files/figure-html/aus-exports-compare-1.png)
Figure 3.11: Different moving averages applied to the Australian exports data.
Simple moving averages such as these are usually of an odd order (e.g., 3, 5, 7, etc.). This is so they are symmetric: in a moving average of order \(m=2k+1\), the middle observation, and \(k\) observations on either side, are averaged. But if \(m\) was even, it would no longer be symmetric.
### Moving averages of moving averages
It is possible to apply a moving average to a moving average. One reason for doing this is to make an even-order moving average symmetric.
For example, we might take a moving average of order 4, and then apply another moving average of order 2 to the results. In the following table, this has been done for the first few years of the Australian quarterly beer production data.
```
beer <- aus_production |>
filter(year(Quarter) >= 1992) |>
select(Quarter, Beer)
beer_ma <- beer |>
mutate(
`4-MA` = slider::slide_dbl(Beer, mean,
.before = 1, .after = 2, .complete = TRUE),
`2x4-MA` = slider::slide_dbl(`4-MA`, mean,
.before = 1, .after = 0, .complete = TRUE)
)
```
Table 3.2: A moving average of order 4 applied to the quarterly beer data, followed by a moving average of order 2.
| Quarter | Beer | 4-MA | 2x4-MA |
| --- | --- | --- | --- |
| 1992 Q1 | 443.00 | | |
| 1992 Q2 | 410.00 | 451.25 | |
| 1992 Q3 | 420.00 | 448.75 | 450.00 |
| 1992 Q4 | 532.00 | 451.50 | 450.12 |
| 1993 Q1 | 433.00 | 449.00 | 450.25 |
| 1993 Q2 | 421.00 | 444.00 | 446.50 |
| … | … | … | … |
| 2009 Q1 | 415.00 | 430.00 | 428.88 |
| 2009 Q2 | 398.00 | 430.00 | 430.00 |
| 2009 Q3 | 419.00 | 429.75 | 429.88 |
| 2009 Q4 | 488.00 | 423.75 | 426.75 |
| 2010 Q1 | 414.00 | | |
| 2010 Q2 | 374.00 | | |
The notation “\(2\times4\)-MA” in the last column means a 4-MA followed by a 2-MA. The values in the last column are obtained by taking a moving average of order 2 of the values in the previous column. For example, the first two values in the 4-MA column are
451.25=(443+410+420+532)/4
and
448.75=(410+420+532+433)/4.
The first value in the 2x4-MA column is the average of these two:
450.00=(451.25+448.75)/2.
When a 2-MA follows a moving average of an even order (such as 4), it is called a “centred moving average of order 4”. This is because the results are now symmetric. To see that this is the case, we can write the \(2\times4\)-MA as follows:
\[\begin{align\*}
\hat{T}_{t} &= \frac{1}{2}\Big[
\frac{1}{4} (y_{t-2}+y_{t-1}+y_{t}+y_{t+1}) +
\frac{1}{4} (y_{t-1}+y_{t}+y_{t+1}+y_{t+2})\Big] \\
&= \frac{1}{8}y_{t-2}+\frac14y_{t-1} +
\frac14y_{t}+\frac14y_{t+1}+\frac18y_{t+2}.
\end{align\*}\]
It is now a weighted average of observations that is symmetric.
Other combinations of moving averages are also possible. For example, a \(3\times3\)-MA is often used, and consists of a moving average of order 3 followed by another moving average of order 3. In general, an even order MA should be followed by an even order MA to make it symmetric. Similarly, an odd order MA should be followed by an odd order MA.
### Estimating the trend-cycle with seasonal data
The most common use of centred moving averages is for estimating the trend-cycle from seasonal data. Consider the \(2\times4\)-MA:
\[
\hat{T}_{t} = \frac{1}{8}y_{t-2} + \frac14y_{t-1} +
\frac14y_{t} + \frac14y_{t+1} + \frac18y_{t+2}.
\]
When applied to quarterly data, each quarter of the year is given equal weight as the first and last terms apply to the same quarter in consecutive years. Consequently, the seasonal variation will be averaged out and the resulting values of \(\hat{T}_t\) will have little or no seasonal variation remaining. A similar effect would be obtained using a \(2\times 8\)-MA or a \(2\times 12\)-MA to quarterly data.
In general, a \(2\times m\)-MA is equivalent to a weighted moving average of order \(m+1\) where all observations take the weight \(1/m\), except for the first and last terms which take weights \(1/(2m)\). So, if the seasonal period is even and of order \(m\), we use a \(2\times m\)-MA to estimate the trend-cycle. If the seasonal period is odd and of order \(m\), we use a \(m\)-MA to estimate the trend-cycle. For example, a \(2\times 12\)-MA can be used to estimate the trend-cycle of monthly data with annual seasonality and a 7-MA can be used to estimate the trend-cycle of daily data with a weekly seasonality.
Other choices for the order of the MA will usually result in trend-cycle estimates being contaminated by the seasonality in the data.
### Example: Employment in the US retail sector
```
us_retail_employment_ma <- us_retail_employment |>
mutate(
`12-MA` = slider::slide_dbl(Employed, mean,
.before = 5, .after = 6, .complete = TRUE),
`2x12-MA` = slider::slide_dbl(`12-MA`, mean,
.before = 1, .after = 0, .complete = TRUE)
)
us_retail_employment_ma |>
autoplot(Employed, colour = "gray") +
geom_line(aes(y = `2x12-MA`), colour = "#D55E00") +
labs(y = "Persons (thousands)",
title = "Total employment in US retail")
```
![A 2x12-MA applied to the US retail employment series.](https://otexts.com/fpp3/fpp_files/figure-html/empl-MA-1.png)
Figure 3.12: A 2x12-MA applied to the US retail employment series.
Figure [3.12](https://otexts.com/fpp3/moving-averages.html#fig:empl-MA) shows a \(2\times12\)-MA applied to the total number of persons employed in the US retail sector. Notice that the smooth line shows no seasonality; it is almost the same as the trend-cycle shown in Figure [3.6](https://otexts.com/fpp3/components.html#fig:empltrend), which was estimated using a much more sophisticated method than a moving average. Any other choice for the order of the moving average (except for 24, 36, etc.) would have resulted in a smooth line that showed some seasonal fluctuations.
### Weighted moving averages
Combinations of moving averages result in weighted moving averages. For example, the \(2\times4\)-MA discussed above is equivalent to a weighted 5-MA with weights given by
\(\left[\frac{1}{8},\frac{1}{4},\frac{1}{4},\frac{1}{4},\frac{1}{8}\right]\). In general, a weighted \(m\)-MA can be written as
\[
\hat{T}_t = \sum_{j=-k}^k a_j y_{t+j},
\]
where \(k=(m-1)/2\), and the weights are given by \(\left[a_{-k},\dots,a_k\right]\). It is important that the weights all sum to one and that they are symmetric so that \(a_j = a_{-j}\). The simple \(m\)-MA is a special case where all of the weights are equal to \(1/m\).
A major advantage of weighted moving averages is that they yield a smoother estimate of the trend-cycle. Instead of observations entering and leaving the calculation at full weight, their weights slowly increase and then slowly decrease, resulting in a smoother curve.
## 3.4 Classical decomposition
The classical decomposition method originated in the 1920s. It is a relatively simple procedure, and forms the starting point for most other methods of time series decomposition. There are two forms of classical decomposition: an additive decomposition and a multiplicative decomposition. These are described below for a time series with seasonal period \(m\) (e.g., \(m=4\) for quarterly data, \(m=12\) for monthly data, \(m=7\) for daily data with a weekly pattern).
In classical decomposition, we assume that the seasonal component is constant from year to year. For multiplicative seasonality, the \(m\) values that form the seasonal component are sometimes called the “seasonal indices”.
### Additive decomposition
Step 1
: If \(m\) is an even number, compute the trend-cycle component \(\hat{T}_t\) using a \(2\times m\)-MA. If \(m\) is an odd number, compute the trend-cycle component \(\hat{T}_t\) using an \(m\)-MA.
Step 2
: Calculate the detrended series: \(y_t - \hat{T}_t\).
Step 3
: To estimate the seasonal component for each season, simply average the detrended values for that season. For example, with monthly data, the seasonal component for March is the average of all the detrended March values in the data. These seasonal component values are then adjusted to ensure that they add to zero. The seasonal component is obtained by stringing together these monthly values, and then replicating the sequence for each year of data. This gives \(\hat{S}_t\).
Step 4
: The remainder component is calculated by subtracting the estimated seasonal and trend-cycle components: \(\hat{R}_t = y_t - \hat{T}_t - \hat{S}_t\).
Figure [3.13](https://otexts.com/fpp3/classical-decomposition.html#fig:classical-empl) shows a classical decomposition of the total retail employment series across the US.
```
us_retail_employment |>
model(
classical_decomposition(Employed, type = "additive")
) |>
components() |>
autoplot() +
labs(title = "Classical additive decomposition of total
US retail employment")
```
![A classical additive decomposition of US retail employment.](https://otexts.com/fpp3/fpp_files/figure-html/classical-empl-1.png)
Figure 3.13: A classical additive decomposition of US retail employment.
### Multiplicative decomposition
A classical multiplicative decomposition is similar, except that the subtractions are replaced by divisions.
Step 1
: If \(m\) is an even number, compute the trend-cycle component \(\hat{T}_t\) using a \(2\times m\)-MA. If \(m\) is an odd number, compute the trend-cycle component \(\hat{T}_t\) using an \(m\)-MA.
Step 2
: Calculate the detrended series: \(y_t/ \hat{T}_t\).
Step 3
: To estimate the seasonal component for each season, simply average the detrended values for that season. For example, with monthly data, the seasonal index for March is the average of all the detrended March values in the data. These seasonal indexes are then adjusted to ensure that they add to \(m\). The seasonal component is obtained by stringing together these monthly indexes, and then replicating the sequence for each year of data. This gives \(\hat{S}_t\).
Step 4
: The remainder component is calculated by dividing out the estimated seasonal and trend-cycle components: \(\hat{R}_{t} = y_t /( \hat{T}_t \hat{S}_t)\).
### Comments on classical decomposition
While classical decomposition is still widely used, it is not recommended, as there are now several much better methods. Some of the problems with classical decomposition are summarised below.
* The estimate of the trend-cycle is unavailable for the first few and last few observations. For example, if \(m=12\), there is no trend-cycle estimate for the first six or the last six observations. Consequently, there is also no estimate of the remainder component for the same time periods.
* The trend-cycle estimate tends to over-smooth rapid rises and falls in the data.
* Classical decomposition methods assume that the seasonal component repeats from year to year. For many series, this is a reasonable assumption, but for some longer series it is not. For example, electricity demand patterns have changed over time as air conditioning has become more widespread. In many locations, the seasonal usage pattern from several decades ago had its maximum demand in winter (due to heating), while the current seasonal pattern has its maximum demand in summer (due to air conditioning). Classical decomposition methods are unable to capture these seasonal changes over time.
* Occasionally, the values of the time series in a small number of periods may be particularly unusual. For example, the monthly air passenger traffic may be affected by an industrial dispute, making the traffic during the dispute different from usual. The classical method is not robust to these kinds of unusual values.
## 3.5 Methods used by official statistics agencies
Official statistics agencies (such as the US Census Bureau and the Australian Bureau of Statistics) are responsible for a large number of official economic and social time series. These agencies have developed their own decomposition procedures which are used for seasonal adjustment. Most of them use variants of the X-11 method, or the SEATS method, or a combination of the two. These methods are designed specifically to work with quarterly and monthly data, which are the most common series handled by official statistics agencies. They will not handle seasonality of other kinds, such as daily data, or hourly data, or weekly data. We will use the latest implementation of this group of methods known as “X-13ARIMA-SEATS”. For the methods discussed in this section, you will need to have installed the `seasonal` package in R.
### X-11 method
The X-11 method originated in the US Census Bureau and was further developed by Statistics Canada. It is based on classical decomposition, but includes many extra steps and features in order to overcome the drawbacks of classical decomposition that were discussed in the previous section. In particular, trend-cycle estimates are available for all observations including the end points, and the seasonal component is allowed to vary slowly over time. X-11 also handles trading day variation, holiday effects and the effects of known predictors. There are methods for both additive and multiplicative decomposition. The process is entirely automatic and tends to be highly robust to outliers and level shifts in the time series. The details of the X-11 method are described in Dagum & Bianconcini ([2016](#ref-Dagum2016)).
```
x11_dcmp <- us_retail_employment |>
model(x11 = X_13ARIMA_SEATS(Employed ~ x11())) |>
components()
autoplot(x11_dcmp) +
labs(title =
"Decomposition of total US retail employment using X-11.")
```
![A multiplicative decomposition of US retail employment using X-11.](https://otexts.com/fpp3/fpp_files/figure-html/x11-1.png)
Figure 3.14: A multiplicative decomposition of US retail employment using X-11.
Compare this decomposition with the STL decomposition shown in Figure [3.7](https://otexts.com/fpp3/components.html#fig:emplstl) and the classical decomposition shown in Figure [3.13](https://otexts.com/fpp3/classical-decomposition.html#fig:classical-empl). The default approach for `X_13ARIMA_SEATS` shown here is a multiplicative decomposition, whereas the STL and classical decompositions shown earlier were additive; but it doesnt make much difference in this case. The X-11 trend-cycle has captured the sudden fall in the data due to the 20072008 global financial crisis better than either of the other two methods (where the effect of the crisis has leaked into the remainder component). Also, the unusual observation in 1996 is now more clearly seen in the X-11 remainder component.
Figure [3.15](https://otexts.com/fpp3/methods-used-by-official-statistics-agencies.html#fig:x11-seasadj) shows the trend-cycle component and the seasonally adjusted data, along with the original data. The seasonally adjusted data is very similar to the trend-cycle component in this example, so it is hard to distinguish them on the plot.
```
x11_dcmp |>
ggplot(aes(x = Month)) +
geom_line(aes(y = Employed, colour = "Data")) +
geom_line(aes(y = season_adjust,
colour = "Seasonally Adjusted")) +
geom_line(aes(y = trend, colour = "Trend")) +
labs(y = "Persons (thousands)",
title = "Total employment in US retail") +
scale_colour_manual(
values = c("gray", "#0072B2", "#D55E00"),
breaks = c("Data", "Seasonally Adjusted", "Trend")
)
```
![US retail employment: the original data (grey), the trend-cycle component (orange) and the seasonally adjusted data (barely visible in blue).](https://otexts.com/fpp3/fpp_files/figure-html/x11-seasadj-1.png)
Figure 3.15: US retail employment: the original data (grey), the trend-cycle component (orange) and the seasonally adjusted data (barely visible in blue).
It can be useful to use seasonal plots and seasonal sub-series plots of the seasonal component, to help us visualise the variation in the seasonal component over time. Figure [3.16](https://otexts.com/fpp3/methods-used-by-official-statistics-agencies.html#fig:print-media3) shows a seasonal sub-series plot of the seasonal component from Figure [3.14](https://otexts.com/fpp3/methods-used-by-official-statistics-agencies.html#fig:x11). In this case, there are only small changes over time.
```
x11_dcmp |>
gg_subseries(seasonal)
```
![Seasonal sub-series plot of the seasonal component from the X-11 method applied to total US retail employment.](https://otexts.com/fpp3/fpp_files/figure-html/print-media3-1.png)
Figure 3.16: Seasonal sub-series plot of the seasonal component from the X-11 method applied to total US retail employment.
### SEATS method
“SEATS” stands for “Seasonal Extraction in ARIMA Time Series” (ARIMA models are discussed in Chapter [9](https://otexts.com/fpp3/arima.html#arima)). This procedure was developed at the Bank of Spain, and is now widely used by government agencies around the world. The details are beyond the scope of this book. However, a complete discussion of the method is available in Dagum & Bianconcini ([2016](#ref-Dagum2016)).
```
seats_dcmp <- us_retail_employment |>
model(seats = X_13ARIMA_SEATS(Employed ~ seats())) |>
components()
autoplot(seats_dcmp) +
labs(title =
"Decomposition of total US retail employment using SEATS")
```
![A decomposition of US retail employment obtained using SEATS.](https://otexts.com/fpp3/fpp_files/figure-html/seats-1.png)
Figure 3.17: A decomposition of US retail employment obtained using SEATS.
Figure [3.17](https://otexts.com/fpp3/methods-used-by-official-statistics-agencies.html#fig:seats) shows the SEATS method applied to the total retail employment series across the US. The result is quite similar to that obtained using the X-11 method shown in Figure [3.14](https://otexts.com/fpp3/methods-used-by-official-statistics-agencies.html#fig:x11).
The `X_13ARIMA_SEATS()` function calls the `seasonal` package which has many options for handling variations of X-11 and SEATS. See [the package website](https://bit.ly/seaspkg) for a detailed introduction to the options and features available.
### Bibliography
Dagum, E. B., & Bianconcini, S. (2016). *Seasonal adjustment methods and real time trend-cycle estimation*. Springer.
## 3.6 STL decomposition
STL is a versatile and robust method for decomposing time series. STL is an acronym for “Seasonal and Trend decomposition using Loess”, while loess is a method for estimating nonlinear relationships. The STL method was developed by R. B. Cleveland et al. ([1990](#ref-Cleveland1990)), and later extended to handle multiple seasonal patterns by Bandara et al. ([2025](#ref-mstl)).
STL has several advantages over classical decomposition, and the SEATS and X-11 methods:
* Unlike SEATS and X-11, STL will handle any type of seasonality, not only monthly and quarterly data.
* The seasonal component is allowed to change over time, and the rate of change can be controlled by the user.
* The smoothness of the trend-cycle can also be controlled by the user.
* It can be robust to outliers (i.e., the user can specify a robust decomposition), so that occasional unusual observations will not affect the estimates of the trend-cycle and seasonal components. They will, however, affect the remainder component.
On the other hand, STL has some disadvantages. In particular, it does not handle trading day or calendar variation automatically, and it only provides facilities for additive decompositions.
A multiplicative decomposition can be obtained by first taking logs of the data, then back-transforming the components. Decompositions that are between additive and multiplicative can be obtained using a Box-Cox transformation of the data with \(0<\lambda<1\). A value of \(\lambda=0\) gives a multiplicative decomposition while \(\lambda=1\) gives an additive decomposition.
The best way to begin learning how to use STL is to see some examples and experiment with the settings. Figure [3.7](https://otexts.com/fpp3/components.html#fig:emplstl) showed an example of an STL decomposition applied to the total US retail employment series. Figure [3.18](https://otexts.com/fpp3/stl.html#fig:empl-stl2) shows an alternative STL decomposition where the trend-cycle is more flexible, the seasonal pattern is fixed, and the robust option has been used.
```
us_retail_employment |>
model(
STL(Employed ~ trend(window = 7) +
season(window = "periodic"),
robust = TRUE)) |>
components() |>
autoplot()
```
![Total US retail employment (top) and its three additive components obtained from a robust STL decomposition with flexible trend-cycle and fixed seasonality.](https://otexts.com/fpp3/fpp_files/figure-html/empl-stl2-1.png)
Figure 3.18: Total US retail employment (top) and its three additive components obtained from a robust STL decomposition with flexible trend-cycle and fixed seasonality.
The two main parameters to be chosen when using STL are the trend-cycle window `trend(window = ?)` and the seasonal window `season(window = ?)`. These control how rapidly the trend-cycle and seasonal components can change. Smaller values allow for more rapid changes. Both trend and seasonal windows should be odd numbers; trend window is the number of consecutive observations to be used when estimating the trend-cycle; season window is the number of consecutive years to be used in estimating each value in the seasonal component. Setting the seasonal window to be infinite is equivalent to forcing the seasonal component to be periodic `season(window='periodic')` (i.e., identical across years). This was the case in Figure [3.18](https://otexts.com/fpp3/stl.html#fig:empl-stl2).
By default, the `STL()` function provides a convenient automated STL decomposition using a seasonal window of `season(window=11)` when there is a single seasonal period, and the trend window chosen automatically from the seasonal period. The default setting for monthly data is `trend(window=21)`. For multiple seasonal periods, the default seasonal windows are 11, 15, 19, etc., with larger windows corresponding to larger seasonal periods. This usually gives a good balance between overfitting the seasonality and allowing it to slowly change over time. But, as with any automated procedure, the default settings will need adjusting for some time series. In the example shown in Figure [3.7](https://otexts.com/fpp3/components.html#fig:emplstl), the default trend window setting produces a trend-cycle component that is too rigid. As a result, signal from the 2008 global financial crisis has leaked into the remainder component, as can be seen in the bottom panel of Figure [3.7](https://otexts.com/fpp3/components.html#fig:emplstl). Selecting a shorter trend window as in Figure [3.18](https://otexts.com/fpp3/stl.html#fig:empl-stl2) improves this.
### Bibliography
Bandara, K., Hyndman, R. J., & Bergmeir, C. (2025). MSTL: A seasonal-trend decomposition algorithm for time series with multiple seasonal patterns. *International J Operational Research*, *52*(1).
Cleveland, R. B., Cleveland, W. S., McRae, J. E., & Terpenning, I. J. (1990). STL: A seasonal-trend decomposition procedure based on loess. *Journal of Official Statistics*, *6*(1), 333.
## 3.7 Exercises
1. Consider the GDP information in `global_economy`. Plot the GDP per capita for each country over time. Which country has the highest GDP per capita? How has this changed over time?
2. For each of the following series, make a graph of the data. If transforming seems appropriate, do so and describe the effect.
* United States GDP from `global_economy`.
* Slaughter of Victorian “Bulls, bullocks and steers” in `aus_livestock`.
* Victorian Electricity Demand from `vic_elec`.
* Gas production from `aus_production`.
3. Why is a Box-Cox transformation unhelpful for the `canadian_gas` data?
4. What Box-Cox transformation would you select for your retail data (from Exercise 7 in Section [2.10](https://otexts.com/fpp3/graphics-exercises.html#graphics-exercises))?
5. For the following series, find an appropriate Box-Cox transformation in order to stabilise the variance. Tobacco from `aus_production`, Economy class passengers between Melbourne and Sydney from `ansett`, and Pedestrian counts at Southern Cross Station from `pedestrian`.
6. Show that a \(3\times5\) MA is equivalent to a 7-term weighted moving average with weights of 0.067, 0.133, 0.200, 0.200, 0.200, 0.133, and 0.067.
7. Consider the last five years of the Gas data from `aus_production`.
```
gas <- tail(aus_production, 5*4) |> select(Gas)
```
1. Plot the time series. Can you identify seasonal fluctuations and/or a trend-cycle?
2. Use `classical_decomposition` with `type=multiplicative` to calculate the trend-cycle and seasonal indices.
3. Do the results support the graphical interpretation from part a?
4. Compute and plot the seasonally adjusted data.
5. Change one observation to be an outlier (e.g., add 300 to one observation), and recompute the seasonally adjusted data. What is the effect of the outlier?
6. Does it make any difference if the outlier is near the end rather than in the middle of the time series?
8. Recall your retail time series data (from Exercise 7 in Section [2.10](https://otexts.com/fpp3/graphics-exercises.html#graphics-exercises)).
Decompose the series using X-11. Does it reveal any outliers, or unusual features that you had not noticed previously?
9. Figures [3.19](https://otexts.com/fpp3/decomposition-exercises.html#fig:labour) and [3.20](https://otexts.com/fpp3/decomposition-exercises.html#fig:labour2) show the result of decomposing the number of persons in the civilian labour force in Australia each month from February 1978 to August 1995.
![Decomposition of the number of persons in the civilian labour force in Australia each month from February 1978 to August 1995.](https://otexts.com/fpp3/fpp_files/figure-html/labour-1.png)
Figure 3.19: Decomposition of the number of persons in the civilian labour force in Australia each month from February 1978 to August 1995.
![Seasonal component from the decomposition shown in the previous figure.](https://otexts.com/fpp3/fpp_files/figure-html/labour2-1.png)
Figure 3.20: Seasonal component from the decomposition shown in the previous figure.
1. Write about 35 sentences describing the results of the decomposition. Pay particular attention to the scales of the graphs in making your interpretation.
2. Is the recession of 1991/1992 visible in the estimated components?
10. This exercise uses the `canadian_gas` data (monthly Canadian gas production in billions of cubic metres, January 1960 February 2005).
1. Plot the data using `autoplot()`, `gg_subseries()` and `gg_season()` to look at the effect of the changing seasonality over time.[3](#fn3)
2. Do an STL decomposition of the data. You will need to choose a seasonal window to allow for the changing shape of the seasonal component.
3. How does the seasonal shape change over time? [Hint: Try plotting the seasonal component using `gg_season()`.]
4. Can you produce a plausible seasonally adjusted series?
5. Compare the results with those obtained using SEATS and X-11. How are they different?
---
3. The evolving seasonal pattern is possibly due to changes in the regulation of gas prices — thanks to Lewis Kirvan for pointing this out.[↩︎](https://otexts.com/fpp3/decomposition-exercises.html#fnref3)
## 3.8 Further reading
* A detailed modern discussion of the SEATS and X-11 methods is provided by Dagum & Bianconcini ([2016](#ref-Dagum2016)).
* R. B. Cleveland et al. ([1990](#ref-Cleveland1990)) introduced STL, and still provides the best description of the algorithm.
### Bibliography
Cleveland, R. B., Cleveland, W. S., McRae, J. E., & Terpenning, I. J. (1990). STL: A seasonal-trend decomposition procedure based on loess. *Journal of Official Statistics*, *6*(1), 333.
Dagum, E. B., & Bianconcini, S. (2016). *Seasonal adjustment methods and real time trend-cycle estimation*. Springer.
@@ -0,0 +1,355 @@
Source: https://otexts.com/fpp3/features.html (chapter features, 8 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 04-time-series-features
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 4 Time series features
The `feasts` package includes functions for Feature Extraction And Statistics from Time Series (hence the name). We have already seen some time series features. For example, the autocorrelations discussed in Section [2.8](https://otexts.com/fpp3/acf.html#acf) can be considered features of a time series — they are numerical summaries computed from the series. Another feature we saw in the last chapter was the Guerrero estimate of the Box-Cox transformation parameter — again, this is a number computed from a time series.
We can compute many different features on many different time series, and use them to explore the properties of the series. In this chapter we will look at some features that have been found useful in time series exploration, and how they can be used to uncover interesting information about your data. We will use Australian quarterly tourism as a running example (previously discussed in Section [2.5](https://otexts.com/fpp3/subseries.html#subseries)).
## 4.1 Some simple statistics
Any numerical summary computed from a time series is a feature of that time series — the mean, minimum or maximum, for example. These can be computed using the `features()` function. For example, lets compute the means of all the series in the Australian tourism data.
```
tourism |>
features(Trips, list(mean = mean)) |>
arrange(mean)
#> # A tibble: 304 × 4
#> Region State Purpose mean
#> <chr> <chr> <chr> <dbl>
#> 1 Kangaroo Island South Australia Other 0.340
#> 2 MacDonnell Northern Territory Other 0.449
#> 3 Wilderness West Tasmania Other 0.478
#> 4 Barkly Northern Territory Other 0.632
#> 5 Clare Valley South Australia Other 0.898
#> 6 Barossa South Australia Other 1.02
#> 7 Kakadu Arnhem Northern Territory Other 1.04
#> 8 Lasseter Northern Territory Other 1.14
#> 9 Wimmera Victoria Other 1.15
#> 10 MacDonnell Northern Territory Visiting 1.18
#> # 294 more rows
```
Here we see that the series with least average number of visits was “Other” visits to Kangaroo Island in South Australia.
Rather than compute one feature at a time, it is convenient to compute many features at once. A common short summary of a data set is to compute five summary statistics: the minimum, first quartile, median, third quartile and maximum. These divide the data into four equal-size sections, each containing 25% of the data. The `quantile()` function can be used to compute them.
```
tourism |> features(Trips, quantile)
#> # A tibble: 304 × 8
#> Region State Purpose `0%` `25%` `50%` `75%` `100%`
#> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Adelaide South Australia Busine… 68.7 134. 153. 177. 242.
#> 2 Adelaide South Australia Holiday 108. 135. 154. 172. 224.
#> 3 Adelaide South Australia Other 25.9 43.9 53.8 62.5 107.
#> 4 Adelaide South Australia Visiti… 137. 179. 206. 229. 270.
#> 5 Adelaide Hills South Australia Busine… 0 0 1.26 3.92 28.6
#> 6 Adelaide Hills South Australia Holiday 0 5.77 8.52 14.1 35.8
#> 7 Adelaide Hills South Australia Other 0 0 0.908 2.09 8.95
#> 8 Adelaide Hills South Australia Visiti… 0.778 8.91 12.2 16.8 81.1
#> 9 Alice Springs Northern Terri… Busine… 1.01 9.13 13.3 18.5 34.1
#> 10 Alice Springs Northern Terri… Holiday 2.81 16.9 31.5 44.8 76.5
#> # 294 more rows
```
Here the minimum is labelled `0%` and the maximum is labelled `100%`.
## 4.2 ACF features
Autocorrelations were discussed in Section [2.8](https://otexts.com/fpp3/acf.html#acf). All the autocorrelations of a series can be considered features of that series. We can also summarise the autocorrelations to produce new features; for example, the sum of the first ten squared autocorrelation coefficients is a useful summary of how much autocorrelation there is in a series, regardless of lag.
We can also compute autocorrelations of the changes in the series between periods. That is, we “difference” the data and create a new time series consisting of the differences between consecutive observations. Then we can compute the autocorrelations of this new differenced series. Occasionally it is useful to apply the same differencing operation again, so we compute the differences of the differences. The autocorrelations of this double differenced series may provide useful information.
Another related approach is to compute seasonal differences of a series. If we had monthly data, for example, we would compute the difference between consecutive Januaries, consecutive Februaries, and so on. This enables us to look at how the series is changing between years, rather than between months. Again, the autocorrelations of the seasonally differenced series may provide useful information.
We discuss differencing of time series in more detail in Section [9.1](https://otexts.com/fpp3/stationarity.html#stationarity).
The `feat_acf()` function computes a selection of the autocorrelations discussed here. It will return six or seven features:
* the first autocorrelation coefficient from the original data;
* the sum of squares of the first ten autocorrelation coefficients from the original data;
* the first autocorrelation coefficient from the differenced data;
* the sum of squares of the first ten autocorrelation coefficients from the differenced data;
* the first autocorrelation coefficient from the twice differenced data;
* the sum of squares of the first ten autocorrelation coefficients from the twice differenced data;
* For seasonal data, the autocorrelation coefficient at the first seasonal lag is also returned.
When applied to the Australian tourism data, we get the following output.
```
tourism |> features(Trips, feat_acf)
#> # A tibble: 304 × 10
#> Region State Purpose acf1 acf10 diff1_acf1 diff1_acf10 diff2_acf1
#> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Adelaide Sout… Busine… 0.0333 0.131 -0.520 0.463 -0.676
#> 2 Adelaide Sout… Holiday 0.0456 0.372 -0.343 0.614 -0.487
#> 3 Adelaide Sout… Other 0.517 1.15 -0.409 0.383 -0.675
#> 4 Adelaide Sout… Visiti… 0.0684 0.294 -0.394 0.452 -0.518
#> 5 Adelaide Hi… Sout… Busine… 0.0709 0.134 -0.580 0.415 -0.750
#> 6 Adelaide Hi… Sout… Holiday 0.131 0.313 -0.536 0.500 -0.716
#> 7 Adelaide Hi… Sout… Other 0.261 0.330 -0.253 0.317 -0.457
#> 8 Adelaide Hi… Sout… Visiti… 0.139 0.117 -0.472 0.239 -0.626
#> 9 Alice Sprin… Nort… Busine… 0.217 0.367 -0.500 0.381 -0.658
#> 10 Alice Sprin… Nort… Holiday -0.00660 2.11 -0.153 2.11 -0.274
#> # 294 more rows
#> # 2 more variables: diff2_acf10 <dbl>, season_acf1 <dbl>
```
## 4.3 STL Features
The STL decomposition discussed in Chapter [3](https://otexts.com/fpp3/decomposition.html#decomposition) is the basis for several more features.
A time series decomposition can be used to measure the strength of trend and seasonality in a time series. Recall that the decomposition is written as
\[
y_t = T_t + S_{t} + R_t,
\]
where \(T_t\) is the smoothed trend component, \(S_{t}\) is the seasonal component and \(R_t\) is a remainder component. For strongly trended data, the seasonally adjusted data should have much more variation than the remainder component. Therefore Var\((R_t)\)/Var\((T_t+R_t)\) should be relatively small. But for data with little or no trend, the two variances should be approximately the same. So we define the strength of trend as:
\[
F_T = \max\left(0, 1 - \frac{\text{Var}(R_t)}{\text{Var}(T_t+R_t)}\right).
\]
This will give a measure of the strength of the trend between 0 and 1. Because the variance of the remainder might occasionally be even larger than the variance of the seasonally adjusted data, we set the minimal possible value of \(F_T\) equal to zero.
The strength of seasonality is defined similarly, but with respect to the detrended data rather than the seasonally adjusted data:
\[
F_S = \max\left(0, 1 - \frac{\text{Var}(R_t)}{\text{Var}(S_{t}+R_t)}\right).
\]
A series with seasonal strength \(F_S\) close to 0 exhibits almost no seasonality, while a series with strong seasonality will have \(F_S\) close to 1 because Var\((R_t)\) will be much smaller than Var\((S_{t}+R_t)\).
These measures can be useful, for example, when you have a large collection of time series, and you need to find the series with the most trend or the most seasonality. These and other STL-based features are computed using the `feat_stl()` function.
```
tourism |>
features(Trips, feat_stl)
#> # A tibble: 304 × 12
#> Region State Purpose trend_strength seasonal_strength_year
#> <chr> <chr> <chr> <dbl> <dbl>
#> 1 Adelaide South Austral… Busine… 0.464 0.407
#> 2 Adelaide South Austral… Holiday 0.554 0.619
#> 3 Adelaide South Austral… Other 0.746 0.202
#> 4 Adelaide South Austral… Visiti… 0.435 0.452
#> 5 Adelaide Hills South Austral… Busine… 0.464 0.179
#> 6 Adelaide Hills South Austral… Holiday 0.528 0.296
#> 7 Adelaide Hills South Austral… Other 0.593 0.404
#> 8 Adelaide Hills South Austral… Visiti… 0.488 0.254
#> 9 Alice Springs Northern Terr… Busine… 0.534 0.251
#> 10 Alice Springs Northern Terr… Holiday 0.381 0.832
#> # 294 more rows
#> # 7 more variables: seasonal_peak_year <dbl>, seasonal_trough_year <dbl>,
#> # spikiness <dbl>, linearity <dbl>, curvature <dbl>, stl_e_acf1 <dbl>,
#> # stl_e_acf10 <dbl>
```
We can then use these features in plots to identify what type of series are heavily trended and what are most seasonal.
```
tourism |>
features(Trips, feat_stl) |>
ggplot(aes(x = trend_strength, y = seasonal_strength_year,
col = Purpose)) +
geom_point() +
facet_wrap(vars(State))
```
![Seasonal strength vs trend strength for all tourism series.](https://otexts.com/fpp3/fpp_files/figure-html/featuresplot-1.png)
Figure 4.1: Seasonal strength vs trend strength for all tourism series.
Clearly, holiday series are most seasonal which is unsurprising. The strongest trends tend to be in Western Australia and Victoria. The most seasonal series can also be easily identified and plotted.
```
tourism |>
features(Trips, feat_stl) |>
filter(
seasonal_strength_year == max(seasonal_strength_year)
) |>
left_join(tourism, by = c("State", "Region", "Purpose"), multiple = "all") |>
ggplot(aes(x = Quarter, y = Trips)) +
geom_line() +
facet_grid(vars(State, Region, Purpose))
```
![The most seasonal series in the Australian tourism data.](https://otexts.com/fpp3/fpp_files/figure-html/extreme-1.png)
Figure 4.2: The most seasonal series in the Australian tourism data.
This shows holiday trips to the most popular ski region of Australia.
The `feat_stl()` function returns several more features other than those discussed above.
* `seasonal_peak_year` indicates the timing of the peaks — which month or quarter contains the largest seasonal component. This tells us something about the nature of the seasonality. In the Australian tourism data, if Quarter 3 is the peak seasonal period, then people are travelling to the region in winter, whereas a peak in Quarter 1 suggests that the region is more popular in summer.
* `seasonal_trough_year` indicates the timing of the troughs — which month or quarter contains the smallest seasonal component.
* `spikiness` measures the prevalence of spikes in the remainder component \(R_t\) of the STL decomposition. It is the variance of the leave-one-out variances of \(R_t\).
* `linearity` measures the linearity of the trend component of the STL decomposition. It is based on the coefficient of a linear regression applied to the trend component.
* `curvature` measures the curvature of the trend component of the STL decomposition. It is based on the coefficient from an orthogonal quadratic regression applied to the trend component.
* `stl_e_acf1` is the first autocorrelation coefficient of the remainder series.
* `stl_e_acf10` is the sum of squares of the first ten autocorrelation coefficients of the remainder series.
## 4.4 Other features
Many more features are possible, and the `feasts` package computes only a few dozen features that have proven useful in time series analysis. It is also easy to add your own features by writing an R function that takes a univariate time series input and returns a numerical vector containing the feature values.
The remaining features in the `feasts` package, not previously discussed, are listed here for reference. The details of some of them are discussed later in the book.
* `coef_hurst` will calculate the Hurst coefficient of a time series which is a measure of “long memory”. A series with long memory will have significant autocorrelations for many lags.
* `feat_spectral` will compute the (Shannon) spectral entropy of a time series, which is a measure of how easy the series is to forecast. A series which has strong trend and seasonality (and so is easy to forecast) will have entropy close to 0. A series that is very noisy (and so is difficult to forecast) will have entropy close to 1.
* `box_pierce` gives the Box-Pierce statistic for testing if a time series is white noise, and the corresponding p-value. This test is discussed in Section [5.4](https://otexts.com/fpp3/diagnostics.html#diagnostics).
* `ljung_box` gives the Ljung-Box statistic for testing if a time series is white noise, and the corresponding p-value. This test is discussed in Section [5.4](https://otexts.com/fpp3/diagnostics.html#diagnostics).
* The \(k\)th partial autocorrelation measures the relationship between observations \(k\) periods apart after removing the effects of observations between them. So the first partial autocorrelation (\(k=1\)) is identical to the first autocorrelation, because there is nothing between consecutive observations to remove. Partial autocorrelations are discussed in Section [9.5](https://otexts.com/fpp3/non-seasonal-arima.html#non-seasonal-arima). The `feat_pacf` function contains several features involving partial autocorrelations including the sum of squares of the first five partial autocorrelations for the original series, the first-differenced series and the second-differenced series. For seasonal data, it also includes the partial autocorrelation at the first seasonal lag.
* `unitroot_kpss` gives the Kwiatkowski-Phillips-Schmidt-Shin (KPSS) statistic for testing if a series is stationary, and the corresponding p-value. This test is discussed in Section [9.1](https://otexts.com/fpp3/stationarity.html#stationarity).
* `unitroot_pp` gives the Phillips-Perron statistic for testing if a series is non-stationary, and the corresponding p-value.
* `unitroot_ndiffs` gives the number of differences required to lead to a stationary series based on the KPSS test. This is discussed in Section [9.1](https://otexts.com/fpp3/stationarity.html#stationarity)
* `unitroot_nsdiffs` gives the number of seasonal differences required to make a series stationary. This is discussed in Section [9.1](https://otexts.com/fpp3/stationarity.html#stationarity).
* `var_tiled_mean` gives the variances of the “tiled means” (i.e., the means of consecutive non-overlapping blocks of observations). The default tile length is either 10 (for non-seasonal data) or the length of the seasonal period. This is sometimes called the “stability” feature.
* `var_tiled_var` gives the variances of the “tiled variances” (i.e., the variances of consecutive non-overlapping blocks of observations). This is sometimes called the “lumpiness” feature.
* `shift_level_max` finds the largest mean shift between two consecutive sliding windows of the time series. This is useful for finding sudden jumps or drops in a time series.
* `shift_level_index` gives the index at which the largest mean shift occurs.
* `shift_var_max` finds the largest variance shift between two consecutive sliding windows of the time series. This is useful for finding sudden changes in the volatility of a time series.
* `shift_var_index` gives the index at which the largest variance shift occurs.
* `shift_kl_max` finds the largest distributional shift (based on the Kulback-Leibler divergence) between two consecutive sliding windows of the time series. This is useful for finding sudden changes in the distribution of a time series.
* `shift_kl_index` gives the index at which the largest KL shift occurs.
* `n_crossing_points` computes the number of times a time series crosses the median.
* `longest_flat_spot` computes the number of sections of the data where the series is relatively unchanging.
* `stat_arch_lm` returns the statistic based on the Lagrange Multiplier (LM) test of Engle (1982) for autoregressive conditional heteroscedasticity (ARCH).
* `guerrero` computes the optimal \(\lambda\) value for a Box-Cox transformation using the Guerrero method (discussed in Section [3.1](https://otexts.com/fpp3/transformations.html#transformations)).
## 4.5 Exploring Australian tourism data
All of the features included in the `feasts` package can be computed in one line like this.
```
tourism_features <- tourism |>
features(Trips, feature_set(pkgs = "feasts"))
tourism_features
#> # A tibble: 304 × 51
#> Region State Purpose trend_strength seasonal_strength_year
#> <chr> <chr> <chr> <dbl> <dbl>
#> 1 Adelaide South Austral… Busine… 0.464 0.407
#> 2 Adelaide South Austral… Holiday 0.554 0.619
#> 3 Adelaide South Austral… Other 0.746 0.202
#> 4 Adelaide South Austral… Visiti… 0.435 0.452
#> 5 Adelaide Hills South Austral… Busine… 0.464 0.179
#> 6 Adelaide Hills South Austral… Holiday 0.528 0.296
#> 7 Adelaide Hills South Austral… Other 0.593 0.404
#> 8 Adelaide Hills South Austral… Visiti… 0.488 0.254
#> 9 Alice Springs Northern Terr… Busine… 0.534 0.251
#> 10 Alice Springs Northern Terr… Holiday 0.381 0.832
#> # 294 more rows
#> # 46 more variables: seasonal_peak_year <dbl>, seasonal_trough_year <dbl>,
#> # spikiness <dbl>, linearity <dbl>, curvature <dbl>, stl_e_acf1 <dbl>,
#> # stl_e_acf10 <dbl>, acf1 <dbl>, acf10 <dbl>, diff1_acf1 <dbl>,
#> # diff1_acf10 <dbl>, diff2_acf1 <dbl>, diff2_acf10 <dbl>,
#> # season_acf1 <dbl>, pacf5 <dbl>, diff1_pacf5 <dbl>, diff2_pacf5 <dbl>,
#> # season_pacf <dbl>, zero_run_mean <dbl>, nonzero_squared_cv <dbl>, …
```
Provided the `urca` and `fracdiff` packages are installed, this gives 48 features for every combination of the three key variables (`Region`, `State` and `Purpose`). We can treat this tibble like any data set and analyse it to find interesting observations or groups of observations.
Weve already seen how we can plot one feature against another (Section [4.3](https://otexts.com/fpp3/stlfeatures.html#stlfeatures)). We can also do pairwise plots of groups of features. In Figure [4.3](https://otexts.com/fpp3/exploring-australian-tourism-data.html#fig:seasonalfeatures), for example, we show all features that involve seasonality, along with the `Purpose` variable.
```
library(glue)
tourism_features |>
select_at(vars(contains("season"), Purpose)) |>
mutate(
seasonal_peak_year = seasonal_peak_year +
4*(seasonal_peak_year==0),
seasonal_trough_year = seasonal_trough_year +
4*(seasonal_trough_year==0),
seasonal_peak_year = glue("Q{seasonal_peak_year}"),
seasonal_trough_year = glue("Q{seasonal_trough_year}"),
) |>
GGally::ggpairs(mapping = aes(colour = Purpose))
```
![Pairwise plots of all the seasonal features for the Australian tourism data](https://otexts.com/fpp3/fpp_files/figure-html/seasonalfeatures-1.png)
Figure 4.3: Pairwise plots of all the seasonal features for the Australian tourism data
Here, the `Purpose` variable is mapped to colour. There is a lot of information in this figure, and we will highlight just a few things we can learn.
* The three numerical measures related to seasonality (`seasonal_strength_year`, `season_acf1` and `season_pacf`) are all positively correlated.
* The bottom left panel and the top right panel both show that the most strongly seasonal series are related to holidays (as we saw previously).
* The bar plots in the bottom row of the `seasonal_peak_year` and `seasonal_trough_year` columns show that seasonal peaks in Business travel occur most often in Quarter 3, and least often in Quarter 1.
It is difficult to explore more than a handful of variables in this way. A useful way to handle many more variables is to use a dimension reduction technique such as principal components. This gives linear combinations of variables that explain the most variation in the original data. We can compute the principal components of the tourism features as follows.
```
library(broom)
pcs <- tourism_features |>
select(-State, -Region, -Purpose) |>
prcomp(scale = TRUE) |>
augment(tourism_features)
pcs |>
ggplot(aes(x = .fittedPC1, y = .fittedPC2, col = Purpose)) +
geom_point() +
theme(aspect.ratio = 1)
```
![A plot of the first two principal components, calculated from the 48 features of the Australian quarterly tourism data.](https://otexts.com/fpp3/fpp_files/figure-html/pca-1.png)
Figure 4.4: A plot of the first two principal components, calculated from the 48 features of the Australian quarterly tourism data.
Each point on Figure [4.4](https://otexts.com/fpp3/exploring-australian-tourism-data.html#fig:pca) represents one series and its location on the plot is based on all 48 features. The first principal component (`.fittedPC1`) is the linear combination of the features which explains the most variation in the data. The second principal component (`.fittedPC2`) is the linear combination which explains the next most variation in the data, while being uncorrelated with the first principal component. For more information about principal component dimension reduction, see Izenman ([2008](#ref-izenman2008)).
Figure [4.4](https://otexts.com/fpp3/exploring-australian-tourism-data.html#fig:pca) reveals a few things about the tourism data. First, the holiday series behave quite differently from the rest of the series. Almost all of the holiday series appear in the top half of the plot, while almost all of the remaining series appear in the bottom half of the plot. Clearly, the second principal component is distinguishing between holidays and other types of travel.
The plot also allows us to identify anomalous time series — series which have unusual feature combinations. These appear as points that are separate from the majority of series in Figure [4.4](https://otexts.com/fpp3/exploring-australian-tourism-data.html#fig:pca). There are four that stand out, and we can identify which series they correspond to as follows.
```
outliers <- pcs |>
filter(.fittedPC1 > 10) |>
select(Region, State, Purpose, .fittedPC1, .fittedPC2)
outliers
#> # A tibble: 4 × 5
#> Region State Purpose .fittedPC1 .fittedPC2
#> <chr> <chr> <chr> <dbl> <dbl>
#> 1 Australia's North West Western Australia Business 13.4 -11.3
#> 2 Australia's South West Western Australia Holiday 10.9 0.880
#> 3 Melbourne Victoria Holiday 12.3 -10.4
#> 4 South Coast New South Wales Holiday 11.9 9.42
outliers |>
left_join(tourism, by = c("State", "Region", "Purpose"), multiple = "all") |>
mutate(Series = glue("{State}", "{Region}", "{Purpose}", .sep = "\n\n")) |>
ggplot(aes(x = Quarter, y = Trips)) +
geom_line() +
facet_grid(Series ~ ., scales = "free") +
labs(title = "Outlying time series in PC space")
```
![Four anomalous time series from the Australian tourism data.](https://otexts.com/fpp3/fpp_files/figure-html/pcaoutliers-1.png)
Figure 4.5: Four anomalous time series from the Australian tourism data.
We can speculate why these series are identified as unusual.
* Holiday visits to the south coast of NSW is highly seasonal but has almost no trend, whereas most holiday destinations in Australia show some trend over time.
* Melbourne is an unusual holiday destination because it has almost no seasonality, whereas most holiday destinations in Australia have highly seasonal tourism.
* The north western corner of Western Australia is unusual because it shows an increase in business tourism in the last few years of data, but little or no seasonality.
* The south western corner of Western Australia is unusual because it shows both an increase in holiday tourism in the last few years of data and a high level of seasonality.
### Bibliography
Izenman, A. J. (2008). *Modern multivariate statistical techniques: Regression, classification and manifold learning*. Springer.
## 4.6 Exercises
1. Write a function to compute the mean and standard deviation of a time series, and apply it to the `PBS` data. Plot the series with the highest mean, and the series with the lowest standard deviation.
2. Use `GGally::ggpairs()` to look at the relationships between the STL-based features for the holiday series in the `tourism` data. Change `seasonal_peak_year` and `seasonal_trough_year` to factors, as shown in Figure [4.3](https://otexts.com/fpp3/exploring-australian-tourism-data.html#fig:seasonalfeatures). Which is the peak quarter for holidays in each state?
3. Use a feature-based approach to look for outlying series in the `PBS` data. What is unusual about the series you identify as “outliers”.
## 4.7 Further reading
* The idea of using STL for features originated with Wang et al. ([2006](#ref-WangSH06)).
* The features provided by the `feasts` package were motivated by their use in Hyndman et al. ([2015](#ref-cikm2015)) and Kang et al. ([2017](#ref-m3pca)).
* The exploration of a set of time series using principal components on a large collection of features was proposed by Kang et al. ([2017](#ref-m3pca)).
### Bibliography
Hyndman, R. J., Wang, E., & Laptev, N. (2015). Large-scale unusual time series detection. *Proceedings of the IEEE International Conference on Data Mining*, 16161619.
Kang, Y., Hyndman, R. J., & Smith-Miles, K. (2017). Visualising forecasting algorithm performance using time series instance spaces. *International Journal of Forecasting*, *33*(2), 345358.
Wang, X., Smith, K. A., & Hyndman, R. J. (2006). Characteristic-based clustering for time series data. *Data Mining and Knowledge Discovery*, *13*(3), 335364.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,346 @@
Source: https://otexts.com/fpp3/judgmental.html (chapter judgmental, 9 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 06-judgmental-forecasts
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 6 Judgmental forecasts
Forecasting using judgment is common in practice. In many cases, judgmental forecasting is the only option, such as when there is a complete lack of historical data, or when a new product is being launched, or when a new competitor enters the market, or during completely new and unique market conditions. For example, in December 2012, the Australian government was the first in the world to pass legislation that banned the use of company logos on cigarette packets, and required all cigarette packets to be a dark green colour. Judgment must be applied in order to forecast the effect of such a policy, as there are no historical precedents.
There are also situations where the data are incomplete, or only become available after some delay. For example, central banks include judgment when forecasting the current level of economic activity, a procedure known as nowcasting, as GDP is only available on a quarterly basis.
Research in this area[6](#fn6) has shown that the accuracy of judgmental forecasting improves when the forecaster has (i) important domain knowledge, and (ii) more timely, up-to-date information. A judgmental approach can be quick to adjust to such changes, information or events.
Over the years, the acceptance of judgmental forecasting as a science has increased, as has the recognition of its need. More importantly, the quality of judgmental forecasts has also improved, as a direct result of recognising that improvements in judgmental forecasting can be achieved by implementing well-structured and systematic approaches. It is important to recognise that judgmental forecasting is subjective and comes with limitations. However, implementing systematic and well-structured approaches can confine these limitations and markedly improve forecast accuracy.
There are three general settings in which judgmental forecasting is used: (i) there are no available data, so that statistical methods are not applicable and judgmental forecasting is the only feasible approach; (ii) data are available, statistical forecasts are generated, and these are then adjusted using judgment; and (iii) data are available and statistical and judgmental forecasts are generated independently and then combined. We should clarify that when data are available, applying statistical methods (such as those discussed in other chapters of this book), is preferable and should always be used as a starting point. Statistical forecasts are generally superior to generating forecasts using only judgment. For the majority of the chapter, we focus on the first setting where no data are available, and in the last section we discuss the judgmental adjustment of statistical forecasts. We discuss combining forecasts in Section [13.4](https://otexts.com/fpp3/combinations.html#combinations).
### Bibliography
Lawrence, M., Goodwin, P., OConnor, M., & Önkal, D. (2006). Judgmental forecasting: A review of progress over the last 25 years. *International Journal of Forecasting*, *22*(3), 493518.
---
6. Lawrence et al. ([2006](#ref-Lawrence2006))[↩︎](https://otexts.com/fpp3/judgmental.html#fnref6)
## 6.1 Beware of limitations
Judgmental forecasts are subjective, and therefore do not come free of bias or limitations.
Judgmental forecasts can be inconsistent. Unlike statistical forecasts, which can be generated by the same mathematical formulas every time, judgmental forecasts depend heavily on human cognition, and are vulnerable to its limitations. For example, a limited memory may render recent events more important than they actually are and may ignore momentous events from the more distant past; or a limited attention span may result in important information being missed; or a misunderstanding of causal relationships may lead to erroneous inferences. Furthermore, human judgment can vary due to the effect of psychological factors. One can imagine a manager who is in a positive frame of mind one day, generating forecasts that may tend to be somewhat optimistic, and in a negative frame of mind another day, generating somewhat less optimistic forecasts.
Judgment can be clouded by personal or political agendas, where targets and forecasts (as defined in Chapter [1](https://otexts.com/fpp3/intro.html#intro)) are not segregated. For example, if a sales manager knows that the forecasts she generates will be used to set sales expectations (targets), she may tend to set these low in order to show a good performance (i.e., exceed the expected targets). Even in cases where targets and forecasts are well segregated, judgment may be plagued by optimism or wishful thinking. For example, it would be highly unlikely that a team working towards launching a new product would forecast its failure. As we will discuss later, this optimism can be accentuated in a group meeting setting. “Beware of the enthusiasm of your marketing and sales colleagues”[7](#fn7).
Another undesirable property which is commonly seen in judgmental forecasting is the effect of anchoring. In this case, the subsequent forecasts tend to converge or be close to an initial familiar reference point. For example, it is common to take the last observed value as a reference point. The forecaster is influenced unduly by prior information, and therefore gives this more weight in the forecasting process. Anchoring may lead to conservatism and undervaluing new and more current information, and thereby create a systematic bias.
### Bibliography
Fildes, R., & Goodwin, P. (2007b). Good and bad judgment in forecasting: Lessons from four companies. *Foresight: The International Journal of Applied Forecasting*, *8*, 510.
---
7. Fildes & Goodwin ([2007b](#ref-Fildes2007a))[↩︎](https://otexts.com/fpp3/judgmental-limitations.html#fnref7)
## 6.2 Key principles
Using a systematic and well structured approach in judgmental forecasting helps to reduce the adverse effects of the limitations of judgmental forecasting, some of which we listed in the previous section. Whether this approach involves one individual or many, the following principles should be followed.
### Set the forecasting task clearly and concisely
Care is needed when setting the forecasting challenges and expressing the forecasting tasks. It is important that everyone be clear about what the task is. All definitions should be clear and comprehensive, avoiding ambiguous and vague expressions. Also, it is important to avoid incorporating emotive terms and irrelevant information that may distract the forecaster. In the Delphi method that follows (see Section [6.3](https://otexts.com/fpp3/delphimethod.html#delphimethod)), it may sometimes be useful to conduct a preliminary round of information gathering before setting the forecasting task.
### Implement a systematic approach
Forecast accuracy and consistency can be improved by using a systematic approach to judgmental forecasting involving checklists of categories of information which are relevant to the forecasting task. For example, it is helpful to identify what information is important and how this information is to be weighted. When forecasting the demand for a new product, what factors should we account for and how should we account for them? Should it be the price, the quality and/or quantity of the competition, the economic environment at the time, the target population of the product? It is worthwhile to devote significant effort and resources to put together decision rules that will lead to the best possible systematic approach.
### Document and justify
Formalising and documenting the decision rules and assumptions implemented in the systematic approach can promote consistency, as the same rules can be implemented repeatedly. Also, requesting a forecaster to document and justify their forecasts leads to accountability, which can lead to reduced bias. Furthermore, formal documentation aids significantly in the systematic evaluation process that is suggested next.
### Systematically evaluate forecasts
Systematically monitoring the forecasting process can identify unforeseen irregularities. In particular, keep records of forecasts and use them to obtain feedback when the corresponding observations become available. Although you may do your best as a forecaster, the environment you operate in is dynamic. Changes occur, and you need to monitor these in order to evaluate the decision rules and assumptions. Feedback and evaluation help forecasters learn and improve their forecast accuracy.
### Segregate forecasters and users
Forecast accuracy may be impeded if the forecasting task is carried out by users of the forecasts, such as those responsible for implementing plans of action about which the forecast is concerned. We should clarify again here (as in Section [1.2](https://otexts.com/fpp3/planning.html#planning)), that forecasting is about predicting the future as accurately as possible, given all of the information available, including historical data and knowledge of any future events that may impact the forecasts. Forecasters and users should be clearly segregated. A classic case is that of a new product being launched. The forecast should be a reasonable estimate of the sales volume of a new product, which may differ considerably from what management expects or hopes the sales will be in order to meet company financial objectives. In this case, a forecaster may be delivering a reality check to the user.
It is important that forecasters communicate forecasts to potential users thoroughly. As we will see in Section [6.7](https://otexts.com/fpp3/judgmental-adjustments.html#judgmental-adjustments), users may feel distant and disconnected from forecasts, and may not have full confidence in them. Explaining and clarifying the process and justifying the basic assumptions that led to the forecasts will provide some assurance to users.
The way in which forecasts may then be used and implemented will clearly depend on managerial decision making. For example, management may decide to adjust a forecast upwards (be over-optimistic), as the forecast may be used to guide purchasing and stock keeping levels. Such a decision may be taken after a cost-benefit analysis reveals that the cost of holding excess stock is much lower than that of lost sales. This type of adjustment should be part of setting goals or planning supply, rather than part of the forecasting process. In contrast, if forecasts are used as targets, they may be set low so that they can be exceeded more easily. Again, setting targets is different from producing forecasts, and the two should not be confused.
The example that follows comes from our experience in industry. It exemplifies two contrasting styles of judgmental forecasting — one that adheres to the principles we have just presented and one that does not.
### Example: Pharmaceutical Benefits Scheme (PBS)
The Australian government subsidises the cost of a wide range of prescription medicines as part of the PBS. Each subsidised medicine falls into one of four categories: concession copayments, concession safety net, general copayments, and general safety net. Each person with a concession card makes a concession copayment per PBS medicine ($5.80)[8](#fn8),
until they reach a set threshold amount labelled the concession safety net ($348). For the rest of the financial year, all PBS-listed medicines are free. Each general patient makes a general copayment per PBS medicine ($35.40) until the general safety net amount is reached ($1,363.30). For the rest of the financial year, they contribute a small amount per PBS-listed medicine ($5.80). The PBS forecasting process uses 84 groups of PBS-listed medicines, and produces forecasts of the medicine volume and the total expenditure for each group and for each of the four PBS categories, a total of 672 series. This forecasting process aids in setting the government budget allocated to the PBS, which is over $7 billion per year, or approximately 1% of GDP.
![Process for producing PBS forecasts.](https://otexts.com/fpp3/figs/PBSprocess.png)
Figure 6.1: Process for producing PBS forecasts.
Figure [6.1](https://otexts.com/fpp3/judgmental-principles.html#fig:pbsdiagram) summarises the forecasting process. Judgmental forecasts are generated for new listings of medicines and for estimating the impact of new policies. These are shown by the green items. The pink items indicate the data used which were obtained from various government departments and associated authorities. The blue items show things that are calculated from the data provided. There were judgmental adjustments to the data to take account of new listings and new policies, and there were also judgmental adjustments to the forecasts. Because of the changing size of both the concession population and the total population, forecasts are produced on a per-capita basis, and then multiplied by the forecast population to obtain forecasts of total volume and expenditure per month.
One of us (Hyndman) was asked to evaluate the forecasting process a few years ago. We found that using judgment for new listings and new policy impacts gave better forecasts than using a statistical model alone. However, we also found that the forecasting accuracy and consistency could be improved through a more structured and systematic process, especially for policy impacts.
*Forecasting new listings:* Companies who apply for their medicine to be added to the PBS are asked to submit detailed forecasts for various aspects of the medicine, such as projected patient numbers, market share of the new medicine, substitution effects, etc. The Pharmaceutical Benefits Advisory Committee provides guidelines describing a highly structured and systematic approach for generating these forecasts, and requires careful documentation for each step of the process. This structured process helps to reduce the likelihood and effects of deliberate self-serving biases. Two detailed evaluation rounds of the company forecasts are implemented by a sub-committee, one before the medicine is added to the PBS and one after it is added. Finally, comparisons of observations versus forecasts for some selected new listings are performed, 12 months and 24 months after the listings, and the results are sent back to the companies for comment.
*Policy impact forecasts:* In contrast to the highly structured process used for new listings, there were no systematic procedures for policy impact forecasts. On many occasions, forecasts of policy impacts were calculated by a small team, and were often heavily reliant on the work of one person. The forecasts were not usually subject to a formal review process. There were no guidelines for how to construct judgmental forecasts for policy impacts, and there was often a lack of adequate documentation about how these forecasts were obtained, the assumptions underlying them, etc.
Consequently, we recommended several changes:
* that guidelines for forecasting new policy impacts be developed, to encourage a more systematic and structured forecasting approach;
* that the forecast methodology be documented in each case, including all assumptions made in forming the forecasts;
* that new policy forecasts be made by at least two people from different areas of the organisation;
* that a review of forecasts be conducted one year after the implementation of each new policy by a review committee, especially for new policies that have a significant annual projected cost or saving. The review committee should include those involved in generating the forecasts, but also others.
These recommendations reflect the principles outlined in this section.
---
8. These are Australian dollar amounts published by the Australian government for 2012.[↩︎](https://otexts.com/fpp3/judgmental-principles.html#fnref8)
## 6.3 The Delphi method
The Delphi method was invented by Olaf Helmer and Norman Dalkey of the Rand Corporation in the 1950s for the purpose of addressing a specific military problem. The method relies on the key assumption that forecasts from a group are generally more accurate than those from individuals. The aim of the Delphi method is to construct consensus forecasts from a group of experts in a structured iterative manner. A facilitator is appointed in order to implement and manage the process. The Delphi method generally involves the following stages:
1. A panel of experts is assembled.
2. Forecasting tasks/challenges are set and distributed to the experts.
3. Experts return initial forecasts and justifications. These are compiled and summarised in order to provide feedback.
4. Feedback is provided to the experts, who now review their forecasts in light of the feedback. This step may be iterated until a satisfactory level of consensus is reached.
5. Final forecasts are constructed by aggregating the experts forecasts.
Each stage of the Delphi method comes with its own challenges. In what follows, we provide some suggestions and discussions about each one of these.[9](#fn9)
### Experts and anonymity
The first challenge of the facilitator is to identify a group of experts who can contribute to the forecasting task. The usual suggestion is somewhere between 5 and 20 experts with diverse expertise. Experts submit forecasts and also provide detailed qualitative justifications for these.
A key feature of the Delphi method is that the participating experts remain anonymous at all times. This means that the experts cannot be influenced by political and social pressures in their forecasts. Furthermore, all experts are given an equal say and all are held accountable for their forecasts. This avoids the situation where a group meeting is held and some members do not contribute, while others dominate. It also prevents members exerting undue influence based on seniority or personality. There have been suggestions that even something as simple as the seating arrangements in a group setting can influence the group dynamics. Furthermore, there is ample evidence that a group meeting setting promotes enthusiasm and influences individual judgment, leading to optimism and overconfidence.[10](#fn10)
A by-product of anonymity is that the experts do not need to meet as a group in a physical location. An important advantage of this is that it increases the likelihood of gathering experts with diverse skills and expertise from varying locations. Furthermore, it makes the process cost-effective by eliminating the expense and inconvenience of travel, and it makes it flexible, as the experts only have to meet a common deadline for submitting forecasts, rather than having to set a common meeting time.
### Setting the forecasting task in a Delphi
In a Delphi setting, it may be useful to conduct a preliminary round of information gathering from the experts before setting the forecasting tasks. Alternatively, as experts submit their initial forecasts and justifications, valuable information which is not shared between all experts can be identified by the facilitator when compiling the feedback.
### Feedback
Feedback to the experts should include summary statistics of the forecasts and outlines of qualitative justifications. Numerical data summaries and graphical representations can be used to summarise the experts forecasts.
As the feedback is controlled by the facilitator, there may be scope to direct attention and information from the experts to areas where it is most required. For example, the facilitator may direct the experts attention to responses that fall outside the interquartile range, and the qualitative justification for such forecasts.
### Iteration
The process of the experts submitting forecasts, receiving feedback, and reviewing their forecasts in light of the feedback, is repeated until a satisfactory level of consensus between the experts is reached. Satisfactory consensus does not mean complete convergence in the forecast value; it simply means that the variability of the responses has decreased to a satisfactory level. Usually two or three rounds are sufficient. Experts are more likely to drop out as the number of iterations increases, so too many rounds should be avoided.
### Final forecasts
The final forecasts are usually constructed by giving equal weight to all of the experts forecasts. However, the facilitator should keep in mind the possibility of extreme values which can distort the final forecast.
### Limitations and variations
Applying the Delphi method can be time consuming. In a group meeting, final forecasts can possibly be reached in hours or even minutes — something which is almost impossible to do in a Delphi setting. If it is taking a long time to reach a consensus in a Delphi setting, the panel may lose interest and cohesiveness.
In a group setting, personal interactions can lead to quicker and better clarifications of qualitative justifications. A variation of the Delphi method which is often applied is the “estimate-talk-estimate” method, where the experts can interact between iterations, although the forecast submissions can still remain anonymous. A disadvantage of this variation is the possibility of the loudest person exerting undue influence.
### The facilitator
The role of the facilitator is of the utmost importance. The facilitator is largely responsible for the design and administration of the Delphi process. The facilitator is also responsible for providing feedback to the experts and generating the final forecasts. In this role, the facilitator needs to be experienced enough to recognise areas that may need more attention, and to direct the experts attention to these. Also, as there is no face-to-face interaction between the experts, the facilitator is responsible for disseminating important information. The efficiency and effectiveness of the facilitator can dramatically increase the probability of a successful Delphi method in a judgmental forecasting setting.
### Bibliography
Buehler, R., Messervey, D., & Griffin, D. (2005). Collaborative planning and prediction: Does group discussion affect optimistic biases in time estimation? *Organizational Behavior and Human Decision Processes*, *97*(1), 4763.
Rowe, G. (2007). A guide to Delphi. *Foresight: The International Journal of Applied Forecasting*, *8*, 1116.
Rowe, G., & Wright, G. (1999). The Delphi technique as a forecasting tool: Issues and analysis. *International Journal of Forecasting*, *15*(4), 353375.
---
9. For further reading, refer to: Rowe ([2007](#ref-Rowe2007)); Rowe & Wright ([1999](#ref-RW99))[↩︎](https://otexts.com/fpp3/delphimethod.html#fnref9)
10. Buehler et al. ([2005](#ref-Buehler2005))[↩︎](https://otexts.com/fpp3/delphimethod.html#fnref10)
## 6.4 Forecasting by analogy
A useful judgmental approach which is often implemented in practice is forecasting by analogy. A common example is the pricing of a house through an appraisal process. An appraiser estimates the market value of a house by comparing it to similar properties that have sold in the area. The degree of similarity depends on the attributes considered. With house appraisals, attributes such as land size, dwelling size, numbers of bedrooms and bathrooms, and garage space are usually considered.
Even thinking and discussing analogous products or situations can generate useful (and sometimes crucial) information. We illustrate this point with the following example.[11](#fn11)
### Example: Designing a high school curriculum
A small group of academics and teachers were assigned the task of developing a curriculum for teaching judgment and decision making under uncertainty for high schools in Israel. Each group member was asked to forecast how long it would take for the curriculum to be completed. Responses ranged between 18 and 30 months. One of the group members who was an expert in curriculum design was asked to consider analogous curricula developments around the world. He concluded that 40% of analogous groups he considered never completed the task. The rest took between 7 to 10 years. The Israel project was completed in 8 years.
Obviously, forecasting by analogy comes with challenges. We should aspire to base forecasts on multiple analogies rather than a single analogy, which may create biases. However, these may be challenging to identify. Similarly, we should aspire to consider multiple attributes. Identifying or even comparing these may not always be straightforward. As always, we suggest performing these comparisons and the forecasting process using a systematic approach. Developing a detailed scoring mechanism to rank attributes and record the process of ranking will always be useful.
### A structured analogy
Alternatively, a structured approach comprising a panel of experts can be implemented, as was proposed by Green & Armstrong ([2007](#ref-Green2007)). The concept is similar to that of a Delphi; however, the forecasting task is completed by considering analogies. First, a facilitator is appointed. Then the structured approach involves the following steps.
1. A panel of experts who are likely to have experience with analogous situations is assembled.
2. Tasks/challenges are set and distributed to the experts.
3. Experts identify and describe as many analogies as they can, and generate forecasts based on each analogy.
4. Experts list similarities and differences of each analogy to the target situation, then rate the similarity of each analogy to the target situation on a scale.
5. Forecasts are derived by the facilitator using a set rule. This can be a weighted average, where the weights can be guided by the ranking scores of each analogy by the experts.
As with the Delphi approach, anonymity of the experts may be an advantage in not suppressing creativity, but could hinder collaboration. Green and Armstrong found no gain in collaboration between the experts in their results. A key finding was that experts with multiple analogies (more than two), and who had direct experience with the analogies, generated the most accurate forecasts.
### Bibliography
Green, K. C., & Armstrong, J. S. (2007). Structured analogies for forecasting. *International Journal of Forecasting*, *23*(3), 365376.
Kahneman, D., & Lovallo, D. (1993). Timid choices and bold forecasts: A cognitive perspective on risk taking. *Management Science*, *39*(1), 1731.
---
11. This example is extracted from Kahneman & Lovallo ([1993](#ref-Kahneman1993))[↩︎](https://otexts.com/fpp3/analogies.html#fnref11)
## 6.5 Scenario forecasting
A fundamentally different approach to judgmental forecasting is scenario-based forecasting. The aim of this approach is to generate forecasts based on plausible scenarios. In contrast to the two previous approaches (Delphi and forecasting by analogy) where the resulting forecast is intended to be a likely outcome, each scenario-based forecast may have a low probability of occurrence. The scenarios are generated by considering all possible factors or drivers, their relative impacts, the interactions between them, and the targets to be forecast.
Building forecasts based on scenarios allows a wide range of possible forecasts to be generated and some extremes to be identified. For example it is usual for “best”, “middle” and “worst” case scenarios to be presented, although many other scenarios will be generated. Thinking about and documenting these contrasting extremes can lead to early contingency planning.
With scenario forecasting, decision makers often participate in the generation of scenarios. While this may lead to some biases, it can ease the communication of the scenario-based forecasts, and lead to a better understanding of the results.
## 6.6 New product forecasting
The definition of a new product can vary. It may be an entirely new product which has been launched, a variation of an existing product (“new and improved”), a change in the pricing scheme of an existing product, or even an existing product entering a new market.
Judgmental forecasting is usually the only available method for new product forecasting, as historical data are unavailable. The approaches we have already outlined (Delphi, forecasting by analogy and scenario forecasting) are all applicable when forecasting the demand for a new product.
Other methods which are more specific to the situation are also available. We briefly describe three such methods which are commonly applied in practice. These methods are less structured than those already discussed, and are likely to lead to more biased forecasts as a result.
### Sales force composite
In this approach, forecasts for each outlet/branch/store of a company are generated by salespeople, and are then aggregated. This usually involves sales managers forecasting the demand for the outlet they manage. Salespeople are usually closest to the interaction between customers and products, and often develop an intuition about customer purchasing intentions. They bring this valuable experience and expertise to the forecast.
However, having salespeople generate forecasts violates the key principle of segregating forecasters and users, which can create biases in many directions. It is common for the performance of a salesperson to be evaluated against the sales forecasts or expectations set beforehand. In this case, the salesperson acting as a forecaster may introduce some self-serving bias by generating low forecasts. On the other hand, one can imagine an enthusiastic salesperson, full of optimism, generating high forecasts.
Moreover a successful salesperson is not necessarily a successful nor well-informed forecaster. A large proportion of salespeople will have no or limited formal training in forecasting. Finally, salespeople will feel customer displeasure at first hand if, for example, the product runs out or is not introduced in their store. Such interactions will cloud their judgment.
### Executive opinion
In contrast to the sales force composite, this approach involves staff at the top of the managerial structure generating aggregate forecasts. Such forecasts are usually generated in a group meeting, where executives contribute information from their own area of the company. Having executives from different functional areas of the company promotes great skill and knowledge diversity in the group.
This process carries all of the advantages and disadvantages of a group meeting setting which we discussed earlier. In this setting, it is important to justify and document the forecasting process. That is, executives need to be held accountable in order to reduce the biases generated by the group meeting setting. There may also be scope to apply variations to a Delphi approach in this setting; for example, the estimate-talk-estimate process described earlier.
### Customer intentions
Customer intentions can be used to forecast the demand for a new product or for a variation on an existing product. Questionnaires are filled in by customers on their intentions to buy the product. A structured questionnaire is used, asking customers to rate the likelihood of them purchasing the product on a scale; for example, highly likely, likely, possible, unlikely, highly unlikely.
Survey design challenges, such as collecting a representative sample, applying a time- and cost-effective method, and dealing with non-responses, need to be addressed.[12](#fn12)
Furthermore, in this survey setting we must keep in mind the relationship between purchase intention and purchase behaviour. Customers do not always do what they say they will. Many studies have found a positive correlation between purchase intentions and purchase behaviour; however, the strength of these correlations varies substantially. The factors driving this variation include the timings of data collection and product launch, the definition of “new” for the product, and the type of industry. Behavioural theory tells us that intentions predict behaviour if the intentions are measured just before the behaviour.[13](#fn13) The time between intention and behaviour will vary depending on whether it is a completely new product or a variation on an existing product. Also, the correlation between intention and behaviour is found to be stronger for variations on existing and familiar products than for completely new products.
Whichever method of new product forecasting is used, it is important to thoroughly document the forecasts made, and the reasoning behind them, in order to be able to evaluate them when data become available.
### Bibliography
Groves, R. M., Fowler, F. J., Couper, M. P., Lepkowski, J. M., Singer, E., & Tourangeau, R. (2009). *Survey methodology* (2nd ed). John Wiley & Sons.
Randall, D. M., & Wolff, J. A. (1994). The time interval in the intention-behaviour relationship: Meta-analysis. *British Journal of Social Psychology*, *33*(4), 405418.
---
12. Groves et al. ([2009](#ref-Groves2009))[↩︎](https://otexts.com/fpp3/new-products.html#fnref12)
13. Randall & Wolff ([1994](#ref-RW94))[↩︎](https://otexts.com/fpp3/new-products.html#fnref13)
## 6.7 Judgmental adjustments
In this final section, we consider the situation where historical data are available and are used to generate statistical forecasts. It is common for practitioners to then apply judgmental adjustments to these forecasts. These adjustments can potentially provide all of the advantages of judgmental forecasting which have been discussed earlier in this chapter. For example, they provide an avenue for incorporating factors that may not be accounted for in the statistical model, such as promotions, large sporting events, holidays, or recent events that are not yet reflected in the data. However, these advantages come to fruition only when the right conditions are present. Judgmental adjustments, like judgmental forecasts, come with biases and limitations, and we must implement methodical strategies in order to minimise them.
### Use adjustments sparingly
Practitioners adjust much more often than they should, and many times for the wrong reasons. By adjusting statistical forecasts, users of forecasts create a feeling of ownership and credibility. Users often do not understand or appreciate the mechanisms that generate the statistical forecasts (as they will usually have no training in this area). By implementing judgmental adjustments, users feel that they have contributed to and completed the forecasts, and they can now relate their own intuition and interpretations to these. The forecasts have become their own.
Judgmental adjustments should not aim to correct for a systematic pattern in the data that is thought to have been missed by the statistical model. This has been proven to be ineffective, as forecasters tend to read non-existent patterns in noisy series. Statistical models are much better at taking account of data patterns, and judgmental adjustments only hinder accuracy.
Judgmental adjustments are most effective when there is significant additional information at hand or strong evidence of the need for an adjustment. We should only adjust when we have important extra information which is not incorporated in the statistical model. Hence, adjustments seem to be most accurate when they are large in size. Small adjustments (especially in the positive direction promoting the illusion of optimism) have been found to hinder accuracy, and should be avoided.
### Apply a structured approach
Using a structured and systematic approach will improve the accuracy of judgmental adjustments. Following the key principles outlined in Section [6.2](https://otexts.com/fpp3/judgmental-principles.html#judgmental-principles) is vital. In particular, having to document and justify adjustments will make it more challenging to override the statistical forecasts, and will guard against unnecessary adjustments.
It is common for adjustments to be implemented by a panel (see the example that follows). Using a Delphi setting carries great advantages. However, if adjustments are implemented in a group meeting, it is wise to consider the forecasts of key markets or products first, as panel members will get tired during this process. Fewer adjustments tend to be made as the meeting goes on through the day.
### Example: Tourism Forecasting Committee (TFC)
Tourism Australia publishes forecasts for all aspects of Australian tourism twice a year. The published forecasts are generated by the TFC, an independent body which comprises experts from various government and industry sectors; for example, the Australian Commonwealth Treasury, airline companies, consulting firms, banking sector companies, and tourism bodies.
The forecasting methodology applied is an iterative process. First, model-based statistical forecasts are generated by the forecasting unit within Tourism Australia, then judgmental adjustments are made to these in two rounds. In the first round, the TFC Technical Committee[14](#fn14) (comprising senior researchers, economists and independent advisers) adjusts the model-based forecasts. In the second and final round, the TFC (comprising industry and government experts) makes final adjustments. In both rounds, adjustments are made by consensus.
![Long run annual forecasts for domestic visitor nights for Australia. We study regression models in Chapter 7, and ETS (ExponenTial Smoothing) models in Chapter 8.](https://otexts.com/fpp3/fpp_files/figure-html/tfc-1.png)
Figure 6.2: Long run annual forecasts for domestic visitor nights for Australia. We study regression models in Chapter [7](https://otexts.com/fpp3/regression.html#regression), and ETS (ExponenTial Smoothing) models in Chapter [8](https://otexts.com/fpp3/expsmooth.html#expsmooth).
In 2008, we[15](#fn15) analysed forecasts for Australian domestic tourism. We concluded that the published TFC forecasts were optimistic, especially for the long-run, and we proposed alternative model-based forecasts. We now have access to observed data up to and including 2011. In Figure [6.2](https://otexts.com/fpp3/judgmental-adjustments.html#fig:tfc), we plot the published forecasts against the actual data. We can see that the published TFC forecasts have continued to be optimistic.
What can we learn from this example? Although the TFC clearly states in its methodology that it produces forecasts rather than targets, could this be a case where these have been confused? Are the forecasters and users sufficiently well-segregated in this process? Could the iterative process itself be improved? Could the adjustment process in the meetings be improved? Could it be that the group meetings have promoted optimism? Could it be that domestic tourism should have been considered earlier in the day?
### Bibliography
Athanasopoulos, G., & Hyndman, R. J. (2008). Modelling and forecasting Australian domestic tourism. *Tourism Management*, *29*(1), 1931.
---
14. Athanasopoulos was an observer on this technical committee for a few years.[↩︎](https://otexts.com/fpp3/judgmental-adjustments.html#fnref14)
15. Athanasopoulos & Hyndman ([2008](#ref-austourism))[↩︎](https://otexts.com/fpp3/judgmental-adjustments.html#fnref15)
## 6.8 Further reading
Many forecasting textbooks ignore judgmental forecasting altogether. Here are three which do cover it in some detail.
* Chapter 11 of Ord et al. ([2017](#ref-Ord2017)) provides an excellent review of some of the same topics as this chapter, but also includes using judgment to assessing forecast uncertainty, and forecasting using prediction markets.
* Goodwin & Wright ([2009](#ref-GW04)) is a book-length treatment of the use of judgment in decision making by two of the leading researchers in the field.
* Kahn ([2006](#ref-Kahn2006)) covers techniques for new product forecasting, where judgmental methods play an important role.
There have been some helpful survey papers on judgmental forecasting published in the last 20 years. We have found these three particularly helpful.
* Fildes & Goodwin ([2007b](#ref-Fildes2007a))
* Fildes & Goodwin ([2007a](#ref-Fildes2007))
* Harvey ([2001](#ref-Harvey2001))
Some helpful papers on individual judgmental forecasting methods are listed in the table below.
| **Forecasting Method** | **Recommended papers** |
| --- | --- |
| Delphi | Rowe & Wright ([1999](#ref-RW99)) |
| | Rowe ([2007](#ref-Rowe2007)) |
| Adjustments | Sanders et al. ([2005](#ref-Sanders2005)) |
| | Eroglu & Croxton ([2010](#ref-Eroglu2010)) |
| | Franses & Legerstee ([2013](#ref-Franses2013)) |
| Analogy | Green & Armstrong ([2007](#ref-Green2007)) |
| Scenarios | Önkal et al. ([2013](#ref-Onkal2012)) |
| Customer intentions | Morwitz et al. ([2007](#ref-Morwitz2007)) |
### Bibliography
Eroglu, C., & Croxton, K. L. (2010). Biases in judgmental adjustments of statistical forecasts: The role of individual differences. *International Journal of Forecasting*, *26*(1), 116133.
Fildes, R., & Goodwin, P. (2007a). Against your better judgment? How organizations can improve their use of management judgment in forecasting. *Interfaces*, *37*(6), 570576.
Fildes, R., & Goodwin, P. (2007b). Good and bad judgment in forecasting: Lessons from four companies. *Foresight: The International Journal of Applied Forecasting*, *8*, 510.
Franses, P. H., & Legerstee, R. (2013). Do statistical forecasting models for SKU-level data benefit from including past expert knowledge? *International Journal of Forecasting*, *29*(1), 8087.
Goodwin, P., & Wright, G. (2009). *Decision analysis for management judgment* (4th ed). John Wiley & Sons.
Green, K. C., & Armstrong, J. S. (2007). Structured analogies for forecasting. *International Journal of Forecasting*, *23*(3), 365376.
Harvey, N. (2001). Improving judgment in forecasting. In J. S. Armstrong (Ed.), *Principles of forecasting: A handbook for researchers and practitioners* (pp. 5980). Kluwer Academic Publishers.
Kahn, K. B. (2006). *New product forecasting: An applied approach*. M.E. Sharp.
Morwitz, V. G., Steckel, J. H., & Gupta, A. (2007). When do purchase intentions predict sales? *International Journal of Forecasting*, *23*(3), 347364.
Önkal, D., Sayım, K. Z., & Gönül, M. S. (2013). Scenarios as channels of forecast advice. *Technological Forecasting and Social Change*, *80*(4), 772788.
Ord, J. K., Fildes, R., & Kourentzes, N. (2017). *Principles of business forecasting* (2nd ed.). Wessex Press Publishing Co.
Rowe, G. (2007). A guide to Delphi. *Foresight: The International Journal of Applied Forecasting*, *8*, 1116.
Rowe, G., & Wright, G. (1999). The Delphi technique as a forecasting tool: Issues and analysis. *International Journal of Forecasting*, *15*(4), 353375.
Sanders, N., Goodwin, P., Önkal, D., Gönül, M. S., Harvey, N., Lee, A., & Kjolso, L. (2005). When and how should statistical forecasts be judgmentally adjusted? *Foresight: The International Journal of Applied Forecasting*, *1*(1), 523.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,947 @@
Source: https://otexts.com/fpp3/expsmooth.html (chapter expsmooth, 10 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 08-exponential-smoothing
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 8 Exponential smoothing
Exponential smoothing was proposed in the late 1950s ([Brown, 1959](#ref-Brown59); [Holt, 1957](#ref-Holt57); [Winters, 1960](#ref-Winters60)), and has motivated some of the most successful forecasting methods. Forecasts produced using exponential smoothing methods are weighted averages of past observations, with the weights decaying exponentially as the observations get older. In other words, the more recent the observation the higher the associated weight. This framework generates reliable forecasts quickly and for a wide range of time series, which is a great advantage and of major importance to applications in industry.
This chapter is divided into two parts. In the first part (Sections [8.1](https://otexts.com/fpp3/ses.html#ses)[8.4](https://otexts.com/fpp3/taxonomy.html#taxonomy)) we present the mechanics of the most important exponential smoothing methods, and their application in forecasting time series with various characteristics. This helps us develop an intuition to how these methods work. In this setting, selecting and using a forecasting method may appear to be somewhat ad hoc. The selection of the method is generally based on recognising key components of the time series (trend and seasonal) and the way in which these enter the smoothing method (e.g., in an additive, damped or multiplicative manner).
In the second part of the chapter (Sections [8.5](https://otexts.com/fpp3/ets.html#ets)[8.7](https://otexts.com/fpp3/ets-forecasting.html#ets-forecasting)) we present the statistical models that underlie exponential smoothing methods. These models generate identical point forecasts to the methods discussed in the first part of the chapter, but also generate prediction intervals. Furthermore, this statistical framework allows for genuine model selection between competing models.
### Bibliography
Brown, R. G. (1959). *Statistical forecasting for inventory control*. McGraw/Hill.
Holt, C. C. (1957). *Forecasting seasonals and trends by exponentially weighted averages* (ONR Memorandum No. 52). Carnegie Institute of Technology, Pittsburgh USA. Reprinted in the *International Journal of Forecasting*, 2004.
Winters, P. R. (1960). Forecasting sales by exponentially weighted moving averages. *Management Science*, *6*(3), 324342.
## 8.1 Simple exponential smoothing
The simplest of the exponentially smoothing methods is naturally called **simple exponential smoothing** (SES)[16](#fn16). This method is suitable for forecasting data with no clear trend or seasonal pattern. For example, the data in Figure [8.1](https://otexts.com/fpp3/ses.html#fig:7-oil) do not display any clear trending behaviour or any seasonality. (There is a decline in the last few years, which might suggest a trend. We will consider whether a trended method would be better for this series later in this chapter.) We have already considered the naïve and the average as possible methods for forecasting such data (Section [5.2](https://otexts.com/fpp3/simple-methods.html#simple-methods)).
```
algeria_economy <- global_economy |>
filter(Country == "Algeria")
algeria_economy |>
autoplot(Exports) +
labs(y = "% of GDP", title = "Exports: Algeria")
```
![Exports of goods and services from Algeria from 1960 to 2017.](https://otexts.com/fpp3/fpp_files/figure-html/7-oil-1.png)
Figure 8.1: Exports of goods and services from Algeria from 1960 to 2017.
Using the naïve method, all forecasts for the future are equal to the last observed value of the series,
\[
\hat{y}_{T+h|T} = y_{T},
\]
for \(h=1,2,\dots\). Hence, the naïve method assumes that the most recent observation is the only important one, and all previous observations provide no information for the future. This can be thought of as a weighted average where all of the weight is given to the last observation.
Using the average method, all future forecasts are equal to a simple average of the observed data,
\[
\hat{y}_{T+h|T} = \frac1T \sum_{t=1}^T y_t,
\]
for \(h=1,2,\dots\). Hence, the average method assumes that all observations are of equal importance, and gives them equal weights when generating forecasts.
We often want something between these two extremes. For example, it may be sensible to attach larger weights to more recent observations than to observations from the distant past. This is exactly the concept behind simple exponential smoothing. Forecasts are calculated using weighted averages, where the weights decrease exponentially as observations come from further in the past — the smallest weights are associated with the oldest observations:
\[\begin{equation}
\hat{y}_{T+1|T} = \alpha y_T + \alpha(1-\alpha) y_{T-1} + \alpha(1-\alpha)^2 y_{T-2}+ \cdots, \tag{8.1}
\end{equation}\]
where \(0 \le \alpha \le 1\) is the smoothing parameter. The one-step-ahead forecast for time \(T+1\) is a weighted average of all of the observations in the series \(y_1,\dots,y_T\). The rate at which the weights decrease is controlled by the parameter \(\alpha\).
The table below shows the weights attached to observations for four different values of \(\alpha\) when forecasting using simple exponential smoothing. Note that the sum of the weights even for a small value of \(\alpha\) will be approximately one for any reasonable sample size.
| | \(\alpha=0.2\) | \(\alpha=0.4\) | \(\alpha=0.6\) | \(\alpha=0.8\) |
| --- | --- | --- | --- | --- |
| \(y_{T}\) | 0.2000 | 0.4000 | 0.6000 | 0.8000 |
| \(y_{T-1}\) | 0.1600 | 0.2400 | 0.2400 | 0.1600 |
| \(y_{T-2}\) | 0.1280 | 0.1440 | 0.0960 | 0.0320 |
| \(y_{T-3}\) | 0.1024 | 0.0864 | 0.0384 | 0.0064 |
| \(y_{T-4}\) | 0.0819 | 0.0518 | 0.0154 | 0.0013 |
| \(y_{T-5}\) | 0.0655 | 0.0311 | 0.0061 | 0.0003 |
For any \(\alpha\) between 0 and 1, the weights attached to the observations decrease exponentially as we go back in time, hence the name “exponential smoothing”. If \(\alpha\) is small (i.e., close to 0), more weight is given to observations from the more distant past. If \(\alpha\) is large (i.e., close to 1), more weight is given to the more recent observations. For the extreme case where \(\alpha=1\), \(\hat{y}_{T+1|T}=y_T\), so the forecasts are equal to the naïve forecasts.
We present two equivalent forms of simple exponential smoothing, each of which leads to the forecast Equation [(8.1)](https://otexts.com/fpp3/ses.html#eq:7-ses).
### Weighted average form
The forecast at time \(T+1\) is equal to a weighted average between the most recent observation \(y_T\) and the previous forecast \(\hat{y}_{T|T-1}\):
\[
\hat{y}_{T+1|T} = \alpha y_T + (1-\alpha) \hat{y}_{T|T-1},
\]
where \(0 \le \alpha \le 1\) is the smoothing parameter.
Similarly, we can write the fitted values as
\[
\hat{y}_{t+1|t} = \alpha y_t + (1-\alpha) \hat{y}_{t|t-1},
\]
for \(t=1,\dots,T\). (Recall that fitted values are simply one-step forecasts of the training data.)
The process has to start somewhere, so we let the first fitted value at time 1 be denoted by \(\ell_0\) (which we will have to estimate). Then
\[\begin{align\*}
\hat{y}_{2|1} &= \alpha y_1 + (1-\alpha) \ell_0\\
\hat{y}_{3|2} &= \alpha y_2 + (1-\alpha) \hat{y}_{2|1}\\
\hat{y}_{4|3} &= \alpha y_3 + (1-\alpha) \hat{y}_{3|2}\\
\vdots\\
\hat{y}_{T|T-1} &= \alpha y_{T-1} + (1-\alpha) \hat{y}_{T-1|T-2}\\
\hat{y}_{T+1|T} &= \alpha y_T + (1-\alpha) \hat{y}_{T|T-1}.
\end{align\*}\]
Substituting each equation into the following equation, we obtain
\[\begin{align\*}
\hat{y}_{3|2} & = \alpha y_2 + (1-\alpha) \left[\alpha y_1 + (1-\alpha) \ell_0\right] \\
& = \alpha y_2 + \alpha(1-\alpha) y_1 + (1-\alpha)^2 \ell_0 \\
\hat{y}_{4|3} & = \alpha y_3 + (1-\alpha) [\alpha y_2 + \alpha(1-\alpha) y_1 + (1-\alpha)^2 \ell_0]\\
& = \alpha y_3 + \alpha(1-\alpha) y_2 + \alpha(1-\alpha)^2 y_1 + (1-\alpha)^3 \ell_0 \\
& ~~\vdots \\
\hat{y}_{T+1|T} & = \sum_{j=0}^{T-1} \alpha(1-\alpha)^j y_{T-j} + (1-\alpha)^T \ell_{0}.
\end{align\*}\]
The last term becomes tiny for large \(T\). So, the weighted average form leads to the same forecast Equation [(8.1)](https://otexts.com/fpp3/ses.html#eq:7-ses).
### Component form
An alternative representation is the component form. For simple exponential smoothing, the only component included is the level, \(\ell_t\). (Other methods which are considered later in this chapter may also include a trend \(b_t\) and a seasonal component \(s_t\).) Component form representations of exponential smoothing methods comprise a forecast equation and a smoothing equation for each of the components included in the method. The component form of simple exponential smoothing is given by:
\[\begin{align\*}
\text{Forecast equation} && \hat{y}_{t+h|t} & = \ell_{t}\\
\text{Smoothing equation} && \ell_{t} & = \alpha y_{t} + (1 - \alpha)\ell_{t-1},
\end{align\*}\]
where \(\ell_{t}\) is the level (or the smoothed value) of the series at time \(t\). Setting \(h=1\) gives the fitted values, while setting \(t=T\) gives the true forecasts beyond the training data.
The forecast equation shows that the forecast value at time \(t+1\) is the estimated level at time \(t\). The smoothing equation for the level (usually referred to as the level equation) gives the estimated level of the series at each period \(t\).
If we replace \(\ell_t\) with \(\hat{y}_{t+1|t}\) and \(\ell_{t-1}\) with \(\hat{y}_{t|t-1}\) in the smoothing equation, we will recover the weighted average form of simple exponential smoothing.
The component form of simple exponential smoothing is not particularly useful on its own, but it will be the easiest form to use when we start adding other components.
### Flat forecasts
Simple exponential smoothing has a “flat” forecast function:
\[
\hat{y}_{T+h|T} = \hat{y}_{T+1|T}=\ell_T, \qquad h=2,3,\dots.
\]
That is, all forecasts take the same value, equal to the last level component. Remember that these forecasts will only be suitable if the time series has no trend or seasonal component.
### Optimisation
The application of every exponential smoothing method requires the smoothing parameters and the initial values to be chosen. In particular, for simple exponential smoothing, we need to select the values of \(\alpha\) and \(\ell_0\). All forecasts can be computed from the data once we know those values. For the methods that follow there is usually more than one smoothing parameter and more than one initial component to be chosen.
In some cases, the smoothing parameters may be chosen in a subjective manner — the forecaster specifies the value of the smoothing parameters based on previous experience. However, a more reliable and objective way to obtain values for the unknown parameters is to estimate them from the observed data.
In Section [7.2](https://otexts.com/fpp3/least-squares.html#least-squares), we estimated the coefficients of a regression model by minimising the sum of the squared residuals (usually known as SSE or “sum of squared errors”). Similarly, the unknown parameters and the initial values for any exponential smoothing method can be estimated by minimising the SSE. The residuals are specified as \(e_t=y_t - \hat{y}_{t|t-1}\) for \(t=1,\dots,T\). Hence, we find the values of the unknown parameters and the initial values that minimise
\[\begin{equation}
\text{SSE}=\sum_{t=1}^T(y_t - \hat{y}_{t|t-1})^2=\sum_{t=1}^Te_t^2. \tag{8.2}
\end{equation}\]
Unlike the regression case (where we have formulas which return the values of the regression coefficients that minimise the SSE), this involves a non-linear minimisation problem, and we need to use an optimisation tool to solve it.
### Example: Algerian exports
In this example, simple exponential smoothing is applied to forecast exports of goods and services from Algeria.
```
# Estimate parameters
fit <- algeria_economy |>
model(ETS(Exports ~ error("A") + trend("N") + season("N")))
fc <- fit |>
forecast(h = 5)
```
This gives parameter estimates \(\hat\alpha=0.84\) and \(\hat\ell_0=39.5\), obtained by minimising SSE over periods \(t=1,2,\dots,58\), subject to the restriction that \(0\le\alpha\le1\).
In Table [8.1](https://otexts.com/fpp3/ses.html#tab:export-ses) we demonstrate the calculation using these parameters. The second last column shows the estimated level for times \(t=0\) to \(t=58\); the last few rows of the last column show the forecasts for \(h=1\) to \(5\)-steps ahead.
Table 8.1: Forecasting goods and services exports from Algeria using simple exponential smoothing.
| Year | Time | Observation | Level | Forecast |
| --- | --- | --- | --- | --- |
| | \(t\) | \(y_t\) | \(\ell_t\) | \(\hat{y}_{t\vert t-1}\) |
| 1959 | 0 | | 39.54 | |
| 1960 | 1 | 39.04 | 39.12 | 39.54 |
| 1961 | 2 | 46.24 | 45.10 | 39.12 |
| 1962 | 3 | 19.79 | 23.84 | 45.10 |
| 1963 | 4 | 24.68 | 24.55 | 23.84 |
| 1964 | 5 | 25.08 | 25.00 | 24.55 |
| 1965 | 6 | 22.60 | 22.99 | 25.00 |
| 1966 | 7 | 25.99 | 25.51 | 22.99 |
| 1967 | 8 | 23.43 | 23.77 | 25.51 |
| | ⋮ | ⋮ | ⋮ | ⋮ |
| 2014 | 55 | 30.22 | 30.80 | 33.85 |
| 2015 | 56 | 23.17 | 24.39 | 30.80 |
| 2016 | 57 | 20.86 | 21.43 | 24.39 |
| 2017 | 58 | 22.64 | 22.44 | 21.43 |
| | \(h\) | | | \(\hat{y}_{T+h\vert T}\) |
| 2018 | 1 | | | 22.44 |
| 2019 | 2 | | | 22.44 |
| 2020 | 3 | | | 22.44 |
| 2021 | 4 | | | 22.44 |
| 2022 | 5 | | | 22.44 |
The black line in Figure [8.2](https://otexts.com/fpp3/ses.html#fig:ses) shows the data, which has a changing level over time.
```
fc |>
autoplot(algeria_economy) +
geom_line(aes(y = .fitted), col="#D55E00",
data = augment(fit)) +
labs(y="% of GDP", title="Exports: Algeria") +
guides(colour = "none")
```
![Simple exponential smoothing applied to exports from Algeria (1960--2017). The orange curve shows the one-step-ahead fitted values.](https://otexts.com/fpp3/fpp_files/figure-html/ses-1.png)
Figure 8.2: Simple exponential smoothing applied to exports from Algeria (19602017). The orange curve shows the one-step-ahead fitted values.
The forecasts for the period 20182022 are plotted in Figure [8.2](https://otexts.com/fpp3/ses.html#fig:ses). Also plotted are one-step-ahead fitted values alongside the data over the period 19602017. The large value of \(\alpha\) in this example is reflected in the large adjustment that takes place in the estimated level \(\ell_t\) at each time. A smaller value of \(\alpha\) would lead to smaller changes over time, and so the series of fitted values would be smoother.
The prediction intervals shown here are calculated using the methods described in Section [8.7](https://otexts.com/fpp3/ets-forecasting.html#ets-forecasting). The prediction intervals show that there is considerable uncertainty in the future exports over the five-year forecast period. So interpreting the point forecasts without accounting for the large uncertainty can be very misleading.
---
16. In some books it is called “single exponential smoothing”.[↩︎](https://otexts.com/fpp3/ses.html#fnref16)
## 8.2 Methods with trend
### Holts linear trend method
Holt ([1957](#ref-Holt57)) extended simple exponential smoothing to allow the forecasting of data with a trend. This method involves a forecast equation and two smoothing equations (one for the level and one for the trend):
\[\begin{align\*}
\text{Forecast equation}&& \hat{y}_{t+h|t} &= \ell_{t} + hb_{t} \\
\text{Level equation} && \ell_{t} &= \alpha y_{t} + (1 - \alpha)(\ell_{t-1} + b_{t-1})\\
\text{Trend equation} && b_{t} &= \beta^\*(\ell_{t} - \ell_{t-1}) + (1 -\beta^\*)b_{t-1},
\end{align\*}\]
where \(\ell_t\) denotes an estimate of the level of the series at time \(t\), \(b_t\) denotes an estimate of the trend (slope) of the series at time \(t\), \(\alpha\) is the smoothing parameter for the level, \(0\le\alpha\le1\), and \(\beta^\*\) is the smoothing parameter for the trend, \(0\le\beta^\*\le1\). (We denote this as \(\beta^\*\) instead of \(\beta\) for reasons that will be explained in Section [8.5](https://otexts.com/fpp3/ets.html#ets).)
As with simple exponential smoothing, the level equation here shows that \(\ell_t\) is a weighted average of observation \(y_t\) and the one-step-ahead training forecast for time \(t\), here given by \(\ell_{t-1} + b_{t-1}\). The trend equation shows that \(b_t\) is a weighted average of the estimated trend at time \(t\) based on \(\ell_{t} - \ell_{t-1}\) and \(b_{t-1}\), the previous estimate of the trend.
The forecast function is no longer flat but trending. The \(h\)-step-ahead forecast is equal to the last estimated level plus \(h\) times the last estimated trend value. Hence the forecasts are a linear function of \(h\).
### Example: Australian population
```
aus_economy <- global_economy |>
filter(Code == "AUS") |>
mutate(Pop = Population / 1e6)
autoplot(aus_economy, Pop) +
labs(y = "Millions", title = "Australian population")
```
![Australia's population, 1960-2017.](https://otexts.com/fpp3/fpp_files/figure-html/auspop-1.png)
Figure 8.3: Australias population, 1960-2017.
Figure [8.3](https://otexts.com/fpp3/holt.html#fig:auspop) shows Australias annual population from 1960 to 2017. We will apply Holts method to this series. The smoothing parameters, \(\alpha\) and \(\beta^\*\), and the initial values \(\ell_0\) and \(b_0\) are estimated by minimising the SSE for the one-step training errors as in Section [8.1](https://otexts.com/fpp3/ses.html#ses).
```
fit <- aus_economy |>
model(
AAN = ETS(Pop ~ error("A") + trend("A") + season("N"))
)
fc <- fit |> forecast(h = 10)
```
The estimated smoothing coefficient for the level is \(\hat{\alpha} = 0.9999\). The very high value shows that the level changes rapidly in order to capture the highly trended series. The estimated smoothing coefficient for the slope is \(\hat{\beta}^\* = 0.3267\). This is relatively large suggesting that the trend also changes often (even if the changes are slight).
In Table [8.2](https://otexts.com/fpp3/holt.html#tab:popholt) we use these values to demonstrate the application of Holts method.
Table 8.2: Forecasting Australian annual population using Holts linear trend method.
| Year | Time | Observation | Level | Slope | Forecast |
| --- | --- | --- | --- | --- | --- |
| | \(t\) | \(y_t\) | \(\ell_t\) | | \(\hat{y}_{t+1\mid t}\) |
| 1959 | 0 | | 10.05 | 0.22 | |
| 1960 | 1 | 10.28 | 10.28 | 0.22 | 10.28 |
| 1961 | 2 | 10.48 | 10.48 | 0.22 | 10.50 |
| 1962 | 3 | 10.74 | 10.74 | 0.23 | 10.70 |
| 1963 | 4 | 10.95 | 10.95 | 0.22 | 10.97 |
| 1964 | 5 | 11.17 | 11.17 | 0.22 | 11.17 |
| 1965 | 6 | 11.39 | 11.39 | 0.22 | 11.39 |
| 1966 | 7 | 11.65 | 11.65 | 0.23 | 11.61 |
| | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 2014 | 55 | 23.50 | 23.50 | 0.37 | 23.52 |
| 2015 | 56 | 23.85 | 23.85 | 0.36 | 23.87 |
| 2016 | 57 | 24.21 | 24.21 | 0.36 | 24.21 |
| 2017 | 58 | 24.60 | 24.60 | 0.37 | 24.57 |
| | \(h\) | | | | \(\hat{y}_{T+h\mid T}\) |
| 2018 | 1 | | | | 24.97 |
| 2019 | 2 | | | | 25.34 |
| 2020 | 3 | | | | 25.71 |
| 2021 | 4 | | | | 26.07 |
| 2022 | 5 | | | | 26.44 |
| 2023 | 6 | | | | 26.81 |
| 2024 | 7 | | | | 27.18 |
| 2025 | 8 | | | | 27.55 |
| 2026 | 9 | | | | 27.92 |
| 2027 | 10 | | | | 28.29 |
### Damped trend methods
The forecasts generated by Holts linear method display a constant trend (increasing or decreasing) indefinitely into the future. Empirical evidence indicates that these methods tend to over-forecast, especially for longer forecast horizons. Motivated by this observation, Gardner & McKenzie ([1985](#ref-GarMacK1985)) introduced a parameter that “dampens” the trend to a flat line some time in the future. Methods that include a damped trend have proven to be very successful, and are arguably the most popular individual methods when forecasts are required automatically for many series.
In conjunction with the smoothing parameters \(\alpha\) and \(\beta^\*\) (with values between 0 and 1 as in Holts method), this method also includes a damping parameter \(0<\phi<1\):
\[\begin{align\*}
\hat{y}_{t+h|t} &= \ell_{t} + (\phi+\phi^2 + \dots + \phi^{h})b_{t} \\
\ell_{t} &= \alpha y_{t} + (1 - \alpha)(\ell_{t-1} + \phi b_{t-1})\\
b_{t} &= \beta^\*(\ell_{t} - \ell_{t-1}) + (1 -\beta^\*)\phi b_{t-1}.
\end{align\*}\]
If \(\phi=1\), the method is identical to Holts linear method. For values between \(0\) and \(1\), \(\phi\) dampens the trend so that it approaches a constant some time in the future. In fact, the forecasts converge to \(\ell_T+\phi b_T/(1-\phi)\) as \(h\rightarrow\infty\) for any value \(0<\phi<1\). This means that short-run forecasts are trended while long-run forecasts are constant.
In practice, \(\phi\) is rarely less than 0.8 as the damping has a very strong effect for smaller values. Values of \(\phi\) close to 1 will mean that a damped model is not able to be distinguished from a non-damped model. For these reasons, we usually restrict \(\phi\) to a minimum of 0.8 and a maximum of 0.98.
### Example: Australian Population (continued)
Figure [8.4](https://otexts.com/fpp3/holt.html#fig:dampedtrend) shows the forecasts for years 20182032 generated from Holts linear trend method and the damped trend method.
```
aus_economy |>
model(
`Holt's method` = ETS(Pop ~ error("A") +
trend("A") + season("N")),
`Damped Holt's method` = ETS(Pop ~ error("A") +
trend("Ad", phi = 0.9) + season("N"))
) |>
forecast(h = 15) |>
autoplot(aus_economy, level = NULL) +
labs(title = "Australian population",
y = "Millions") +
guides(colour = guide_legend(title = "Forecast"))
```
![Forecasting annual Australian population (millions) over 2018-2032. For the damped trend method, $\phi=0.90$.](https://otexts.com/fpp3/fpp_files/figure-html/dampedtrend-1.png)
Figure 8.4: Forecasting annual Australian population (millions) over 2018-2032. For the damped trend method, \(\phi=0.90\).
We have set the damping parameter to a relatively low number \((\phi=0.90)\) to exaggerate the effect of damping for comparison. Usually, we would estimate \(\phi\) along with the other parameters. We have also used a rather large forecast horizon (\(h=15\)) to highlight the difference between a damped trend and a linear trend.
### Example: Internet usage
In this example, we compare the forecasting performance of the three exponential smoothing methods that we have considered so far in forecasting the number of users connected to the internet via a server. The data is observed over 100 minutes and is shown in Figure [8.5](https://otexts.com/fpp3/holt.html#fig:www-usage).
```
www_usage <- as_tsibble(WWWusage)
www_usage |> autoplot(value) +
labs(x="Minute", y="Number of users",
title = "Internet usage per minute")
```
![Users connected to the internet through a server](https://otexts.com/fpp3/fpp_files/figure-html/www-usage-1.png)
Figure 8.5: Users connected to the internet through a server
We will use time series cross-validation to compare the one-step forecast accuracy of the three methods.
```
www_usage |>
stretch_tsibble(.init = 10) |>
model(
SES = ETS(value ~ error("A") + trend("N") + season("N")),
Holt = ETS(value ~ error("A") + trend("A") + season("N")),
Damped = ETS(value ~ error("A") + trend("Ad") +
season("N"))
) |>
forecast(h = 1) |>
accuracy(www_usage)
#> # A tibble: 3 × 10
#> .model .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Damped Test 0.288 3.69 3.00 0.347 2.26 0.663 0.636 0.336
#> 2 Holt Test 0.0610 3.87 3.17 0.244 2.38 0.701 0.668 0.296
#> 3 SES Test 1.46 6.05 4.81 0.904 3.55 1.06 1.04 0.803
```
Damped Holts method is best whether you compare MAE or RMSE values. So we will proceed with using the damped Holts method and apply it to the whole data set to get forecasts for future minutes.
```
fit <- www_usage |>
model(
Damped = ETS(value ~ error("A") + trend("Ad") +
season("N"))
)
# Estimated parameters:
tidy(fit)
#> # A tibble: 5 × 3
#> .model term estimate
#> <chr> <chr> <dbl>
#> 1 Damped alpha 1.000
#> 2 Damped beta 0.997
#> 3 Damped phi 0.815
#> 4 Damped l[0] 90.4
#> 5 Damped b[0] -0.0173
```
The smoothing parameter for the slope is estimated to be almost one, indicating that the trend changes to mostly reflect the slope between the last two minutes of internet usage. The value of \(\alpha\) is very close to one, showing that the level reacts strongly to each new observation.
```
fit |>
forecast(h = 10) |>
autoplot(www_usage) +
labs(x="Minute", y="Number of users",
title = "Internet usage per minute")
```
![Forecasting internet usage: comparing forecasting performance of non-seasonal methods.](https://otexts.com/fpp3/fpp_files/figure-html/fig-7-comp-1.png)
Figure 8.6: Forecasting internet usage: comparing forecasting performance of non-seasonal methods.
The resulting forecasts look sensible with decreasing trend, which flattens out due to the low value of the damping parameter (0.815), and relatively wide prediction intervals reflecting the variation in the historical data. The prediction intervals are calculated using the methods described in Section [8.7](https://otexts.com/fpp3/ets-forecasting.html#ets-forecasting).
In this example, the process of selecting a method was relatively easy as both MSE and MAE comparisons suggested the same method (damped Holts). However, sometimes different accuracy measures will suggest different forecasting methods, and then a decision is required as to which forecasting method we prefer to use. As forecasting tasks can vary by many dimensions (length of forecast horizon, size of test set, forecast error measures, frequency of data, etc.), it is unlikely that one method will be better than all others for all forecasting scenarios. What we require from a forecasting method are consistently sensible forecasts, and these should be frequently evaluated against the task at hand.
### Bibliography
Gardner, E. S., & McKenzie, E. (1985). Forecasting trends in time series. *Management Science*, *31*(10), 12371246.
Holt, C. C. (1957). *Forecasting seasonals and trends by exponentially weighted averages* (ONR Memorandum No. 52). Carnegie Institute of Technology, Pittsburgh USA. Reprinted in the *International Journal of Forecasting*, 2004.
## 8.3 Methods with seasonality
Holt ([1957](#ref-Holt57)) and Winters ([1960](#ref-Winters60)) extended Holts method to capture seasonality. The Holt-Winters seasonal method comprises the forecast equation and three smoothing equations — one for the level \(\ell_t\), one for the trend \(b_t\), and one for the seasonal component \(s_t\), with corresponding smoothing parameters \(\alpha\), \(\beta^\*\) and \(\gamma\). We use \(m\) to denote the period of the seasonality, i.e., the number of seasons in a year. For example, for quarterly data \(m=4\), and for monthly data \(m=12\).
There are two variations to this method that differ in the nature of the seasonal component. The additive method is preferred when the seasonal variations are roughly constant through the series, while the multiplicative method is preferred when the seasonal variations are changing proportional to the level of the series. With the additive method, the seasonal component is expressed in absolute terms in the scale of the observed series, and in the level equation the series is seasonally adjusted by subtracting the seasonal component. Within each year, the seasonal component will add up to approximately zero. With the multiplicative method, the seasonal component is expressed in relative terms (percentages), and the series is seasonally adjusted by dividing through by the seasonal component. Within each year, the seasonal component will sum up to approximately \(m\).
### Holt-Winters additive method
The component form for the additive method is:
\[\begin{align\*}
\hat{y}_{t+h|t} &= \ell_{t} + hb_{t} + s_{t+h-m(k+1)} \\
\ell_{t} &= \alpha(y_{t} - s_{t-m}) + (1 - \alpha)(\ell_{t-1} + b_{t-1})\\
b_{t} &= \beta^\*(\ell_{t} - \ell_{t-1}) + (1 - \beta^\*)b_{t-1}\\
s_{t} &= \gamma (y_{t}-\ell_{t-1}-b_{t-1}) + (1-\gamma)s_{t-m},
\end{align\*}\]
where \(k\) is the integer part of \((h-1)/m\), which ensures that the estimates of the seasonal indices used for forecasting come from the final year of the sample. The level equation shows a weighted average between the seasonally adjusted observation \((y_{t} - s_{t-m})\) and the non-seasonal forecast \((\ell_{t-1}+b_{t-1})\) for time \(t\). The trend equation is identical to Holts linear method. The seasonal equation shows a weighted average between the current seasonal index, \((y_{t}-\ell_{t-1}-b_{t-1})\), and the seasonal index of the same season last year (i.e., \(m\) time periods ago).
The equation for the seasonal component is often expressed as
\[
s_{t} = \gamma^\* (y_{t}-\ell_{t})+ (1-\gamma^\*)s_{t-m}.
\]
If we substitute \(\ell_t\) from the smoothing equation for the level of the component form above, we get
\[
s_{t} = \gamma^\*(1-\alpha) (y_{t}-\ell_{t-1}-b_{t-1})+ [1-\gamma^\*(1-\alpha)]s_{t-m},
\]
which is identical to the smoothing equation for the seasonal component we specify here, with \(\gamma=\gamma^\*(1-\alpha)\). The usual parameter restriction is \(0\le\gamma^\*\le1\), which translates to \(0\le\gamma\le 1-\alpha\).
### Holt-Winters multiplicative method
The component form for the multiplicative method is:
\[\begin{align\*}
\hat{y}_{t+h|t} &= (\ell_{t} + hb_{t})s_{t+h-m(k+1)} \\
\ell_{t} &= \alpha \frac{y_{t}}{s_{t-m}} + (1 - \alpha)(\ell_{t-1} + b_{t-1})\\
b_{t} &= \beta^\*(\ell_{t}-\ell_{t-1}) + (1 - \beta^\*)b_{t-1} \\
s_{t} &= \gamma \frac{y_{t}}{(\ell_{t-1} + b_{t-1})} + (1 - \gamma)s_{t-m}.
\end{align\*}\]
### Example: Domestic overnight trips in Australia
We apply Holt-Winters method with both additive and multiplicative seasonality[17](#fn17) to forecast quarterly visitor nights in Australia spent by domestic tourists. Figure [8.7](https://otexts.com/fpp3/holt-winters.html#fig:7-HW) shows the data from 19982017, and the forecasts for 20182020. The data show an obvious seasonal pattern, with peaks observed in the March quarter of each year, corresponding to the Australian summer.
```
aus_holidays <- tourism |>
filter(Purpose == "Holiday") |>
summarise(Trips = sum(Trips)/1e3)
fit <- aus_holidays |>
model(
additive = ETS(Trips ~ error("A") + trend("A") +
season("A")),
multiplicative = ETS(Trips ~ error("M") + trend("A") +
season("M"))
)
fc <- fit |> forecast(h = "3 years")
fc |>
autoplot(aus_holidays, level = NULL) +
labs(title="Australian domestic tourism",
y="Overnight trips (millions)") +
guides(colour = guide_legend(title = "Forecast"))
```
![Forecasting domestic overnight trips in Australia using the Holt-Winters method with both additive and multiplicative seasonality.](https://otexts.com/fpp3/fpp_files/figure-html/7-HW-1.png)
Figure 8.7: Forecasting domestic overnight trips in Australia using the Holt-Winters method with both additive and multiplicative seasonality.
Table 8.3: Applying Holt-Winters method with additive seasonality for forecasting domestic tourism in Australia. Notice that the additive seasonal component sums to approximately zero. The smoothing parameters are \(\alpha = 0.2620\), \(\beta^\* = 0.1646\), \(\gamma = 0.0001\) and RMSE \(=0.4169\).
| Quarter | Time | Observation | Level | Slope | Season | Forecast |
| --- | --- | --- | --- | --- | --- | --- |
| | \(t\) | \(y_t\) | \(\ell_t\) | \(b_t\) | \(s_t\) | \(\hat{y}_{t+1\vert t}\) |
| 1997 Q1 | 0 | | | | 1.5 | |
| 1997 Q2 | 1 | | | | -0.3 | |
| 1997 Q3 | 2 | | | | -0.7 | |
| 1997 Q4 | 3 | | 9.8 | 0.0 | -0.5 | |
| 1998 Q1 | 4 | 11.8 | 9.9 | 0.0 | 1.5 | 11.3 |
| 1998 Q2 | 5 | 9.3 | 9.9 | 0.0 | -0.3 | 9.7 |
| 1998 Q3 | 6 | 8.6 | 9.7 | -0.0 | -0.7 | 9.2 |
| 1998 Q4 | 7 | 9.3 | 9.8 | 0.0 | -0.5 | 9.2 |
| | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 2017 Q1 | 80 | 12.4 | 10.9 | 0.1 | 1.5 | 12.3 |
| 2017 Q2 | 81 | 10.5 | 10.9 | 0.1 | -0.3 | 10.7 |
| 2017 Q3 | 82 | 10.5 | 11.0 | 0.1 | -0.7 | 10.3 |
| 2017 Q4 | 83 | 11.2 | 11.3 | 0.1 | -0.5 | 10.6 |
| | \(h\) | | | | | \(\hat{y}_{T+h\vert T}\) |
| 2018 Q1 | 1 | | | | | 12.9 |
| 2018 Q2 | 2 | | | | | 11.2 |
| 2018 Q3 | 3 | | | | | 11.0 |
| 2018 Q4 | 4 | | | | | 11.2 |
| 2019 Q1 | 5 | | | | | 13.4 |
| 2019 Q2 | 6 | | | | | 11.7 |
| 2019 Q3 | 7 | | | | | 11.5 |
| 2019 Q4 | 8 | | | | | 11.7 |
| 2020 Q1 | 9 | | | | | 13.9 |
| 2020 Q2 | 10 | | | | | 12.2 |
| 2020 Q3 | 11 | | | | | 11.9 |
| 2020 Q4 | 12 | | | | | 12.2 |
Table 8.4: Applying Holt-Winters method with multiplicative seasonality for forecasting domestic tourism in Australia. Notice that the multiplicative seasonal component sums to approximately \(m=4\). The smoothing parameters are \(\alpha = 0.2237\), \(\beta^\* = 0.1360\), \(\gamma = 0.0001\) and RMSE \(=0.4122\).
| Quarter | Time | Observation | Level | Slope | Season | Forecast |
| --- | --- | --- | --- | --- | --- | --- |
| | \(t\) | \(y_t\) | \(\ell_t\) | \(b_t\) | \(s_t\) | \(\hat{y}_{t+1\vert t}\) |
| 1997 Q1 | 0 | | | | 1.2 | |
| 1997 Q2 | 1 | | | | 1.0 | |
| 1997 Q3 | 2 | | | | 0.9 | |
| 1997 Q4 | 3 | | 10.0 | -0.0 | 0.9 | |
| 1998 Q1 | 4 | 11.8 | 10.0 | -0.0 | 1.2 | 11.6 |
| 1998 Q2 | 5 | 9.3 | 9.9 | -0.0 | 1.0 | 9.7 |
| 1998 Q3 | 6 | 8.6 | 9.8 | -0.0 | 0.9 | 9.2 |
| 1998 Q4 | 7 | 9.3 | 9.8 | -0.0 | 0.9 | 9.2 |
| | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 2017 Q1 | 80 | 12.4 | 10.8 | 0.1 | 1.2 | 12.6 |
| 2017 Q2 | 81 | 10.5 | 10.9 | 0.1 | 1.0 | 10.6 |
| 2017 Q3 | 82 | 10.5 | 11.1 | 0.1 | 0.9 | 10.2 |
| 2017 Q4 | 83 | 11.2 | 11.3 | 0.1 | 0.9 | 10.5 |
| | \(h\) | | | | | \(\hat{y}_{T+h\vert T}\) |
| 2018 Q1 | 1 | | | | | 13.3 |
| 2018 Q2 | 2 | | | | | 11.2 |
| 2018 Q3 | 3 | | | | | 10.8 |
| 2018 Q4 | 4 | | | | | 11.1 |
| 2019 Q1 | 5 | | | | | 13.8 |
| 2019 Q2 | 6 | | | | | 11.7 |
| 2019 Q3 | 7 | | | | | 11.3 |
| 2019 Q4 | 8 | | | | | 11.6 |
| 2020 Q1 | 9 | | | | | 14.4 |
| 2020 Q2 | 10 | | | | | 12.2 |
| 2020 Q3 | 11 | | | | | 11.7 |
| 2020 Q4 | 12 | | | | | 12.1 |
The applications of both methods (with additive and multiplicative seasonality) are presented in Tables [8.3](https://otexts.com/fpp3/holt-winters.html#tab:tab75) and [8.4](https://otexts.com/fpp3/holt-winters.html#tab:tab76) respectively. Because both methods have exactly the same number of parameters to estimate, we can compare the training RMSE from both models. In this case, the method with multiplicative seasonality fits the data slightly better.
The estimated components for both models are plotted in Figure [8.8](https://otexts.com/fpp3/holt-winters.html#fig:fig-7-LevelTrendSeas). The small value of \(\gamma\) for the multiplicative model means that the seasonal component hardly changes over time. The small value of \(\beta^{\*}\) means the slope component hardly changes over time (compare the vertical scales of the slope and level components).
![Estimated components for the Holt-Winters method with additive and multiplicative seasonal components.](https://otexts.com/fpp3/fpp_files/figure-html/fig-7-LevelTrendSeas-1.png)
Figure 8.8: Estimated components for the Holt-Winters method with additive and multiplicative seasonal components.
### Holt-Winters damped method
Damping is possible with both additive and multiplicative Holt-Winters methods. A method that often provides accurate and robust forecasts for seasonal data is the Holt-Winters method with a damped trend and multiplicative seasonality:
\[\begin{align\*}
\hat{y}_{t+h|t} &= \left[\ell_{t} + (\phi+\phi^2 + \dots + \phi^{h})b_{t}\right]s_{t+h-m(k+1)} \\
\ell_{t} &= \alpha(y_{t} / s_{t-m}) + (1 - \alpha)(\ell_{t-1} + \phi b_{t-1})\\
b_{t} &= \beta^\*(\ell_{t} - \ell_{t-1}) + (1 - \beta^\*)\phi b_{t-1} \\
s_{t} &= \gamma \frac{y_{t}}{(\ell_{t-1} + \phi b_{t-1})} + (1 - \gamma)s_{t-m}.
\end{align\*}\]
### Example: Holt-Winters method with daily data
The Holt-Winters method can also be used for daily type of data, where the seasonal period is \(m=7\), and the appropriate unit of time for \(h\) is in days. Here we forecast pedestrian traffic at a busy Melbourne train station in July 2016.
```
sth_cross_ped <- pedestrian |>
filter(Date >= "2016-07-01",
Sensor == "Southern Cross Station") |>
index_by(Date) |>
summarise(Count = sum(Count)/1000)
sth_cross_ped |>
filter(Date <= "2016-07-31") |>
model(
hw = ETS(Count ~ error("M") + trend("Ad") + season("M"))
) |>
forecast(h = "2 weeks") |>
autoplot(sth_cross_ped |> filter(Date <= "2016-08-14")) +
labs(title = "Daily traffic: Southern Cross",
y="Pedestrians ('000)")
```
![Forecasts of daily pedestrian traffic at the Southern Cross railway station, Melbourne.](https://otexts.com/fpp3/fpp_files/figure-html/hyndsight-1.png)
Figure 8.9: Forecasts of daily pedestrian traffic at the Southern Cross railway station, Melbourne.
Clearly the model has identified the weekly seasonal pattern and the increasing trend at the end of the data, and the forecasts are a close match to the test data.
### Bibliography
Holt, C. C. (1957). *Forecasting seasonals and trends by exponentially weighted averages* (ONR Memorandum No. 52). Carnegie Institute of Technology, Pittsburgh USA. Reprinted in the *International Journal of Forecasting*, 2004.
Winters, P. R. (1960). Forecasting sales by exponentially weighted moving averages. *Management Science*, *6*(3), 324342.
---
17. Our implementation uses maximum likelihood estimation as described in Section [8.6](https://otexts.com/fpp3/ets-estimation.html#ets-estimation) while Holt and Winters originally minimized the sum of squared errors. For multiplicative seasonality, this will lead to slightly different parameter estimates. Optimizing the sum of squared errors can be obtained by setting `opt_crit="mse"` in `ETS()`.[↩︎](https://otexts.com/fpp3/holt-winters.html#fnref17)
## 8.4 A taxonomy of exponential smoothing methods
Exponential smoothing methods are not restricted to those we have presented so far. By considering variations in the combinations of the trend and seasonal components, nine exponential smoothing methods are possible, listed in Table [8.5](https://otexts.com/fpp3/taxonomy.html#tab:taxonomy). Each method is labelled by a pair of letters (T,S) defining the type of Trend and Seasonal components. For example, (A,M) is the method with an additive trend and multiplicative seasonality; (A\(_d\),N) is the method with damped trend and no seasonality; and so on.
Table 8.5: A two-way classification of exponential smoothing methods.
| Trend Component | Seasonal Component | | |
| --- | --- | --- | --- |
| | N | A | M |
| | (None) | (Additive) | (Multiplicative) |
| N (None) | (N,N) | (N,A) | (N,M) |
| A (Additive) | (A,N) | (A,A) | (A,M) |
| A\(_d\) (Additive damped) | (A\(_d\),N) | (A\(_d\),A) | (A\(_d\),M) |
Some of these methods we have already seen using other names:
| Short hand | Method |
| --- | --- |
| (N,N) | Simple exponential smoothing |
| (A,N) | Holts linear method |
| (A\(_d\),N) | Additive damped trend method |
| (A,A) | Additive Holt-Winters method |
| (A,M) | Multiplicative Holt-Winters method |
| (A\(_d\),M) | Holt-Winters damped method |
This type of classification was first proposed by Pegels ([1969](#ref-Pegels1969)), who also included a method with a multiplicative trend. It was later extended by Gardner ([1985](#ref-Gar1985)) to include methods with an additive damped trend and by J. W. Taylor ([2003](#ref-Taylor2003)) to include methods with a multiplicative damped trend. We do not consider the multiplicative trend methods in this book as they tend to produce poor forecasts. See Hyndman et al. ([2008](#ref-expsmooth08)) for a more thorough discussion of all exponential smoothing methods.
Table [8.6](https://otexts.com/fpp3/taxonomy.html#tab:pegels) gives the recursive formulas for applying the nine exponential smoothing methods in Table [8.5](https://otexts.com/fpp3/taxonomy.html#tab:taxonomy). Each cell includes the forecast equation for generating \(h\)-step-ahead forecasts, and the smoothing equations for applying the method.
Table 8.6: Formulas for recursive calculations and point forecasts. In each case, \(\ell_t\) denotes the series level at time \(t\), \(b_t\) denotes the slope at time \(t\), \(s_t\) denotes the seasonal component of the series at time \(t\), and \(m\) denotes the number of seasons in a year; \(\alpha\), \(\beta^\*\), \(\gamma\) and \(\phi\) are smoothing parameters, \(\phi_h = \phi+\phi^2+\dots+\phi^{h}\), and \(k\) is the integer part of \((h-1)/m\).
| |
| --- |
| ![](https://otexts.com/fpp3/figs/pegelstable-1.png) |
### Bibliography
Gardner, E. S. (1985). Exponential smoothing: The state of the art. *Journal of Forecasting*, *4*(1), 128.
Hyndman, R. J., Koehler, A. B., Ord, J. K., & Snyder, R. D. (2008). *Forecasting with exponential smoothing: The state space approach*. Springer-Verlag.
Pegels, C. C. (1969). Exponential forecasting: Some new variations. *Management Science*, *15*(5), 311315.
Taylor, J. W. (2003). Exponential smoothing with a damped multiplicative trend. *International Journal of Forecasting*, *19*(4), 715725.
## 8.5 Innovations state space models for exponential smoothing
In the rest of this chapter, we study the statistical models that underlie the exponential smoothing methods we have considered so far. The exponential smoothing methods presented in Table [8.6](https://otexts.com/fpp3/taxonomy.html#tab:pegels) are algorithms which generate point forecasts. The statistical models in this section generate the same point forecasts, but can also generate prediction (or forecast) intervals. A statistical model is a stochastic (or random) data generating process that can produce an entire forecast distribution. We will also describe how to use the model selection criteria introduced in Chapter [7](https://otexts.com/fpp3/regression.html#regression) to choose the model in an objective manner.
Each model consists of a measurement equation that describes the observed data, and some state equations that describe how the unobserved components or states (level, trend, seasonal) change over time. Hence, these are referred to as **state space models**.
For each method there exist two models: one with additive errors and one with multiplicative errors. The point forecasts produced by the models are identical if they use the same smoothing parameter values. They will, however, generate different prediction intervals.
To distinguish between a model with additive errors and one with multiplicative errors (and also to distinguish the models from the methods), we add a third letter to the classification of Table [8.5](https://otexts.com/fpp3/taxonomy.html#tab:taxonomy). We label each state space model as ETS(\(\cdot,\cdot,\cdot\)) for (Error, Trend, Seasonal). This label can also be thought of as ExponenTial Smoothing. Using the same notation as in Table [8.5](https://otexts.com/fpp3/taxonomy.html#tab:taxonomy), the possibilities for each component (or state) are: Error \(=\{\)A,M\(\}\), Trend \(=\{\)N,A,A\(_d\}\) and Seasonal \(=\{\)N,A,M\(\}\).
### ETS(A,N,N): simple exponential smoothing with additive errors
Recall the component form of simple exponential smoothing:
\[\begin{align\*}
\text{Forecast equation} && \hat{y}_{t+1|t} & = \ell_{t}\\
\text{Smoothing equation} && \ell_{t} & = \alpha y_{t} + (1 - \alpha)\ell_{t-1}.
\end{align\*}\]
If we re-arrange the smoothing equation for the level, we get the “error correction” form,
\[\begin{align\*}
\ell_{t} %&= \alpha y_{t}+\ell_{t-1}-\alpha\ell_{t-1}\\
&= \ell_{t-1}+\alpha( y_{t}-\ell_{t-1})\\
&= \ell_{t-1}+\alpha e_{t},
\end{align\*}\]
where \(e_{t}=y_{t}-\ell_{t-1}=y_{t}-\hat{y}_{t|t-1}\) is the residual at time \(t\).
The training data errors lead to the adjustment of the estimated level throughout the smoothing process for \(t=1,\dots,T\). For example, if the error at time \(t\) is negative, then \(y_t < \hat{y}_{t|t-1}\) and so the level at time \(t-1\) has been over-estimated. The new level \(\ell_t\) is then the previous level \(\ell_{t-1}\) adjusted downwards. The closer \(\alpha\) is to one, the “rougher” the estimate of the level (large adjustments take place). The smaller the \(\alpha\), the “smoother” the level (small adjustments take place).
We can also write \(y_t = \ell_{t-1} + e_t\), so that each observation can be represented by the previous level plus an error. To make this into an innovations state space model, all we need to do is specify the probability distribution for \(e_t\). For a model with additive errors, we assume that residuals (the one-step training errors) \(e_t\) are normally distributed white noise with mean 0 and variance \(\sigma^2\). A short-hand notation for this is \(e_t = \varepsilon_t\sim\text{NID}(0,\sigma^2)\); NID stands for “normally and independently distributed”.
Then the equations of the model can be written as
\[\begin{align}
y_t &= \ell_{t-1} + \varepsilon_t \tag{8.3}\\
\ell_t&=\ell_{t-1}+\alpha \varepsilon_t. \tag{8.4}
\end{align}\]
We refer to [(8.3)](https://otexts.com/fpp3/ets.html#eq:ann-1a) as the *measurement* (or observation) equation and [(8.4)](https://otexts.com/fpp3/ets.html#eq:ann-2a) as the *state* (or transition) equation. These two equations, together with the statistical distribution of the errors, form a fully specified statistical model. Specifically, these constitute an innovations state space model underlying simple exponential smoothing.
The term “innovations” comes from the fact that all equations use the same random error process, \(\varepsilon_t\). For the same reason, this formulation is also referred to as a “single source of error” model. There are alternative multiple source of error formulations which we do not present here.
The measurement equation shows the relationship between the observations and the unobserved states. In this case, observation \(y_t\) is a linear function of the level \(\ell_{t-1}\), the predictable part of \(y_t\), and the error \(\varepsilon_t\), the unpredictable part of \(y_t\). For other innovations state space models, this relationship may be nonlinear.
The state equation shows the evolution of the state through time. The influence of the smoothing parameter \(\alpha\) is the same as for the methods discussed earlier. For example, \(\alpha\) governs the amount of change in successive levels: high values of \(\alpha\) allow rapid changes in the level; low values of \(\alpha\) lead to smooth changes. If \(\alpha=0\), the level of the series does not change over time; if \(\alpha=1\), the model reduces to a random walk model, \(y_t=y_{t-1}+\varepsilon_t\). (See Section [9.1](https://otexts.com/fpp3/stationarity.html#stationarity) for a discussion of this model.)
### ETS(M,N,N): simple exponential smoothing with multiplicative errors
In a similar fashion, we can specify models with multiplicative errors by writing the one-step-ahead training errors as relative errors
\[
\varepsilon_t = \frac{y_t-\hat{y}_{t|t-1}}{\hat{y}_{t|t-1}}
\]
where \(\varepsilon_t \sim \text{NID}(0,\sigma^2)\). Substituting \(\hat{y}_{t|t-1}=\ell_{t-1}\) gives \(y_t = \ell_{t-1}+\ell_{t-1}\varepsilon_t\) and \(e_t = y_t - \hat{y}_{t|t-1} = \ell_{t-1}\varepsilon_t\).
Then we can write the multiplicative form of the state space model as
\[\begin{align\*}
y_t&=\ell_{t-1}(1+\varepsilon_t)\\
\ell_t&=\ell_{t-1}(1+\alpha \varepsilon_t).
\end{align\*}\]
### ETS(A,A,N): Holts linear method with additive errors
For this model, we assume that the one-step-ahead training errors are given by \(\varepsilon_t=y_t-\ell_{t-1}-b_{t-1} \sim \text{NID}(0,\sigma^2)\). Substituting this into the error correction equations for Holts linear method we obtain
\[\begin{align\*}
y_t&=\ell_{t-1}+b_{t-1}+\varepsilon_t\\
\ell_t&=\ell_{t-1}+b_{t-1}+\alpha \varepsilon_t\\
b_t&=b_{t-1}+\beta \varepsilon_t,
\end{align\*}\]
where for simplicity we have set \(\beta=\alpha \beta^\*\).
### ETS(M,A,N): Holts linear method with multiplicative errors
Specifying one-step-ahead training errors as relative errors such that
\[
\varepsilon_t=\frac{y_t-(\ell_{t-1}+b_{t-1})}{(\ell_{t-1}+b_{t-1})}
\]
and following an approach similar to that used above, the innovations state space model underlying Holts linear method with multiplicative errors is specified as
\[\begin{align\*}
y_t&=(\ell_{t-1}+b_{t-1})(1+\varepsilon_t)\\
\ell_t&=(\ell_{t-1}+b_{t-1})(1+\alpha \varepsilon_t)\\
b_t&=b_{t-1}+\beta(\ell_{t-1}+b_{t-1}) \varepsilon_t,
\end{align\*}\]
where again \(\beta=\alpha \beta^\*\) and \(\varepsilon_t \sim \text{NID}(0,\sigma^2)\).
### Other ETS models
In a similar fashion, we can write an innovations state space model for each of the exponential smoothing methods of Table [8.6](https://otexts.com/fpp3/taxonomy.html#tab:pegels). Table [8.7](https://otexts.com/fpp3/ets.html#tab:ssm) presents the equations for all of the models in the ETS framework.
Table 8.7: State space equations for each of the models in the ETS framework.
| |
| --- |
| ![](https://otexts.com/fpp3/figs/statespacemodels-1.png) |
## 8.6 Estimation and model selection
### Estimating ETS models
An alternative to estimating the parameters by minimising the sum of squared errors is to maximise the “likelihood”. The likelihood is the probability of the data arising from the specified model. Thus, a large likelihood is associated with a good model. For an additive error model, maximising the likelihood (assuming normally distributed errors) gives the same results as minimising the sum of squared errors. However, different results will be obtained for multiplicative error models. In this section, we will estimate the smoothing parameters \(\alpha\), \(\beta\), \(\gamma\) and \(\phi\), and the initial states \(\ell_0\), \(b_0\), \(s_0,s_{-1},\dots,s_{-m+1}\), by maximising the likelihood.
The possible values that the smoothing parameters can take are restricted. Traditionally, the parameters have been constrained to lie between 0 and 1 so that the equations can be interpreted as weighted averages. That is, \(0< \alpha,\beta^\*,\gamma^\*,\phi<1\). For the state space models, we have set \(\beta=\alpha\beta^\*\) and \(\gamma=(1-\alpha)\gamma^\*\). Therefore, the traditional restrictions translate to \(0< \alpha <1\), \(0 < \beta < \alpha\) and \(0< \gamma < 1-\alpha\). In practice, the damping parameter \(\phi\) is usually constrained further to prevent numerical difficulties in estimating the model. In the `fable` package, it is restricted so that \(0.8<\phi<0.98\).
Another way to view the parameters is through a consideration of the mathematical properties of the state space models. The parameters are constrained in order to prevent observations in the distant past having a continuing effect on current forecasts. This leads to some *admissibility* constraints on the parameters, which are usually (but not always) less restrictive than the traditional constraints region ([Hyndman et al., 2008, pp. 149161](#ref-expsmooth08)). For example, for the ETS(A,N,N) model, the traditional parameter region is \(0< \alpha <1\) but the admissible region is \(0< \alpha <2\). For the ETS(A,A,N) model, the traditional parameter region is \(0<\alpha<1\) and \(0<\beta<\alpha\) but the admissible region is \(0<\alpha<2\) and \(0<\beta<4-2\alpha\).
### Model selection
A great advantage of the ETS statistical framework is that information criteria can be used for model selection. The AIC, AIC\(_{\text{c}}\) and BIC, introduced in Section [7.5](https://otexts.com/fpp3/selecting-predictors.html#selecting-predictors), can be used here to determine which of the ETS models is most appropriate for a given time series.
For ETS models, Akaikes Information Criterion (AIC) is defined as
\[
\text{AIC} = -2\log(L) + 2k,
\]
where \(L\) is the likelihood of the model and \(k\) is the total number of parameters and initial states that have been estimated (including the residual variance).
The AIC corrected for small sample bias (AIC\(_\text{c}\)) is defined as
\[
\text{AIC}_{\text{c}} = \text{AIC} + \frac{2k(k+1)}{T-k-1},
\]
and the Bayesian Information Criterion (BIC) is
\[
\text{BIC} = \text{AIC} + k[\log(T)-2].
\]
Three of the combinations of (Error, Trend, Seasonal) can lead to numerical difficulties. Specifically, the models that can cause such instabilities are ETS(A,N,M), ETS(A,A,M), and ETS(A,A\(_d\),M), due to division by values potentially close to zero in the state equations. We normally do not consider these particular combinations when selecting a model.
Models with multiplicative errors are useful when the data are strictly positive, but are not numerically stable when the data contain zeros or negative values. Therefore, multiplicative error models will not be considered if the time series is not strictly positive. In that case, only the six fully additive models will be applied.
### Example: Domestic holiday tourist visitor nights in Australia
We now employ the ETS statistical framework to forecast Australian holiday tourism over the period 20162019. We let the `ETS()` function select the model by minimising the AICc.
```
aus_holidays <- tourism |>
filter(Purpose == "Holiday") |>
summarise(Trips = sum(Trips)/1e3)
fit <- aus_holidays |>
model(ETS(Trips))
report(fit)
#> Series: Trips
#> Model: ETS(M,N,A)
#> Smoothing parameters:
#> alpha = 0.3484
#> gamma = 1e-04
#>
#> Initial states:
#> l[0] s[0] s[-1] s[-2] s[-3]
#> 9.727 -0.5376 -0.6884 -0.2934 1.519
#>
#> sigma^2: 0.0022
#>
#> AIC AICc BIC
#> 226.2 227.8 242.9
```
The model selected is ETS(M,N,A)
\[\begin{align\*}
y_{t} &= (\ell_{t-1}+s_{t-m})(1 + \varepsilon_t)\\
\ell_t &= \ell_{t-1} + \alpha(\ell_{t-1}+s_{t-m})\varepsilon_t\\
s_t &= s_{t-m} + \gamma(\ell_{t-1}+s_{t-m}) \varepsilon_t.
\end{align\*}\]
The parameter estimates are \(\hat\alpha= 0.3484\), and \(\hat\gamma=0.0001\). The output also returns the estimates for the initial states \(\ell_0\), \(s_{0}\), \(s_{-1}\), \(s_{-2}\) and \(s_{-3}.\) Compare these with the values obtained for the Holt-Winters method with additive seasonality presented in Table [8.3](https://otexts.com/fpp3/holt-winters.html#tab:tab75).
Figure [8.10](https://otexts.com/fpp3/ets-estimation.html#fig:MNAstates) shows the states over time, while Figure [8.12](https://otexts.com/fpp3/ets-forecasting.html#fig:MNAforecasts) shows point forecasts and prediction intervals generated from the model. The small values of \(\gamma\) indicate that the seasonal states change very little over time.
```
components(fit) |>
autoplot() +
labs(title = "ETS(M,N,A) components")
```
![Graphical representation of the estimated states over time.](https://otexts.com/fpp3/fpp_files/figure-html/MNAstates-1.png)
Figure 8.10: Graphical representation of the estimated states over time.
Because this model has multiplicative errors, the innovation residuals are not equivalent to the regular residuals (i.e., the one-step training errors). The innovation residuals are given by \(\hat{\varepsilon}_t\), while the regular residuals are defined as \(y_t - \hat{y}_{t|t-1}\). We can obtain both using the `augment()` function. They are plotted in Figure [8.11](https://otexts.com/fpp3/ets-estimation.html#fig:MNAresiduals).
![Residuals and one-step forecast errors from the ETS(M,N,A) model.](https://otexts.com/fpp3/fpp_files/figure-html/MNAresiduals-1.png)
Figure 8.11: Residuals and one-step forecast errors from the ETS(M,N,A) model.
### Bibliography
Hyndman, R. J., Koehler, A. B., Ord, J. K., & Snyder, R. D. (2008). *Forecasting with exponential smoothing: The state space approach*. Springer-Verlag.
## 8.7 Forecasting with ETS models
Point forecasts can be obtained from the models by iterating the equations for \(t=T+1,\dots,T+h\) and setting all \(\varepsilon_t=0\) for \(t>T\).
For example, for model ETS(M,A,N), \(y_{T+1} = (\ell_T + b_T )(1+ \varepsilon_{T+1}).\) Therefore \(\hat{y}_{T+1|T}=\ell_{T}+b_{T}.\) Similarly,
\[\begin{align\*}
y_{T+2} &= (\ell_{T+1} + b_{T+1})(1 + \varepsilon_{T+2})\\
&= \left[
(\ell_T + b_T) (1+ \alpha\varepsilon_{T+1}) +
b_T + \beta (\ell_T + b_T)\varepsilon_{T+1}
\right]
(1 + \varepsilon_{T+2}).
\end{align\*}\]
Therefore, \(\hat{y}_{T+2|T}= \ell_{T}+2b_{T},\) and so on. These forecasts are identical to the forecasts from Holts linear method, and also to those from model ETS(A,A,N). Thus, the point forecasts obtained from the method and from the two models that underlie the method are identical (assuming that the same parameter values are used). ETS point forecasts constructed in this way are equal to the means of the forecast distributions, except for the models with multiplicative seasonality ([Hyndman et al., 2008](#ref-expsmooth08)).
To obtain forecasts from an ETS model, we use the `forecast()` function from the `fable` package. This function will always return the means of the forecast distribution, even when they differ from these traditional point forecasts.
```
fit |>
forecast(h = 8) |>
autoplot(aus_holidays)+
labs(title="Australian domestic tourism",
y="Overnight trips (millions)")
```
![Forecasting Australian domestic overnight trips using an ETS(M,N,A) model.](https://otexts.com/fpp3/fpp_files/figure-html/MNAforecasts-1.png)
Figure 8.12: Forecasting Australian domestic overnight trips using an ETS(M,N,A) model.
### Prediction intervals
A big advantage of the statistical models is that prediction intervals can also be generated — something that cannot be done using the point forecasting methods alone. The prediction intervals will differ between models with additive and multiplicative methods.
For most ETS models, a prediction interval can be written as
\[
\hat{y}_{T+h|T} \pm c \sigma_h
\]
where \(c\) depends on the coverage probability, and \(\sigma_h^2\) is the forecast variance. Values for \(c\) were given in Table [5.1](https://otexts.com/fpp3/prediction-intervals.html#tab:pcmultipliers). For ETS models, formulas for \(\sigma_h^2\) can be complicated; the details are given in Chapter 6 of Hyndman et al. ([2008](#ref-expsmooth08)). In Table [8.8](https://otexts.com/fpp3/ets-forecasting.html#tab:pitable) we give the formulas for the additive ETS models, which are the simplest.
Table 8.8: Forecast variance expressions for each additive state space model, where \(\sigma^2\) is the residual variance, \(m\) is the seasonal period, and \(k\) is the integer part of \((h-1) /m\) (i.e., the number of complete years in the forecast period prior to time \(T+h\)).
| Model | Forecast variance: \(\sigma_h^2\) |
| --- | --- |
| (A,N,N) | \(\sigma_h^2 = \sigma^2\big[1 + \alpha^2(h-1)\big]\) |
| (A,A,N) | \(\sigma_h^2 = \sigma^2\Big[1 + (h-1)\big\{\alpha^2 + \alpha\beta h + \frac16\beta^2h(2h-1)\big\}\Big]\) |
| (A,A\(_d\),N) | \(\sigma_h^2 = \sigma^2\biggl[1 + \alpha^2(h-1) + \frac{\beta\phi h}{(1-\phi)^2} \left\{2\alpha(1-\phi) +\beta\phi\right\}\) |
| | \(\mbox{} - \frac{\beta\phi(1-\phi^h)}{(1-\phi)^2(1-\phi^2)} \left\{ 2\alpha(1-\phi^2)+ \beta\phi(1+2\phi-\phi^h)\right\}\biggr]\) |
| (A,N,A) | \(\sigma_h^2 = \sigma^2\Big[1 + \alpha^2(h-1) + \gamma k(2\alpha+\gamma)\Big]\) |
| (A,A,A) | \(\sigma_h^2 = \sigma^2\Big[1 + (h-1)\big\{\alpha^2 + \alpha\beta h + \frac16\beta^2h(2h-1)\big\}\) |
| | \(\mbox{} + \gamma k \big\{2\alpha+ \gamma + \beta m (k+1)\big\} \Big]\) |
| (A,A\(_d\),A) | \(\sigma_h^2 = \sigma^2\biggl[1 + \alpha^2(h-1) + \gamma k(2\alpha+\gamma)\) |
| | \(\mbox{} +\frac{\beta\phi h}{(1-\phi)^2} \left\{2\alpha(1-\phi) + \beta\phi \right\}\) |
| | \(\mbox{} - \frac{\beta\phi(1-\phi^h)}{(1-\phi)^2(1-\phi^2)} \left\{ 2\alpha(1-\phi^2)+ \beta\phi(1+2\phi-\phi^h)\right\}\) |
| | \(\mbox{} + \frac{2\beta\gamma\phi}{(1-\phi)(1-\phi^m)}\left\{k(1-\phi^m) - \phi^m(1-\phi^{mk})\right\}\biggr]\) |
For a few ETS models, there are no known formulas for prediction intervals. In these cases, the `forecast()` function uses simulated future sample paths and computes prediction intervals from the percentiles of these simulated future paths.
### Bibliography
Hyndman, R. J., Koehler, A. B., Ord, J. K., & Snyder, R. D. (2008). *Forecasting with exponential smoothing: The state space approach*. Springer-Verlag.
## 8.8 Exercises
1. Consider the number of pigs slaughtered in Victoria, available in the `aus_livestock` dataset.
1. Use the `ETS()` function to estimate the equivalent model for simple exponential smoothing. Find the optimal values of \(\alpha\) and \(\ell_0\), and generate forecasts for the next four months.
2. Compute a 95% prediction interval for the first forecast using \(\hat{y} \pm 1.96s\) where \(s\) is the standard deviation of the residuals. Compare your interval with the interval produced by R.
2. Write your own function to implement simple exponential smoothing. The function should take arguments `y` (the time series), `alpha` (the smoothing parameter \(\alpha\)) and `level` (the initial level \(\ell_0\)). It should return the forecast of the next observation in the series. Does it give the same forecast as `ETS()`?
3. Modify your function from the previous exercise to return the sum of squared errors rather than the forecast of the next observation. Then use the `optim()` function to find the optimal values of \(\alpha\) and \(\ell_0\). Do you get the same values as the `ETS()` function?
4. Combine your previous two functions to produce a function that both finds the optimal values of \(\alpha\) and \(\ell_0\), and produces a forecast of the next observation in the series.
5. Data set `global_economy` contains the annual Exports from many countries. Select one country to analyse.
1. Plot the Exports series and discuss the main features of the data.
2. Use an ETS(A,N,N) model to forecast the series, and plot the forecasts.
3. Compute the RMSE values for the training data.
4. Compare the results to those from an ETS(A,A,N) model. (Remember that the trended model is using one more parameter than the simpler model.) Discuss the merits of the two forecasting methods for this data set.
5. Compare the forecasts from both methods. Which do you think is best?
6. Calculate a 95% prediction interval for the first forecast for each model, using the RMSE values and assuming normal errors. Compare your intervals with those produced using R.
6. Forecast the Chinese GDP from the `global_economy` data set using an ETS model. Experiment with the various options in the `ETS()` function to see how much the forecasts change with damped trend, or with a Box-Cox transformation. Try to develop an intuition of what each is doing to the forecasts.
[Hint: use a relatively large value of `h` when forecasting, so you can clearly see the differences between the various options when plotting the forecasts.]
7. Find an ETS model for the Gas data from `aus_production` and forecast the next few years. Why is multiplicative seasonality necessary here? Experiment with making the trend damped. Does it improve the forecasts?
8. Recall your retail time series data (from Exercise 7 in Section [2.10](https://otexts.com/fpp3/graphics-exercises.html#graphics-exercises)).
1. Why is multiplicative seasonality necessary for this series?
2. Apply Holt-Winters multiplicative method to the data. Experiment with making the trend damped.
3. Compare the RMSE of the one-step forecasts from the two methods. Which do you prefer?
4. Check that the residuals from the best method look like white noise.
5. Now find the test set RMSE, while training the model to the end of 2010. Can you beat the seasonal naïve approach from Exercise 7 in Section [5.11](https://otexts.com/fpp3/toolbox-exercises.html#toolbox-exercises)?
9. For the same retail data, try an STL decomposition applied to the Box-Cox transformed series, followed by ETS on the seasonally adjusted data. How does that compare with your best previous forecasts on the test set?
10. Compute the total domestic overnight trips across Australia from the `tourism` dataset.
1. Plot the data and describe the main features of the series.
2. Decompose the series using STL and obtain the seasonally adjusted data.
3. Forecast the next two years of the series using an additive damped trend method applied to the seasonally adjusted data. (This can be specified using `decomposition_model()`.)
4. Forecast the next two years of the series using an appropriate model for Holts linear method applied to the seasonally adjusted data (as before but without damped trend).
5. Now use `ETS()` to choose a seasonal model for the data.
6. Compare the RMSE of the ETS model with the RMSE of the models you obtained using STL decompositions. Which gives the better in-sample fits?
7. Compare the forecasts from the three approaches? Which seems most reasonable?
8. Check the residuals of your preferred model.
11. For this exercise use the quarterly number of arrivals to Australia from New Zealand, 1981 Q1 2012 Q3, from data set `aus_arrivals`.
1. Make a time plot of your data and describe the main features of the series.
2. Create a training set that withholds the last two years of available data. Forecast the test set using an appropriate model for Holt-Winters multiplicative method.
3. Why is multiplicative seasonality necessary here?
4. Forecast the two-year test set using each of the following methods:
* an ETS model;
* an additive ETS model applied to a log transformed series;
* a seasonal naïve method;
* an STL decomposition applied to the log transformed data followed by an ETS model applied to the seasonally adjusted (transformed) data.
5. Which method gives the best forecasts? Does it pass the residual tests?
6. Compare the same four methods using time series cross-validation instead of using a training and test set. Do you come to the same conclusions?
12. 1. Apply cross-validation techniques to produce 1 year ahead ETS and seasonal naïve forecasts for Portland cement production (from `aus_production`). Use a stretching data window with initial size of 5 years, and increment the window by one observation.
2. Compute the MSE of the resulting \(4\)-step-ahead errors. Comment on which forecasts are more accurate. Is this what you expected?
13. Compare `ETS()`, `SNAIVE()` and `decomposition_model(STL, ???)` on the following five time series. You might need to use a Box-Cox transformation for the STL decomposition forecasts. Use a test set of three years to decide what gives the best forecasts.
* Beer and bricks production from `aus_production`.
* Cost of drug subsidies for diabetes (`ATC2 == "A10"`) and corticosteroids (`ATC2 == "H02"`) from `PBS`.
* Total food retailing turnover for Australia from `aus_retail`.
14. 1. Use `ETS()` to select an appropriate model for the following series: total number of trips across Australia using `tourism`, the closing prices for the four stocks in `gafa_stock`, and the lynx series in `pelt`. Does it always give good forecasts?
2. Find an example where it does not work well. Can you figure out why?
15. Show that the point forecasts from an ETS(M,A,M) model are the same as those obtained using Holt-Winters multiplicative method.
16. Show that the forecast variance for an ETS(A,N,N) model is given by
\[
\sigma^2\left[1+\alpha^2(h-1)\right].
\]
17. Write down 95% prediction intervals for an ETS(A,N,N) model as a function of \(\ell_T\), \(\alpha\), \(h\) and \(\sigma\), assuming normally distributed errors.
## 8.9 Further reading
* Two articles by Ev Gardner ([Gardner, 1985](#ref-Gar1985), [2006](#ref-Gar2006)) provide a great overview of the history of exponential smoothing, and its many variations.
* A full book treatment of the subject providing the mathematical details is given by Hyndman et al. ([2008](#ref-expsmooth08)).
### Bibliography
Gardner, E. S. (1985). Exponential smoothing: The state of the art. *Journal of Forecasting*, *4*(1), 128.
Gardner, E. S. (2006). Exponential smoothing: The state of the art — Part II. *International Journal of Forecasting*, *22*, 637666.
Hyndman, R. J., Koehler, A. B., Ord, J. K., & Snyder, R. D. (2008). *Forecasting with exponential smoothing: The state space approach*. Springer-Verlag.
File diff suppressed because it is too large Load Diff
+651
View File
@@ -0,0 +1,651 @@
Source: https://otexts.com/fpp3/dynamic.html (chapter dynamic, 9 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 10-dynamic-regression
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 10 Dynamic regression models
The time series models in the previous two chapters allow for the inclusion of information from past observations of a series, but not for the inclusion of other information that may also be relevant. For example, the effects of holidays, competitor activity, changes in the law, the wider economy, or other external variables, may explain some of the historical variation and may lead to more accurate forecasts. On the other hand, the regression models in Chapter [7](https://otexts.com/fpp3/regression.html#regression) allow for the inclusion of a lot of relevant information from predictor variables, but do not allow for the subtle time series dynamics that can be handled with ARIMA models. In this chapter, we consider how to extend ARIMA models in order to allow other information to be included in the models.
In Chapter [7](https://otexts.com/fpp3/regression.html#regression) we considered regression models of the form
\[
y_t = \beta_0 + \beta_1 x_{1,t} + \dots + \beta_k x_{k,t} + \varepsilon_t,
\]
where \(y_t\) is a linear function of the \(k\) predictor variables (\(x_{1,t},\dots,x_{k,t}\)), and \(\varepsilon_t\) is usually assumed to be an uncorrelated error term (i.e., it is white noise). We considered tests such as the Ljung-Box test for assessing whether the resulting residuals were significantly correlated.
In this chapter, we will allow the errors from a regression to contain autocorrelation. To emphasise this change in perspective, we will replace \(\varepsilon_t\) with \(\eta_t\) in the equation. The error series \(\eta_t\) is assumed to follow an ARIMA model. For example, if \(\eta_t\) follows an ARIMA(1,1,1) model, we can write
\[\begin{align\*}
y_t &= \beta_0 + \beta_1 x_{1,t} + \dots + \beta_k x_{k,t} + \eta_t,\\
& (1-\phi_1B)(1-B)\eta_t = (1+\theta_1B)\varepsilon_t,
\end{align\*}\]
where \(\varepsilon_t\) is a white noise series.
Notice that the model has two error terms here — the error from the regression model, which we denote by \(\eta_t\), and the error from the ARIMA model, which we denote by \(\varepsilon_t\). Only the ARIMA model errors are assumed to be white noise.
## 10.1 Estimation
When we estimate the parameters from the model, we need to minimise the sum of squared \(\varepsilon_t\) values. If we minimise the sum of squared \(\eta_t\) values instead (which is what would happen if we estimated the regression model ignoring the autocorrelations in the errors), then several problems arise.
1. The estimated coefficients \(\hat{\beta}_0,\dots,\hat{\beta}_k\) are no longer the best estimates, as some information has been ignored in the calculation;
2. Any statistical tests associated with the model (e.g., t-tests on the coefficients) will be incorrect.
3. The AICc values of the fitted models are no longer a good guide as to which is the best model for forecasting.
4. In most cases, the \(p\)-values associated with the coefficients will be too small, and so some predictor variables will appear to be important when they are not. This is known as “spurious regression”.
Minimising the sum of squared \(\varepsilon_t\) values avoids these problems. Alternatively, maximum likelihood estimation can be used; this will give similar estimates of the coefficients.
An important consideration when estimating a regression with ARMA errors is that all of the variables in the model must first be stationary. Thus, we first have to check that \(y_t\) and all of the predictors \((x_{1,t},\dots,x_{k,t})\) appear to be stationary. If we estimate the model when any of these are non-stationary, the estimated coefficients will not be consistent estimates (and therefore may not be meaningful). One exception to this is the case where non-stationary variables are co-integrated. If there exists a linear combination of the non-stationary \(y_t\) and the predictors that is stationary, then the estimated coefficients will be consistent.[21](#fn21)
We therefore first difference the non-stationary variables in the model. It is often desirable to maintain the form of the relationship between \(y_t\) and the predictors, and consequently it is common to difference all of the variables if any of them need differencing. The resulting model is then called a “model in differences”, as distinct from a “model in levels”, which is what is obtained when the original data are used without differencing.
If all of the variables in the model are stationary, then we only need to consider an ARMA process for the errors. It is easy to see that a regression model with ARIMA errors is equivalent to a regression model in differences with ARMA errors. For example, if the above regression model with ARIMA(1,1,1) errors is differenced we obtain the model
\[\begin{align\*}
y'_t &= \beta_1 x'_{1,t} + \dots + \beta_k x'_{k,t} + \eta'_t,\\
& (1-\phi_1B)\eta'_t = (1+\theta_1B)\varepsilon_t,
\end{align\*}\]
where \(y'_t=y_t-y_{t-1}\), \(x'_{t,i}=x_{t,i}-x_{t-1,i}\) and \(\eta'_t=\eta_t-\eta_{t-1}\), which is a regression model in differences with ARMA errors.
### Bibliography
Harris, R., & Sollis, R. (2003). *Applied time series modelling and forecasting*. John Wiley & Sons.
---
21. Forecasting with cointegrated models is discussed by Harris & Sollis ([2003](#ref-Harris03)).[↩︎](https://otexts.com/fpp3/estimation.html#fnref21)
## 10.2 Regression with ARIMA errors using `fable`
The function `ARIMA()` will fit a regression model with ARIMA errors if exogenous regressors are included in the formula. As introduced in Section [9.5](https://otexts.com/fpp3/non-seasonal-arima.html#non-seasonal-arima), the `pdq()` special specifies the order of the ARIMA error model. If differencing is specified, then the differencing is applied to all variables in the regression model before the model is estimated. For example, the command
```
ARIMA(y ~ x + pdq(1,1,0))
```
will fit the model \(y_t' = \beta_1 x'_t + \eta'_t\), where \(\eta'_t = \phi_1 \eta'_{t-1} + \varepsilon_t\) is an AR(1) error. This is equivalent to the model
\[
y_t = \beta_0 + \beta_1 x_t + \eta_t,
\]
where \(\eta_t\) is an ARIMA(1,1,0) error. Notice that the constant term disappears due to the differencing. To include a constant in the differenced model, we would add `1` to the model formula.
The `ARIMA()` function can also be used to select the best ARIMA model for the errors. This is done by not specifying the `pdq()` special. Whether differencing is required is determined by applying a KPSS test to the residuals from the regression model estimated using ordinary least squares. If differencing is required, then all variables are differenced and the model re-estimated using maximum likelihood estimation. The final model will be expressed in terms of the original variables, even if it has been estimated using differenced variables.
The AICc is calculated for the final model, and this value can be used to determine the best predictors. That is, the procedure should be repeated for all subsets of predictors to be considered, and the model with the lowest AICc value selected.
### Example: US Personal Consumption and Income
Figure [10.1](https://otexts.com/fpp3/regarima.html#fig:usconsump) shows the quarterly changes in personal consumption expenditure and personal disposable income from 1970 to 2019 Q2. We would like to forecast changes in expenditure based on changes in income. A change in income does not necessarily translate to an instant change in consumption (e.g., after the loss of a job, it may take a few months for expenses to be reduced to allow for the new circumstances). However, we will ignore this complexity in this example and try to measure the instantaneous effect of the average change of income on the average change of consumption expenditure.
```
us_change |>
pivot_longer(c(Consumption, Income),
names_to = "var", values_to = "value") |>
ggplot(aes(x = Quarter, y = value)) +
geom_line() +
facet_grid(vars(var), scales = "free_y") +
labs(title = "US consumption and personal income",
y = "Quarterly % change")
```
![Percentage changes in quarterly personal consumption expenditure and personal disposable income for the USA, 1970 Q1 to 2019 Q2.](https://otexts.com/fpp3/fpp_files/figure-html/usconsump-1.png)
Figure 10.1: Percentage changes in quarterly personal consumption expenditure and personal disposable income for the USA, 1970 Q1 to 2019 Q2.
```
fit <- us_change |>
model(ARIMA(Consumption ~ Income))
report(fit)
#> Series: Consumption
#> Model: LM w/ ARIMA(1,0,2) errors
#>
#> Coefficients:
#> ar1 ma1 ma2 Income intercept
#> 0.7070 -0.6172 0.2066 0.1976 0.5949
#> s.e. 0.1068 0.1218 0.0741 0.0462 0.0850
#>
#> sigma^2 estimated as 0.3113: log likelihood=-163
#> AIC=338.1 AICc=338.5 BIC=357.8
```
The data are clearly already stationary (as we are considering percentage changes rather than raw expenditure and income), so there is no need for any differencing. The fitted model is
\[\begin{align\*}
y_t &= 0.595 +
0.198 x_t + \eta_t, \\
\eta_t &= 0.707 \eta_{t-1} + \varepsilon_t
-0.617 \varepsilon_{t-1} +
0.207 \varepsilon_{t-2},\\
\varepsilon_t &\sim \text{NID}(0,0.311).
\end{align\*}\]
We can recover estimates of both the \(\eta_t\) and \(\varepsilon_t\) series using the `residuals()` function.
```
bind_rows(
`Regression residuals` =
as_tibble(residuals(fit, type = "regression")),
`ARIMA residuals` =
as_tibble(residuals(fit, type = "innovation")),
.id = "type"
) |>
mutate(
type = factor(type, levels=c(
"Regression residuals", "ARIMA residuals"))
) |>
ggplot(aes(x = Quarter, y = .resid)) +
geom_line() +
facet_grid(vars(type))
```
![Regression residuals ($\eta_t$) and ARIMA residuals ($\varepsilon_t$) from the fitted model.](https://otexts.com/fpp3/fpp_files/figure-html/usconsumpres-1.png)
Figure 10.2: Regression residuals (\(\eta_t\)) and ARIMA residuals (\(\varepsilon_t\)) from the fitted model.
It is the ARIMA estimated errors (the innovation residuals) that should resemble a white noise series.
```
fit |> gg_tsresiduals()
```
![The innovation residuals (i.e., the estimated ARIMA errors) are not significantly different from white noise.](https://otexts.com/fpp3/fpp_files/figure-html/usconsumpres2-1.png)
Figure 10.3: The innovation residuals (i.e., the estimated ARIMA errors) are not significantly different from white noise.
```
augment(fit) |>
features(.innov, ljung_box, dof = 3, lag = 8)
#> # A tibble: 1 × 3
#> .model lb_stat lb_pvalue
#> <chr> <dbl> <dbl>
#> 1 ARIMA(Consumption ~ Income) 5.21 0.391
```
## 10.3 Forecasting
To forecast using a regression model with ARIMA errors, we need to forecast the regression part of the model and the ARIMA part of the model, and combine the results. As with ordinary regression models, in order to obtain forecasts we first need to forecast the predictors. When the predictors are known into the future (e.g., calendar-related variables such as time, day-of-week, etc.), this is straightforward. But when the predictors are themselves unknown, we must either model them separately, or use assumed future values for each predictor.
### Example: US Personal Consumption and Income
We will calculate forecasts for the next eight quarters assuming that the future percentage changes in personal disposable income will be equal to the mean percentage change from the last forty years.
```
us_change_future <- new_data(us_change, 8) |>
mutate(Income = mean(us_change$Income))
forecast(fit, new_data = us_change_future) |>
autoplot(us_change) +
labs(y = "Percentage change")
```
![Forecasts obtained from regressing the percentage change in consumption expenditure on the percentage change in disposable income, with an ARIMA(1,0,2) error model.](https://otexts.com/fpp3/fpp_files/figure-html/usconsump3-1.png)
Figure 10.4: Forecasts obtained from regressing the percentage change in consumption expenditure on the percentage change in disposable income, with an ARIMA(1,0,2) error model.
The prediction intervals for this model are narrower than if we had fitted an ARIMA model without covariates, because we are now able to explain some of the variation in the data using the income predictor.
It is important to realise that the prediction intervals from regression models (with or without ARIMA errors) do not take into account the uncertainty in the forecasts of the predictors. So they should be interpreted as being conditional on the assumed (or estimated) future values of the predictor variables.
### Example: Forecasting electricity demand
Daily electricity demand can be modelled as a function of temperature. As can be observed on an electricity bill, more electricity is used on cold days due to heating and hot days due to air conditioning. The higher demand on cold and hot days is reflected in the U-shape of Figure [10.5](https://otexts.com/fpp3/forecasting.html#fig:elecscatter), where daily demand is plotted versus daily maximum temperature.
```
vic_elec_daily <- vic_elec |>
filter(year(Time) == 2014) |>
index_by(Date = date(Time)) |>
summarise(
Demand = sum(Demand) / 1e3,
Temperature = max(Temperature),
Holiday = any(Holiday)
) |>
mutate(Day_Type = case_when(
Holiday ~ "Holiday",
wday(Date) %in% 2:6 ~ "Weekday",
TRUE ~ "Weekend"
))
vic_elec_daily |>
ggplot(aes(x = Temperature, y = Demand, colour = Day_Type)) +
geom_point() +
labs(y = "Electricity demand (GW)",
x = "Maximum daily temperature")
```
![Daily electricity demand versus maximum daily temperature for the state of Victoria in Australia for 2014.](https://otexts.com/fpp3/fpp_files/figure-html/elecscatter-1.png)
Figure 10.5: Daily electricity demand versus maximum daily temperature for the state of Victoria in Australia for 2014.
The data stored as `vic_elec_daily` includes total daily demand, daily maximum temperatures, and an indicator variable for if that day is a public holiday. Figure [10.6](https://otexts.com/fpp3/forecasting.html#fig:electime) shows the time series of both daily demand and daily maximum temperatures. The plots highlight the need for both a non-linear and a dynamic model.
```
vic_elec_daily |>
pivot_longer(c(Demand, Temperature)) |>
ggplot(aes(x = Date, y = value)) +
geom_line() +
facet_grid(name ~ ., scales = "free_y") + ylab("")
```
![Daily electricity demand and maximum daily temperature for the state of Victoria in Australia for 2014.](https://otexts.com/fpp3/fpp_files/figure-html/electime-1.png)
Figure 10.6: Daily electricity demand and maximum daily temperature for the state of Victoria in Australia for 2014.
In this example, we fit a quadratic regression model with ARMA errors using the `ARIMA()` function. The model also includes an indicator variable for if the day was a working day or not.
```
fit <- vic_elec_daily |>
model(ARIMA(Demand ~ Temperature + I(Temperature^2) +
(Day_Type == "Weekday")))
fit |> gg_tsresiduals()
```
![Residuals diagnostics for a dynamic regression model for daily electricity demand with workday and quadratic temperature effects.](https://otexts.com/fpp3/fpp_files/figure-html/elecdailyfit-1.png)
Figure 10.7: Residuals diagnostics for a dynamic regression model for daily electricity demand with workday and quadratic temperature effects.
The fitted model has an ARIMA(2,1,2)(2,0,0)[7] error, so there are 6 AR and MA coefficients.
```
augment(fit) |>
features(.innov, ljung_box, dof = 6, lag = 14)
#> # A tibble: 1 × 3
#> .model lb_stat lb_pvalue
#> <chr> <dbl> <dbl>
#> 1 "ARIMA(Demand ~ Temperature + I(Temperature^2) + (Day_Typ… 28.4 0.000404
```
There is clear heteroscedasticity in the residuals, with higher variance in January and February, and lower variance in May. The model also has some significant autocorrelation in the residuals, and the histogram of the residuals shows long tails. All of these issues with the residuals may affect the coverage of the prediction intervals, but the point forecasts should still be ok.
Using the estimated model we forecast 14 days ahead starting from Thursday 1 January 2015 (a non-work-day being a public holiday for New Years Day). In this case, we could obtain weather forecasts from the weather bureau for the next 14 days. But for the sake of illustration, we will use scenario based forecasting (as introduced in Section [7.6](https://otexts.com/fpp3/forecasting-regression.html#forecasting-regression)) where we set the temperature for the next 14 days to a constant 26 degrees.
```
vic_elec_future <- new_data(vic_elec_daily, 14) |>
mutate(
Temperature = 26,
Holiday = c(TRUE, rep(FALSE, 13)),
Day_Type = case_when(
Holiday ~ "Holiday",
wday(Date) %in% 2:6 ~ "Weekday",
TRUE ~ "Weekend"
)
)
forecast(fit, vic_elec_future) |>
autoplot(vic_elec_daily) +
labs(title="Daily electricity demand: Victoria",
y="GW")
```
![Forecasts from the dynamic regression model for daily electricity demand. All future temperatures have been set to 26 degrees, and the working day dummy variable has been set to known future values.](https://otexts.com/fpp3/fpp_files/figure-html/elecdailyfc-1.png)
Figure 10.8: Forecasts from the dynamic regression model for daily electricity demand. All future temperatures have been set to 26 degrees, and the working day dummy variable has been set to known future values.
The point forecasts look reasonable for the first two weeks of 2015. The slow down in electricity demand at the end of 2014 (due to many people taking summer vacations) has caused the forecasts for the next two weeks to show similarly low demand values.
## 10.4 Stochastic and deterministic trends
There are two different ways of modelling a linear trend. A *deterministic trend* is obtained using the regression model
\[
y_t = \beta_0 + \beta_1 t + \eta_t,
\]
where \(\eta_t\) is an ARMA process. A *stochastic trend* is obtained using the model
\[
y_t = \beta_0 + \beta_1 t + \eta_t,
\]
where \(\eta_t\) is an ARIMA process with \(d=1\). In the latter case, we can difference both sides so that \(y_t' = \beta_1 + \eta_t'\), where \(\eta_t'\) is an ARMA process. In other words,
\[
y_t = y_{t-1} + \beta_1 + \eta_t'.
\]
This is similar to a random walk with drift (introduced in Section [9.1](https://otexts.com/fpp3/stationarity.html#stationarity)), but here the error term is an ARMA process rather than simply white noise.
Although these models appear quite similar (they only differ in the number of differences that need to be applied to \(\eta_t\)), their forecasting characteristics are quite different.
### Example: Air transport passengers Australia
```
aus_airpassengers |>
autoplot(Passengers) +
labs(y = "Passengers (millions)",
title = "Total annual air passengers")
```
![Total annual passengers (in millions) for Australian air carriers, 1970--2016.](https://otexts.com/fpp3/fpp_files/figure-html/austa-1.png)
Figure 10.9: Total annual passengers (in millions) for Australian air carriers, 19702016.
Figure [10.9](https://otexts.com/fpp3/stochastic-and-deterministic-trends.html#fig:austa) shows the total number of passengers for Australian air carriers each year from 1970 to 2016. We will fit both a deterministic and a stochastic trend model to these data.
The deterministic trend model is obtained as follows:
```
fit_deterministic <- aus_airpassengers |>
model(deterministic = ARIMA(Passengers ~ 1 + trend() +
pdq(d = 0)))
report(fit_deterministic)
#> Series: Passengers
#> Model: LM w/ ARIMA(1,0,0) errors
#>
#> Coefficients:
#> ar1 trend() intercept
#> 0.9564 1.4151 0.9014
#> s.e. 0.0362 0.1972 7.0751
#>
#> sigma^2 estimated as 4.343: log likelihood=-100.88
#> AIC=209.77 AICc=210.72 BIC=217.17
```
This model can be written as
\[\begin{align\*}
y_t &= 0.901 + 1.415 t + \eta_t \\
\eta_t &= 0.956 \eta_{t-1} + \varepsilon_t\\
\varepsilon_t &\sim \text{NID}(0,4.343).
\end{align\*}\]
The estimated growth in visitor numbers is 1.42 million people per year.
Alternatively, the stochastic trend model can be estimated.
```
fit_stochastic <- aus_airpassengers |>
model(stochastic = ARIMA(Passengers ~ pdq(d = 1)))
report(fit_stochastic)
#> Series: Passengers
#> Model: ARIMA(0,1,0) w/ drift
#>
#> Coefficients:
#> constant
#> 1.4191
#> s.e. 0.3014
#>
#> sigma^2 estimated as 4.271: log likelihood=-98.16
#> AIC=200.31 AICc=200.59 BIC=203.97
```
This model can be written as \(y_t-y_{t-1} = 1.419 + \varepsilon_t\), or equivalently
\[\begin{align\*}
y_t &= y_0 + 1.419 t + \eta_t \\
\eta_t &= \eta_{t-1} + \varepsilon_{t}\\
\varepsilon_t &\sim \text{NID}(0,4.271).
\end{align\*}\]
In this case, the estimated growth in visitor numbers is also 1.42 million people per year. Although the growth estimates are similar, the prediction intervals are not, as Figure [10.10](https://otexts.com/fpp3/stochastic-and-deterministic-trends.html#fig:austaf) shows. In particular, stochastic trends have much wider prediction intervals because the errors are non-stationary.
```
aus_airpassengers |>
autoplot(Passengers) +
autolayer(fit_stochastic |> forecast(h = 20),
colour = "#0072B2", level = 95) +
autolayer(fit_deterministic |> forecast(h = 20),
colour = "#D55E00", alpha = 0.65, level = 95) +
labs(y = "Air passengers (millions)",
title = "Forecasts from trend models")
```
![Forecasts of annual passengers for Australian air carriers using a deterministic trend model (orange) and a stochastic trend model (blue).](https://otexts.com/fpp3/fpp_files/figure-html/austaf-1.png)
Figure 10.10: Forecasts of annual passengers for Australian air carriers using a deterministic trend model (orange) and a stochastic trend model (blue).
There is an implicit assumption with deterministic trends that the slope of the trend is not going to change over time. On the other hand, stochastic trends can change, and the estimated growth is only assumed to be the average growth over the historical period, not necessarily the rate of growth that will be observed into the future. Consequently, it is safer to forecast with stochastic trends, especially for longer forecast horizons, as the prediction intervals allow for greater uncertainty in future growth.
## 10.5 Dynamic harmonic regression
When there are long seasonal periods, a dynamic regression with Fourier terms is often better than other models we have considered in this book.[22](#fn22)
For example, daily data can have annual seasonality of length 365, weekly data has seasonal period of approximately 52, while half-hourly data can have several seasonal periods, the shortest of which is the daily pattern of period 48.
Seasonal versions of ARIMA and ETS models are designed for shorter periods such as 12 for monthly data or 4 for quarterly data. The `ETS()` model restricts seasonality to be a maximum period of 24 to allow hourly data but not data with a larger seasonal period. The problem is that there are \(m-1\) parameters to be estimated for the initial seasonal states where \(m\) is the seasonal period. So for large \(m\), the estimation becomes almost impossible.
The `ARIMA()` function will allow a seasonal period up to \(m=350\), but in practice will usually run out of memory whenever the seasonal period is more than about 200. In any case, seasonal differencing of high order does not make a lot of sense — for daily data it involves comparing what happened today with what happened exactly a year ago and there is no constraint that the seasonal pattern is smooth.
So for such time series, we prefer a harmonic regression approach where the seasonal pattern is modelled using Fourier terms with short-term time series dynamics handled by an ARMA error.
The advantages of this approach are:
* it allows any length seasonality;
* for data with more than one seasonal period, Fourier terms of different frequencies can be included;
* the smoothness of the seasonal pattern can be controlled by \(K\), the number of Fourier sin and cos pairs the seasonal pattern is smoother for smaller values of \(K\);
* the short-term dynamics are easily handled with a simple ARMA error.
The only real disadvantage (compared to a seasonal ARIMA model) is that the seasonality is assumed to be fixed — the seasonal pattern is not allowed to change over time. But in practice, seasonality is usually remarkably constant so this is not a big disadvantage except for long time series.
### Example: Australian eating out expenditure
In this example we demonstrate combining Fourier terms for capturing seasonality with ARIMA errors capturing other dynamics in the data. For simplicity, we will use an example with monthly data. The same modelling approach using weekly data is discussed in Section [13.1](https://otexts.com/fpp3/weekly.html#weekly).
We use the total monthly expenditure on cafes, restaurants and takeaway food services in Australia ($billion) from 2004 up to 2018 and forecast 24 months ahead. We vary \(K\), the number of Fourier sin and cos pairs, from \(K=1\) to \(K=6\) (which is equivalent to including seasonal dummies). Figure [10.11](https://otexts.com/fpp3/dhr.html#fig:eatout) shows the seasonal pattern projected forward as \(K\) increases. Notice that as \(K\) increases the Fourier terms capture and project a more “wiggly” seasonal pattern and simpler ARIMA models are required to capture other dynamics. The AICc value is minimised for \(K=6\), with a significant jump going from \(K=4\) to \(K=5\), hence the forecasts generated from this model would be the ones used.
```
aus_cafe <- aus_retail |>
filter(
Industry == "Cafes, restaurants and takeaway food services",
year(Month) %in% 2004:2018
) |>
summarise(Turnover = sum(Turnover))
fit <- model(aus_cafe,
`K = 1` = ARIMA(log(Turnover) ~ fourier(K=1) + PDQ(0,0,0)),
`K = 2` = ARIMA(log(Turnover) ~ fourier(K=2) + PDQ(0,0,0)),
`K = 3` = ARIMA(log(Turnover) ~ fourier(K=3) + PDQ(0,0,0)),
`K = 4` = ARIMA(log(Turnover) ~ fourier(K=4) + PDQ(0,0,0)),
`K = 5` = ARIMA(log(Turnover) ~ fourier(K=5) + PDQ(0,0,0)),
`K = 6` = ARIMA(log(Turnover) ~ fourier(K=6) + PDQ(0,0,0))
)
fit |>
forecast(h = "2 years") |>
autoplot(aus_cafe, level = 95) +
facet_wrap(vars(.model), ncol = 2) +
guides(colour = "none", fill = "none", level = "none") +
geom_label(
aes(x = yearmonth("2007 Jan"), y = 4250,
label = paste0("AICc = ", format(AICc))),
data = glance(fit)
) +
labs(title= "Total monthly eating-out expenditure",
y="$ billions")
```
![Using Fourier terms and ARIMA errors for forecasting monthly expenditure on eating out in Australia.](https://otexts.com/fpp3/fpp_files/figure-html/eatout-1.png)
Figure 10.11: Using Fourier terms and ARIMA errors for forecasting monthly expenditure on eating out in Australia.
### Bibliography
Young, P. C., Pedregal, D. J., & Tych, W. (1999). Dynamic harmonic regression. *Journal of Forecasting*, *18*, 369394.
---
22. The term “dynamic harmonic regression” is also used for a harmonic regression with time-varying parameters ([Young et al., 1999](#ref-DHR99)).[↩︎](https://otexts.com/fpp3/dhr.html#fnref22)
## 10.6 Lagged predictors
Sometimes, the impact of a predictor that is included in a regression model will not be simple and immediate. For example, an advertising campaign may impact sales for some time beyond the end of the campaign, and sales in one month will depend on the advertising expenditure in each of the past few months. Similarly, a change in a companys safety policy may reduce accidents immediately, but have a diminishing effect over time as employees take less care when they become familiar with the new working conditions.
In these situations, we need to allow for lagged effects of the predictor. Suppose that we have only one predictor in our model. Then a model which allows for lagged effects can be written as
\[
y_t = \beta_0 + \gamma_0x_t + \gamma_1 x_{t-1} + \dots + \gamma_k x_{t-k} + \eta_t,
\]
where \(\eta_t\) is an ARIMA process. The value of \(k\) can be selected using the AICc, along with the values of \(p\) and \(q\) for the ARIMA error.
### Example: TV advertising and insurance quotations
A US insurance company advertises on national television in an attempt to increase the number of insurance quotations provided (and consequently the number of new policies). Figure [10.12](https://otexts.com/fpp3/lagged-predictors.html#fig:tvadvert) shows the number of quotations and the expenditure on television advertising for the company each month from January 2002 to April 2005.
```
insurance |>
pivot_longer(Quotes:TVadverts) |>
ggplot(aes(x = Month, y = value)) +
geom_line() +
facet_grid(vars(name), scales = "free_y") +
labs(y = "", title = "Insurance advertising and quotations")
```
![Numbers of insurance quotations provided per month and the expenditure on advertising per month.](https://otexts.com/fpp3/fpp_files/figure-html/tvadvert-1.png)
Figure 10.12: Numbers of insurance quotations provided per month and the expenditure on advertising per month.
We will consider including advertising expenditure for up to four months; that is, the model may include advertising expenditure in the current month, and the three months before that. When comparing models, it is important that they all use the same training set. In the following code, we exclude the first three months in order to make fair comparisons.
```
fit <- insurance |>
# Restrict data so models use same fitting period
mutate(Quotes = c(NA, NA, NA, Quotes[4:40])) |>
# Estimate models
model(
lag0 = ARIMA(Quotes ~ pdq(d = 0) + TVadverts),
lag1 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + lag(TVadverts)),
lag2 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + lag(TVadverts) +
lag(TVadverts, 2)),
lag3 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + lag(TVadverts) +
lag(TVadverts, 2) + lag(TVadverts, 3))
)
```
Next we choose the optimal lag length for advertising based on the AICc.
```
glance(fit)
#> # A tibble: 4 × 8
#> .model sigma2 log_lik AIC AICc BIC ar_roots ma_roots
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <list> <list>
#> 1 lag0 0.265 -28.3 66.6 68.3 75.0 <cpl [2]> <cpl [0]>
#> 2 lag1 0.209 -24.0 58.1 59.9 66.5 <cpl [1]> <cpl [1]>
#> 3 lag2 0.215 -24.0 60.0 62.6 70.2 <cpl [1]> <cpl [1]>
#> 4 lag3 0.206 -22.2 60.3 65.0 73.8 <cpl [1]> <cpl [1]>
```
The best model (with the smallest AICc value) is `lag1` with two predictors; that is, it includes advertising only in the current month and the previous month. So we now re-estimate that model, but using all the available data.
```
fit_best <- insurance |>
model(ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + lag(TVadverts)))
report(fit_best)
#> Series: Quotes
#> Model: LM w/ ARIMA(1,0,2) errors
#>
#> Coefficients:
#> ar1 ma1 ma2 TVadverts lag(TVadverts) intercept
#> 0.5123 0.9169 0.4591 1.2527 0.1464 2.1554
#> s.e. 0.1849 0.2051 0.1895 0.0588 0.0531 0.8595
#>
#> sigma^2 estimated as 0.2166: log likelihood=-23.94
#> AIC=61.88 AICc=65.38 BIC=73.7
```
The chosen model has ARIMA(1,0,2) errors. The model can be written as
\[
y_t = 2.155 +
1.253 x_t +
0.146 x_{t-1} + \eta_t,
\]
where \(y_t\) is the number of quotations provided in month \(t\), \(x_t\) is the advertising expenditure in month \(t\),
\[
\eta_t = 0.512 \eta_{t-1} +
\varepsilon_t +
0.917 \varepsilon_{t-1} +
0.459 \varepsilon_{t-2},
\]
and \(\varepsilon_t\) is white noise.
We can calculate forecasts using this model if we assume future values for the advertising variable. If we set the future monthly advertising to 8 units, we get the forecasts in Figure [10.13](https://otexts.com/fpp3/lagged-predictors.html#fig:tvadvertf8).
```
insurance_future <- new_data(insurance, 20) |>
mutate(TVadverts = 8)
fit_best |>
forecast(insurance_future) |>
autoplot(insurance) +
labs(
y = "Quotes",
title = "Forecast quotes with future advertising set to 8"
)
```
![Forecasts of monthly insurance quotes, assuming that the future advertising expenditure is 8 units in each future month.](https://otexts.com/fpp3/fpp_files/figure-html/tvadvertf8-1.png)
Figure 10.13: Forecasts of monthly insurance quotes, assuming that the future advertising expenditure is 8 units in each future month.
## 10.7 Exercises
1. This exercise uses data set `LakeHuron` giving the level of Lake Huron from 18751972.
1. Convert the data to a tsibble object using the `as_tsibble()` function.
2. Fit a piecewise linear trend model to the Lake Huron data with a knot at 1920 and an ARMA error structure.
3. Forecast the level for the next 30 years. Do you think the extrapolated linear trend is realistic?
2. Repeat Exercise 4 from Section [7.10](https://otexts.com/fpp3/regression-exercises.html#regression-exercises), but this time adding in ARIMA errors to address the autocorrelations in the residuals.
1. How much difference does the ARIMA error process make to the regression coefficients?
2. How much difference does the ARIMA error process make to the forecasts?
3. Check the residuals of the fitted model to ensure the ARIMA process has adequately addressed the autocorrelations seen in the `TSLM` model.
3. Repeat the daily electricity example, but instead of using a quadratic function of temperature, use a piecewise linear function with the “knot” around 25 degrees Celsius (use predictors `Temperature` & `Temp2`). How can you optimise the choice of knot?
The data can be created as follows.
```
vic_elec_daily <- vic_elec |>
filter(year(Time) == 2014) |>
index_by(Date = date(Time)) |>
summarise(
Demand = sum(Demand)/1e3,
Temperature = max(Temperature),
Holiday = any(Holiday)) |>
mutate(
Temp2 = I(pmax(Temperature-25,0)),
Day_Type = case_when(
Holiday ~ "Holiday",
wday(Date) %in% 2:6 ~ "Weekday",
TRUE ~ "Weekend"))
```
4. This exercise concerns `aus_accommodation`: the total quarterly takings from accommodation and the room occupancy level for hotels, motels, and guest houses in Australia, between January 1998 and June 2016. Total quarterly takings are in millions of Australian dollars.
1. Compute the CPI-adjusted takings and plot the result for each state
2. For each state, fit a dynamic regression model of CPI-adjusted takings with seasonal dummy variables, a piecewise linear time trend with one knot at 2008 Q1, and ARIMA errors.
3. Check that the residuals of the model look like white noise.
4. Forecast the takings for each state to the end of 2017. (Hint: You will need to produce forecasts of the CPI first.)
5. What sources of uncertainty have not been taken into account in the prediction intervals?
5. We fitted a harmonic regression model to part of the `us_gasoline` series in Exercise 5 in Section [7.10](https://otexts.com/fpp3/regression-exercises.html#regression-exercises). We will now revisit this model, and extend it to include more data and ARMA errors.
1. Using `TSLM()`, fit a harmonic regression with a piecewise linear time trend to the full series. Select the position of the knots in the trend and the appropriate number of Fourier terms to include by minimising the AICc or CV value.
2. Now refit the model using `ARIMA()` to allow for correlated errors, keeping the same predictor variables as you used with `TSLM()`.
3. Check the residuals of the final model using the `gg_tsresiduals()` function and a Ljung-Box test. Do they look sufficiently like white noise to continue? If not, try modifying your model, or removing the first few years of data.
4. Once you have a model with white noise residuals, produce forecasts for the next year.
6. Electricity consumption is often modelled as a function of temperature. Temperature is measured by daily heating degrees and cooling degrees. Heating degrees is \(18^\circ\)C minus the average daily temperature when the daily average is below \(18^\circ\)C; otherwise it is zero. This provides a measure of our need to heat ourselves as temperature falls. Cooling degrees measures our need to cool ourselves as the temperature rises. It is defined as the average daily temperature minus \(18^\circ\)C when the daily average is above \(18^\circ\)C; otherwise it is zero. Let \(y_t\) denote the monthly total of kilowatt-hours of electricity used, let \(x_{1,t}\) denote the monthly total of heating degrees, and let \(x_{2,t}\) denote the monthly total of cooling degrees.
An analyst fits the following model to a set of such data:
\[y^\*_t = \beta_1x^\*_{1,t} + \beta_2x^\*_{2,t} + \eta_t,\]
where
\[(1-\Phi_{1}B^{12} - \Phi_{2}B^{24})(1-B)(1-B^{12})\eta_t = (1+\theta_1 B)\varepsilon_t\]
and \(y^\*_t = \log(y_t)\), \(x^\*_{1,t} = \sqrt{x_{1,t}}\) and \(x^\*_{2,t}=\sqrt{x_{2,t}}\).
1. What sort of ARIMA model is identified for \(\eta_t\)?
2. The estimated coefficients are
| Parameter | Estimate | s.e. | \(Z\) | \(P\)-value |
| --- | --- | --- | --- | --- |
| \(\beta_1\) | 0.0077 | 0.0015 | 4.98 | 0.000 |
| \(\beta_2\) | 0.0208 | 0.0023 | 9.23 | 0.000 |
| \(\theta_1\) | -0.5830 | 0.0720 | 8.10 | 0.000 |
| \(\Phi_{1}\) | -0.5373 | 0.0856 | -6.27 | 0.000 |
| \(\Phi_{2}\) | -0.4667 | 0.0862 | -5.41 | 0.000 |
Explain what the estimates of \(\beta_1\) and \(\beta_2\) tell us about electricity consumption.
c. Write the equation in a form more suitable for forecasting.
d. Describe how this model could be used to forecast electricity demand for the next 12 months.
e. Explain why the \(\eta_t\) term should be modelled with an ARIMA model rather than modelling the data using a standard regression package. In your discussion, comment on the properties of the estimates, the validity of the standard regression results, and the importance of the \(\eta_t\) model in producing forecasts.
7. For the retail time series considered in earlier chapters:
1. Develop an appropriate dynamic regression model with Fourier terms for the seasonality. Use the AICc to select the number of Fourier terms to include in the model. (You will probably need to use the same Box-Cox transformation you identified previously.)
2. Check the residuals of the fitted model. Does the residual series look like white noise?
3. Compare the forecasts with those you obtained earlier using alternative models.
## 10.8 Further reading
* A detailed discussion of dynamic regression models is provided in Pankratz ([1991](#ref-Pankratz91)).
* A generalisation of dynamic regression models, known as “transfer function models”, is discussed in Box et al. ([2015](#ref-BJRL15)).
### Bibliography
Box, G. E. P., Jenkins, G. M., Reinsel, G. C., & Ljung, G. M. (2015). *Time series analysis: Forecasting and control* (5th ed). John Wiley & Sons.
Pankratz, A. E. (1991). *Forecasting with dynamic regression models*. John Wiley & Sons.
@@ -0,0 +1,893 @@
Source: https://otexts.com/fpp3/hierarchical.html (chapter hierarchical, 9 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 11-hierarchical-grouped
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 11 Forecasting hierarchical and grouped time series
Time series can often be naturally disaggregated by various attributes of interest. For example, the total number of bicycles sold by a cycling manufacturer can be disaggregated by product type such as road bikes, mountain bikes and hybrids. Each of these can be disaggregated into finer categories. For example hybrid bikes can be divided into city, commuting, comfort, and trekking bikes; and so on. These categories are nested within the larger group categories, and so the collection of time series follows a hierarchical aggregation structure. Therefore we refer to these as “hierarchical time series”.
Hierarchical time series often arise due to geographic divisions. For example, the total bicycle sales can be disaggregated by country, then within each country by state, within each state by region, and so on down to the outlet level.
Alternative aggregation structures arise when attributes of interest are crossed rather than nested. For example, the bicycle manufacturer may be interested in attributes such as frame size, gender, price range, etc. Such attributes do not naturally disaggregate in a unique hierarchical manner as the attributes are not nested. We refer to the resulting time series of crossed attributes as “grouped time series”.
More complex structures arise when attributes of interest are both nested and crossed. For example, it would be natural for the bicycle manufacturer to be interested in sales by product type and also by geographic division. Then both the product groupings and the geographic hierarchy are mixed together. We introduce alternative aggregation structures in Section [11.1](https://otexts.com/fpp3/hts.html#hts).
Forecasts are often required for all disaggregate and aggregate series, and it is natural to want the forecasts to add up in the same way as the data. For example, forecasts of regional sales should add up to forecasts of state sales, which should in turn add up to give a forecast for national sales.
In this chapter we discuss forecasting large collections of time series that aggregate in some way. The challenge is that we require forecasts that are **coherent** across the entire aggregation structure. That is, we require forecasts to add up in a manner that is consistent with the aggregation structure of the hierarchy or group that defines the collection of time series.
## 11.1 Hierarchical and grouped time series
### Hierarchical time series
Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree) shows a simple hierarchical structure. At the top of the hierarchy is the “Total”, the most aggregate level of the data. The \(t\)th observation of the Total series is denoted by \(y_t\) for \(t=1,\dots,T\). The Total is disaggregated into two series, which in turn are divided into three and two series respectively at the bottom level of the hierarchy. Below the top level, we use \(y_{j,t}\) to denote the \(t\)th observation of the series corresponding to node \(j\). For example, \(\y{A}{t}\) denotes the \(t\)th observation of the series corresponding to node A, \(\y{AB}{t}\) denotes the \(t\)th observation of the series corresponding to node AB, and so on.
![A two level hierarchical tree diagram.](https://otexts.com/fpp3/figs/hts.png)
Figure 11.1: A two level hierarchical tree diagram.
In this small example, the total number of series in the hierarchy is \(n=1+2+5=8\), while the number of series at the bottom level is \(m=5\). Note that \(n>m\) in all hierarchies.
For any time \(t\), the observations at the bottom level of the hierarchy will sum to the observations of the series above. For example,
\[\begin{equation}
y_{t}=\y{AA}{t}+\y{AB}{t}+\y{AC}{t}+\y{BA}{t}+\y{BB}{t},
\tag{11.1}
\end{equation}\]
\[\begin{equation}
\y{A}{t}=\y{AA}{t}+\y{AB}{t}+\y{AC}{t}\qquad \text{and} \qquad \y{B}{t}=\y{BA}{t}+\y{BB}{t}.
\tag{11.2}
\end{equation}\]
Substituting [(11.2)](https://otexts.com/fpp3/hts.html#eq:middlelevel) into [(11.1)](https://otexts.com/fpp3/hts.html#eq:toplevel), we also get \(y_{t}=\y{A}{t}+\y{B}{t}\).
### Example: Australian tourism hierarchy
Australia is divided into six states and two territories, with each one having its own government and some economic and administrative autonomy. For simplicity, we refer to both states and territories as “states”. Each of these states can be further subdivided into regions as shown in Figure [11.2](https://otexts.com/fpp3/hts.html#fig:ausmap) and Table [11.1](https://otexts.com/fpp3/hts.html#tab:aus-states-tab). In total there are 76 such regions. Business planners and tourism authorities are interested in forecasts for the whole of Australia, for each of the states and territories, and also for the regions.
![Australian states and tourism regions.](https://otexts.com/fpp3/fpp_files/figure-html/ausmap-1.png)
Figure 11.2: Australian states and tourism regions.
Table 11.1: Australian tourism regions.
| State | Region |
| --- | --- |
| Australian Capital Territory | Canberra |
| New South Wales | Blue Mountains, Capital Country, Central Coast, Central NSW, Hunter, New England North West, North Coast NSW, Outback NSW, Riverina, Snowy Mountains, South Coast, Sydney, The Murray. |
| Northern Territory | Alice Springs, Barkly, Darwin, Kakadu Arnhem, Katherine Daly, Lasseter, MacDonnell. |
| Queensland | Brisbane, Bundaberg, Central Queensland, Darling Downs, Fraser Coast, Gold Coast, Mackay, Northern Outback, Sunshine Coast, Tropical North Queensland, Whitsundays. |
| South Australia | Adelaide, Adelaide Hills, Barossa, Clare Valley, Eyre Peninsula, Fleurieu Peninsula, Flinders Ranges and Outback, Kangaroo Island, Limestone Coast, Murraylands, Riverland, Yorke Peninsula. |
| Tasmania | East Coast, Hobart and the South, Launceston Tamar and the North, North West, Wilderness West. |
| Victoria | Ballarat, Bendigo Loddon, Central Highlands, Central Murray, Geelong and the Bellarine, Gippsland, Goulburn, Great Ocean Road, High Country, Lakes, Macedon, Mallee, Melbourne, Melbourne East, Murray East, Peninsula, Phillip Island, Spa Country, Upper Yarra, Western Grampians, Wimmera. |
| Western Australia | Australias Coral Coast, Australias Golden Outback, Australias North West, Australias South West, Experience Perth. |
The `tourism` tsibble contains data on quarterly domestic tourism demand, measured as the number of overnight trips Australians spend away from home. The key variables `State` and `Region` denote the geographical areas, while a further key `Purpose` describes the purpose of travel. For now, we will ignore the purpose of travel and just consider the geographic hierarchy. To make the graphs and tables simpler, we will recode `State` to use abbreviations.
```
tourism <- tsibble::tourism |>
mutate(State = recode(State,
`New South Wales` = "NSW",
`Northern Territory` = "NT",
`Queensland` = "QLD",
`South Australia` = "SA",
`Tasmania` = "TAS",
`Victoria` = "VIC",
`Western Australia` = "WA"
))
```
Using the `aggregate_key()` function, we can create the hierarchical time series with overnight trips in regions at the bottom level of the hierarchy, aggregated to states, which are aggregated to the national total. A hierarchical time series corresponding to the nested structure is created using a `parent/child` specification.
```
tourism_hts <- tourism |>
aggregate_key(State / Region, Trips = sum(Trips))
tourism_hts
#> # A tsibble: 6,800 x 4 [1Q]
#> # Key: State, Region [85]
#> Quarter State Region Trips
#> <qtr> <chr*> <chr*> <dbl>
#> 1 1998 Q1 <aggregated> <aggregated> 23182.
#> 2 1998 Q2 <aggregated> <aggregated> 20323.
#> 3 1998 Q3 <aggregated> <aggregated> 19827.
#> 4 1998 Q4 <aggregated> <aggregated> 20830.
#> 5 1999 Q1 <aggregated> <aggregated> 22087.
#> 6 1999 Q2 <aggregated> <aggregated> 21458.
#> 7 1999 Q3 <aggregated> <aggregated> 19914.
#> 8 1999 Q4 <aggregated> <aggregated> 20028.
#> 9 2000 Q1 <aggregated> <aggregated> 22339.
#> 10 2000 Q2 <aggregated> <aggregated> 19941.
#> # 6,790 more rows
```
The new `tsibble` now has some additional rows corresponding to state and national aggregations for each quarter. Figure [11.3](https://otexts.com/fpp3/hts.html#fig:tourismStates) shows the aggregate total overnight trips for the whole of Australia as well as the states, revealing diverse and rich dynamics. For example, there is noticeable national growth since 2010 and for some states such as the ACT, New South Wales, Queensland, South Australia, and Victoria. There seems to be a significant jump for Western Australia in 2014.
```
tourism_hts |>
filter(is_aggregated(Region)) |>
autoplot(Trips) +
labs(y = "Trips ('000)",
title = "Australian tourism: national and states") +
facet_wrap(vars(State), scales = "free_y", ncol = 3) +
theme(legend.position = "none")
```
![Domestic overnight trips from 1998 Q1 to 2017 Q4 aggregated by state.](https://otexts.com/fpp3/fpp_files/figure-html/tourismStates-1.png)
Figure 11.3: Domestic overnight trips from 1998 Q1 to 2017 Q4 aggregated by state.
```
tourism_hts |>
filter(State == "NT" | State == "QLD" |
State == "TAS" | State == "VIC", is_aggregated(Region)) |>
select(-Region) |>
mutate(State = factor(State, levels=c("QLD","VIC","NT","TAS"))) |>
gg_season(Trips) +
facet_wrap(vars(State), nrow = 2, scales = "free_y")+
labs(y = "Trips ('000)")
```
![Seasonal plots for overnight trips for Queensland and the Northern Territory, and Victoria and Tasmania highlighting the contrast in seasonal patterns between northern and southern states in Australia.](https://otexts.com/fpp3/fpp_files/figure-html/seasonStates-1.png)
Figure 11.4: Seasonal plots for overnight trips for Queensland and the Northern Territory, and Victoria and Tasmania highlighting the contrast in seasonal patterns between northern and southern states in Australia.
The seasonal pattern of the northern states, such as Queensland and the Northern Territory, leads to peak visits in winter (corresponding to Q3) due to the tropical climate and rainy summer months. In contrast, the southern states tend to peak in summer (corresponding to Q1). This is highlighted in the seasonal plots shown in Figure [11.4](https://otexts.com/fpp3/hts.html#fig:seasonStates) for Queensland and the Northern Territory (shown in the left column) versus the most southern states of Victoria and Tasmania (shown in the right column).
![Domestic overnight trips from 1998 Q1 to 2017 Q4 for some selected regions.](https://otexts.com/fpp3/fpp_files/figure-html/tourismRegions-1.png)
Figure 11.5: Domestic overnight trips from 1998 Q1 to 2017 Q4 for some selected regions.
The plots in Figure [11.5](https://otexts.com/fpp3/hts.html#fig:tourismRegions) shows data for some selected regions. These help us visualise the diverse regional dynamics within each state, with some series showing strong trends or seasonality, some showing contrasting seasonality, while some series appear to be just noise.
### Grouped time series
With grouped time series, the data structure does not naturally disaggregate in a unique hierarchical manner. Figure [11.6](https://otexts.com/fpp3/hts.html#fig:GroupTree) shows a simple grouped structure. At the top of the grouped structure is the Total, the most aggregate level of the data, again represented by \(y_t\). The Total can be disaggregated by attributes (A, B) forming series \(\y{A}{t}\) and \(\y{B}{t}\), or by attributes (X, Y) forming series \(\y{X}{t}\) and \(\y{Y}{t}\). At the bottom level, the data are disaggregated by both attributes.
![Alternative representations of a two level grouped structure.](https://otexts.com/fpp3/fpp_files/figure-html/GroupTree-1.png)
Figure 11.6: Alternative representations of a two level grouped structure.
This example shows that there are alternative aggregation paths for grouped structures. For any time \(t\), as with the hierarchical structure,
\[\begin{equation\*}
y_{t}=\y{AX}{t}+\y{AY}{t}+\y{BX}{t}+\y{BY}{t}.
\end{equation\*}\]
However, for the first level of the grouped structure,
\[\begin{equation} \y{A}{t}=\y{AX}{t}+\y{AY}{t}\quad \quad \y{B}{t}=\y{BX}{t}+\y{BY}{t}
\tag{11.3}
\end{equation}\] but also
\[\begin{equation} \y{X}{t}=\y{AX}{t}+\y{BX}{t}\quad \quad \y{Y}{t}=\y{AY}{t}+\y{BY}{t}
\tag{11.4}.
\end{equation}\]
Grouped time series can sometimes be thought of as hierarchical time series that do not impose a unique hierarchical structure, in the sense that the order by which the series can be grouped is not unique.
### Example: Australian prison population
In this example we consider the Australia prison population data introduced in Chapter [2](https://otexts.com/fpp3/graphics.html#graphics). The top panel in Figure [11.7](https://otexts.com/fpp3/hts.html#fig:prisongts) shows the total number of prisoners in Australia over the period 2005Q12016Q4. This represents the top-level series in the grouping structure. The panels below show the prison population disaggregated or grouped by (a) state (b) legal status (whether prisoners have already been sentenced or are in remand waiting for a sentence), and (c) gender. The three factors are crossed, but none are nested within the others.
![Total Australian quarterly adult prison population, disaggregated by state, by legal status, and by gender.](https://otexts.com/fpp3/fpp_files/figure-html/prisongts-1.png)
Figure 11.7: Total Australian quarterly adult prison population, disaggregated by state, by legal status, and by gender.
The following code, introduced in Section [2.1](https://otexts.com/fpp3/tsibbles.html#tsibbles), builds a `tsibble` object for the prison data.
```
prison <- readr::read_csv("https://OTexts.com/fpp3/extrafiles/prison_population.csv") |>
mutate(Quarter = yearquarter(Date)) |>
select(-Date) |>
as_tsibble(key = c(Gender, Legal, State, Indigenous),
index = Quarter) |>
relocate(Quarter)
```
We create a grouped time series using `aggregate_key()` with attributes or groupings of interest now being crossed using the syntax `attribute1*attribute2` (in contrast to the `parent/child` syntax used for hierarchical time series). The following code builds a grouped tsibble for the prison data with crossed attributes: gender, legal status and state.
```
prison_gts <- prison |>
aggregate_key(Gender * Legal * State, Count = sum(Count)/1e3)
```
Using `is_aggregated()` within `filter()` is helpful for exploring or plotting the main groups shown in the bottom panels of Figure [11.7](https://otexts.com/fpp3/hts.html#fig:prisongts). For example, the following code plots the total numbers of female and male prisoners across Australia.
```
prison_gts |>
filter(!is_aggregated(Gender), is_aggregated(Legal),
is_aggregated(State)) |>
autoplot(Count) +
labs(y = "Number of prisoners ('000)")
```
Plots of other group combinations can be obtained in a similar way. Figure [11.8](https://otexts.com/fpp3/hts.html#fig:prison1) shows the Australian prison population grouped by all possible combinations of two attributes at a time: state and gender, state and legal status, and legal status and gender. The following code will reproduce the first plot in Figure [11.8](https://otexts.com/fpp3/hts.html#fig:prison1).
![Australian adult prison population disaggregated by pairs of attributes.](https://otexts.com/fpp3/fpp_files/figure-html/prison1-1.png)
Figure 11.8: Australian adult prison population disaggregated by pairs of attributes.
```
prison_gts |>
filter(!is_aggregated(Gender), !is_aggregated(Legal),
!is_aggregated(State)) |>
mutate(Gender = as.character(Gender)) |>
ggplot(aes(x = Quarter, y = Count,
group = Gender, colour=Gender)) +
stat_summary(fun = sum, geom = "line") +
labs(title = "Prison population by state and gender",
y = "Number of prisoners ('000)") +
facet_wrap(~ as.character(State),
nrow = 1, scales = "free_y") +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
```
Figure [11.9](https://otexts.com/fpp3/hts.html#fig:prisonBTS) shows the Australian adult prison population disaggregated by all three attributes: state, legal status and gender. These form the bottom-level series of the grouped structure.
![Bottom-level time series for the Australian adult prison population, grouped by state, legal status and gender.](https://otexts.com/fpp3/fpp_files/figure-html/prisonBTS-1.png)
Figure 11.9: Bottom-level time series for the Australian adult prison population, grouped by state, legal status and gender.
### Mixed hierarchical and grouped structure
Often disaggregating factors are both nested and crossed. For example, the Australian tourism data can also be disaggregated by the four purposes of travel: holiday, business, visiting friends and relatives, and other. This grouping variable does not nest within any of the geographical variables. In fact, we could consider overnight trips split by purpose of travel for the whole of Australia, and for each state, and for each region. We describe such a structure as a “nested” geographic hierarchy “crossed” with the purpose of travel. Using `aggregate_key()` this can be specified by simply combining the factors.
```
tourism_full <- tourism |>
aggregate_key((State/Region) * Purpose, Trips = sum(Trips))
```
The `tourism_full` tsibble contains 425 series, including the 85 series from the hierarchical structure, as well as another 340 series obtained when each series of the hierarchical structure is crossed with the purpose of travel.
![Australian domestic overnight trips from 1998 Q1 to 2017 Q4 disaggregated by purpose of travel.](https://otexts.com/fpp3/fpp_files/figure-html/mixed-purpose-1.png)
Figure 11.10: Australian domestic overnight trips from 1998 Q1 to 2017 Q4 disaggregated by purpose of travel.
![Australian domestic overnight trips over the period 1998 Q1 to 2017 Q4 disaggregated by purpose of travel and by state.](https://otexts.com/fpp3/fpp_files/figure-html/mixed-state-purpose-1.png)
Figure 11.11: Australian domestic overnight trips over the period 1998 Q1 to 2017 Q4 disaggregated by purpose of travel and by state.
Figures [11.10](https://otexts.com/fpp3/hts.html#fig:mixed-purpose) and [11.11](https://otexts.com/fpp3/hts.html#fig:mixed-state-purpose) show the aggregate series grouped by purpose of travel, and the series grouped by purpose of travel and state, revealing further rich and diverse dynamics across these series.
## 11.2 Single level approaches
Traditionally, forecasts of hierarchical or grouped time series involved selecting one level of aggregation and generating forecasts for that level. These are then either aggregated for higher levels, or disaggregated for lower levels, to obtain a set of coherent forecasts for the rest of the structure.
### The bottom-up approach
A simple method for generating coherent forecasts is the “bottom-up” approach. This approach involves first generating forecasts for each series at the bottom level, and then summing these to produce forecasts for all the series in the structure.
For example, for the hierarchy of Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree), we first generate \(h\)-step-ahead forecasts for each of the bottom-level series:
\[
\yhat{AA}{h},~~\yhat{AB}{h},~~\yhat{AC}{h},~~ \yhat{BA}{h}~~\text{and}~~\yhat{BB}{h}.
\]
(We have simplified the previously used notation of \(\hat{y}_{T+h|T}\) for brevity.)
Summing these, we get \(h\)-step-ahead coherent forecasts for the rest of the series:
\[\begin{align\*}
\tilde{y}_{h} & =\yhat{AA}{h}+\yhat{AB}{h}+\yhat{AC}{h}+\yhat{BA}{h}+\yhat{BB}{h}, \\
\ytilde{A}{h} & = \yhat{AA}{h}+\yhat{AB}{h}+\yhat{AC}{h}, \\
\text{and}\quad
\ytilde{B}{h} &= \yhat{BA}{h}+\yhat{BB}{h}.
\end{align\*}\]
(In this chapter, we will use the “tilde” notation to indicate coherent forecasts.)
An advantage of this approach is that we are forecasting at the bottom level of a structure, and therefore no information is lost due to aggregation. On the other hand, bottom-level data can be quite noisy and more challenging to model and forecast.
#### Example: Generating bottom-up forecasts
Suppose we want national and state forecasts for the Australian tourism data, but we arent interested in disaggregations using regions or the purpose of travel. So we first create a simple `tsibble` object containing only state and national trip totals for each quarter.
```
tourism_states <- tourism |>
aggregate_key(State, Trips = sum(Trips))
```
We could generate the bottom-level state forecasts first, and then sum them to obtain the national forecasts.
```
fcasts_state <- tourism_states |>
filter(!is_aggregated(State)) |>
model(ets = ETS(Trips)) |>
forecast()
# Sum bottom-level forecasts to get top-level forecasts
fcasts_national <- fcasts_state |>
summarise(value = sum(Trips), .mean = mean(value))
```
However, we want a more general approach that will work with all the forecasting methods discussed in this chapter. So we will use the `reconcile()` function to specify how we want to compute coherent forecasts.
```
tourism_states |>
model(ets = ETS(Trips)) |>
reconcile(bu = bottom_up(ets)) |>
forecast()
#> # A fable: 144 x 5 [1Q]
#> # Key: State, .model [18]
#> State .model Quarter
#> <chr*> <chr> <qtr>
#> 1 ACT ets 2018 Q1
#> 2 ACT ets 2018 Q2
#> 3 ACT ets 2018 Q3
#> 4 ACT ets 2018 Q4
#> 5 ACT ets 2019 Q1
#> 6 ACT ets 2019 Q2
#> 7 ACT ets 2019 Q3
#> 8 ACT ets 2019 Q4
#> 9 ACT bu 2018 Q1
#> 10 ACT bu 2018 Q2
#> # 134 more rows
#> # 2 more variables: Trips <dist>, .mean <dbl>
```
The `reconcile()` step has created a new “model” to produce bottom-up forecasts. The `fable` object contains the `ets` forecasts as well as the coherent `bu` forecasts, for the 8 states and the national aggregate. At the state level, these forecasts are identical, but the national `ets` forecasts will be different from the national `bu` forecasts.
For bottom-up forecasting, this is rather inefficient as we are not interested in the ETS model for the national total, and the resulting `fable` contains a lot of duplicates. But later we will introduce more advanced methods where we will need models for all levels of aggregation, and where the coherent forecasts are different from any of the original forecasts.
#### Workflow for forecasting aggregation structures
The above code illustrates the general workflow for hierarchical and grouped forecasts. We use the following pipeline of functions.
```
data |> aggregate_key() |> model() |>
reconcile() |> forecast()
```
1. Begin with a `tsibble` object (here labelled `data`) containing the individual bottom-level series.
2. Define in `aggregate_key()` the aggregation structure and build a `tsibble` object that also contains the aggregate series.
3. Identify a `model()` for each series, at all levels of aggregation.
4. Specify in `reconcile()` how the coherent forecasts are to be generated from the selected models.
5. Use the `forecast()` function to generate forecasts for the whole aggregation structure.
### Top-down approaches
Top-down approaches involve first generating forecasts for the Total series \(y_t\), and then disaggregating these down the hierarchy.
Let \(p_1,\dots,p_{m}\) denote a set of disaggregation proportions which determine how the forecasts of the Total series are to be distributed to obtain forecasts for each series at the bottom level of the structure. For example, for the hierarchy of Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree), using proportions \(p_1,\dots,p_{5}\) we get
\[
\ytilde{AA}{t}=p_1\hat{y}_t,~~~\ytilde{AB}{t}=p_2\hat{y}_t,~~~\ytilde{AC}{t}=p_3\hat{y}_t,~~~\ytilde{BA}{t}=p_4\hat{y}_t~~~\text{and}~~~~~~\ytilde{BB}{t}=p_5\hat{y}_t.
\]
Once the bottom-level \(h\)-step-ahead forecasts have been generated, these are aggregated to generate coherent forecasts for the rest of the series.
Top-down forecasts can be generated using `top_down()` within the `reconcile()` function.
There are several possible top-down methods that can be specified. The two most common top-down approaches specify disaggregation proportions based on the historical proportions of the data. These performed well in the study of Gross & Sohl ([1990](#ref-GroSoh1990)).
#### Average historical proportions
\[
p_j=\frac{1}{T}\sum_{t=1}^{T}\frac{y_{j,t}}{{y_t}}
\]
for \(j=1,\dots,m\). Each proportion \(p_j\) reflects the average of the historical proportions of the bottom-level series \(y_{j,t}\) over the period \(t=1,\dots,T\) relative to the total aggregate \(y_t\).
This approach is implemented in the `top_down()` function by setting `method = "average_proportions"`.
#### Proportions of the historical averages
\[
p_j={\sum_{t=1}^{T}\frac{y_{j,t}}{T}}\Big/{\sum_{t=1}^{T}\frac{y_t}{T}}
\]
for \(j=1,\dots,m\). Each proportion \(p_j\) captures the average historical value of the bottom-level series \(y_{j,t}\) relative to the average value of the total aggregate \(y_t\).
This approach is implemented in the `top_down()` function by setting `method = "proportion_averages"`.
A convenient attribute of such top-down approaches is their simplicity. One only needs to model and generate forecasts for the most aggregated top-level series. In general, these approaches seem to produce quite reliable forecasts for the aggregate levels and they are useful with low count data. On the other hand, one disadvantage is the loss of information due to aggregation. Using such top-down approaches, we are unable to capture and take advantage of individual series characteristics such as time dynamics, special events, different seasonal patterns, etc.
#### Forecast proportions
Because historical proportions used for disaggregation do not take account of how those proportions may change over time, top-down approaches based on historical proportions tend to produce less accurate forecasts at lower levels of the hierarchy than bottom-up approaches. To address this issue, proportions based on forecasts rather than historical data can be used ([Athanasopoulos et al., 2009](#ref-AthEtAl2009)).
Consider a one level hierarchy. We first generate \(h\)-step-ahead forecasts for all of the series. We dont use these forecasts directly, and they are not coherent (they dont add up correctly). Lets call these “initial” forecasts. We calculate the proportion of each \(h\)-step-ahead initial forecast at the bottom level, to the aggregate of all the \(h\)-step-ahead initial forecasts at this level. We refer to these as the forecast proportions, and we use them to disaggregate the top-level \(h\)-step-ahead initial forecast in order to generate coherent forecasts for the whole of the hierarchy.
For a \(K\)-level hierarchy, this process is repeated for each node, going from the top to the bottom level. Applying this process leads to the following general rule for obtaining the forecast proportions:
\[
p_j=\prod^{K-1}_{\ell=0}\frac{\hat{y}_{j,h}^{(\ell)}}{\hat{S}_{j,h}^{(\ell+1)}}
\]
where \(j=1,2,\dots,m\), \(\hat{y}_{j,h}^{(\ell)}\) is the \(h\)-step-ahead initial forecast of the series that corresponds to the node which is \(\ell\) levels above \(j\), and \(\hat{S}_{j,h}^{(\ell)}\) is the sum of the \(h\)-step-ahead initial forecasts below the node that is \(\ell\) levels above node \(j\) and are directly connected to that node. These forecast proportions disaggregate the \(h\)-step-ahead initial forecast of the Total series to get \(h\)-step-ahead coherent forecasts of the bottom-level series.
We will use the hierarchy of Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree) to explain this notation and to demonstrate how this general rule is reached. Assume we have generated initial forecasts for each series in the hierarchy. Recall that for the top-level “Total” series, \(\tilde{y}_{h}=\hat{y}_{h}\), for any top-down approach. Here are some examples using the above notation:
* \(\hat{y}_{\text{A},h}^{(1)}=\hat{y}_{\text{B},h}^{(1)}=\hat{y}_{h}= \tilde{y}_{h}\);
* \(\hat{y}_{\text{AA},h}^{(1)}=\hat{y}_{\text{AB},h}^{(1)}=\hat{y}_{\text{AC},h}^{(1)}= \hat{y}_{\text{A},h}\);
* \(\hat{y}_{\text{AA},h}^{(2)}=\hat{y}_{\text{AB},h}^{(2)}= \hat{y}_{\text{AC},h}^{(2)}=\hat{y}_{\text{BA},h}^{(2)}= \hat{y}_{\text{BB},h}^{(2)}=\hat{y}_{h}= \tilde{y}_{h}\);
* \(\Shat{AA}{h}{1} = \Shat{AB}{h}{1}= \Shat{AC}{h}{1}= \yhat{AA}{h}+\yhat{AB}{h}+\yhat{AC}{h}\);
* \(\Shat{AA}{h}{2} = \Shat{AB}{h}{2}= \Shat{AC}{h}{2}= \Shat{A}{h}{1} = \Shat{B}{h}{1}= \hat{S}_{h}= \yhat{A}{h}+\yhat{B}{h}\).
Moving down the farthest left branch of the hierarchy, coherent forecasts are given by
\[
\ytilde{A}{h} = \Bigg(\frac{\yhat{A}{h}}{\Shat{A}{h}{1}}\Bigg) \tilde{y}_{h} =
\Bigg(\frac{\yhat{AA}{h}^{(1)}}{\Shat{AA}{h}{2}}\Bigg) \tilde{y}_{h}
\]
and
\[
\ytilde{AA}{h} = \Bigg(\frac{\yhat{AA}{h}}{\Shat{AA}{h}{1}}\Bigg) \ytilde{A}{h}
=\Bigg(\frac{\yhat{AA}{h}}{\Shat{AA}{h}{1}}\Bigg) \Bigg(\frac{\yhat{AA}{h}^{(1)}}{\Shat{AA}{h}{2}}\Bigg)\tilde{y}_{h}.
\]
Consequently,
\[
p_1=\Bigg(\frac{\yhat{AA}{h}}{\Shat{AA}{h}{1}}\Bigg) \Bigg(\frac{\yhat{AA}{h}^{(1)}}{\Shat{AA}{h}{2}}\Bigg).
\]
The other proportions can be obtained similarly.
This approach is implemented in the `top_down()` function by setting `method = "forecast_proportions"`. Because this approach tends to work better than other top-down methods, it is the default choice in the `top_down()` function when no `method` argument is specified.
One disadvantage of all top-down approaches, is that they do not produce unbiased coherent forecasts ([Hyndman et al., 2011](#ref-HynEtAl2011)) even if the base forecasts are unbiased.
### Middle-out approach
The middle-out approach combines bottom-up and top-down approaches. Again, it can only be used for strictly hierarchical aggregation structures.
First, a “middle” level is chosen and forecasts are generated for all the series at this level. For the series above the middle level, coherent forecasts are generated using the bottom-up approach by aggregating the “middle-level” forecasts upwards. For the series below the “middle level”, coherent forecasts are generated using a top-down approach by disaggregating the “middle level” forecasts downwards.
This approach is implemented in the `middle_out()` function by specifying the appropriate middle level via the `level` argument and selecting the top-down approach with the `method` argument.
### Bibliography
Athanasopoulos, G., Ahmed, R. A., & Hyndman, R. J. (2009). Hierarchical forecasts for Australian domestic tourism. *International Journal of Forecasting*, *25*, 146166.
Gross, C. W., & Sohl, J. E. (1990). Disaggregation methods to expedite product line forecasting. *Journal of Forecasting*, *9*, 233254.
Hyndman, R. J., Ahmed, R. A., Athanasopoulos, G., & Shang, H. L. (2011). Optimal combination forecasts for hierarchical time series. *Computational Statistics and Data Analysis*, *55*(9), 25792589.
## 11.3 Forecast reconciliation
*Warning: the rest of this chapter is more advanced and assumes a knowledge of some basic matrix algebra.*
### Matrix notation
Recall that Equations [(11.1)](https://otexts.com/fpp3/hts.html#eq:toplevel) and [(11.2)](https://otexts.com/fpp3/hts.html#eq:middlelevel) represent how data, that adhere to the hierarchical structure of Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree), aggregate. Similarly [(11.3)](https://otexts.com/fpp3/hts.html#eq:middlelevelAB) and [(11.4)](https://otexts.com/fpp3/hts.html#eq:middlelevelXY) represent how data, that adhere to the grouped structure of Figure [11.6](https://otexts.com/fpp3/hts.html#fig:GroupTree), aggregate. These equations can be thought of as aggregation constraints or summing equalities, and can be more efficiently represented using matrix notation.
For any aggregation structure we construct an \(n\times m\) matrix \(\bm{S}\) (referred to as the “summing matrix”) which dictates the way in which the bottom-level series aggregate.
For the hierarchical structure in Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree), we can write
\[
\begin{bmatrix}
y_{t} \\
\y{A}{t} \\
\y{B}{t} \\
\y{AA}{t} \\
\y{AB}{t} \\
\y{AC}{t} \\
\y{BA}{t} \\
\y{BB}{t}
\end{bmatrix}
=
\begin{bmatrix}
1 & 1 & 1 & 1 & 1 \\
1 & 1 & 1 & 0 & 0 \\
0 & 0 & 0 & 1 & 1 \\
1 & 0 & 0 & 0 & 0 \\
0 & 1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 & 0 \\
0 & 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
\y{AA}{t} \\
\y{AB}{t} \\
\y{AC}{t} \\
\y{BA}{t} \\
\y{BB}{t}
\end{bmatrix}
\]
or in more compact notation
\[\begin{equation}
\bm{y}_t=\bm{S}\bm{b}_{t},
\tag{11.5}
\end{equation}\]
where \(\bm{y}_t\) is an \(n\)-dimensional vector of all the observations in the hierarchy at time \(t\), \(\bm{S}\) is the summing matrix, and \(\bm{b}_{t}\) is an \(m\)-dimensional vector of all the observations in the bottom level of the hierarchy at time \(t\). Note that the first row in the summing matrix \(\bm{S}\) represents Equation [(11.1)](https://otexts.com/fpp3/hts.html#eq:toplevel), the second and third rows represent [(11.2)](https://otexts.com/fpp3/hts.html#eq:middlelevel). The rows below these comprise an \(m\)-dimensional identity matrix \(\bm{I}_m\) so that each bottom-level observation on the right hand side of the equation is equal to itself on the left hand side.
Similarly for the grouped structure of Figure [11.6](https://otexts.com/fpp3/hts.html#fig:GroupTree) we write
\[
\begin{bmatrix}
y_{t} \\
\y{A}{t} \\
\y{B}{t} \\
\y{X}{t} \\
\y{Y}{t} \\
\y{AX}{t} \\
\y{AY}{t} \\
\y{BX}{t} \\
\y{BY}{t}
\end{bmatrix}
=
\begin{bmatrix}
1 & 1 & 1 & 1 \\
1 & 1 & 0 & 0 \\
0 & 0 & 1 & 1 \\
1 & 0 & 1 & 0 \\
0 & 1 & 0 & 1 \\
1 & 0 & 0 & 0 \\
0 & 1 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
\y{AX}{t} \\
\y{AY}{t} \\
\y{BX}{t} \\
\y{BY}{t}
\end{bmatrix},
\]
or
\[\begin{equation}
\bm{y}_t=\bm{S}\bm{b}_{t},
\tag{11.6}
\end{equation}\]
where the second and third rows of \(\bm{S}\) represent Equation [(11.3)](https://otexts.com/fpp3/hts.html#eq:middlelevelAB) and the fourth and fifth rows represent [(11.4)](https://otexts.com/fpp3/hts.html#eq:middlelevelXY).
### Mapping matrices
This matrix notation allows us to represent all forecasting methods for hierarchical or grouped time series using a common notation.
Suppose we forecast all series ignoring any aggregation constraints. We call these the **base forecasts** and denote them by \(\hat{\bm{y}}_h\) where \(h\) is the forecast horizon. They are stacked in the same order as the data \(\bm{y}_t\).
Then all coherent forecasting approaches for either hierarchical or grouped structures can be represented as[23](#fn23)
\[\begin{equation}
\tilde{\bm{y}}_h=\bm{S}\bm{G}\hat{\bm{y}}_h,
\tag{11.7}
\end{equation}\]
where \(\bm{G}\) is a matrix that maps the base forecasts into the bottom level, and the summing matrix \(\bm{S}\) sums these up using the aggregation structure to produce a set of **coherent forecasts** \(\tilde{\bm{y}}_h\).
The \(\bm{G}\) matrix is defined according to the approach implemented. For example if the bottom-up approach is used to forecast the hierarchy of Figure [11.1](https://otexts.com/fpp3/hts.html#fig:HierTree), then
\[\bm{G}=
\begin{bmatrix}
0 & 0 & 0 & 1 & 0 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 1 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 1 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 1 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\
\end{bmatrix}.
\]
Notice that \(\bm{G}\) contains two partitions. The first three columns zero out the base forecasts of the series above the bottom level, while the \(m\)-dimensional identity matrix picks only the base forecasts of the bottom level. These are then summed by the \(\bm{S}\) matrix.
If any of the top-down approaches were used then
\[
\bm{G}=
\begin{bmatrix}
p_1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
p_2 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
p_3 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
p_4 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
p_5 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
\end{bmatrix}.
\]
The first column includes the set of proportions that distribute the base forecasts of the top level to the bottom level. These are then summed up by the \(\bm{S}\) matrix. The rest of the columns zero out the base forecasts below the highest level of aggregation.
For a middle out approach, the \(\bm{G}\) matrix will be a combination of the above two. Using a set of proportions, the base forecasts of some pre-chosen level will be disaggregated to the bottom level, all other base forecasts will be zeroed out, and the bottom-level forecasts will then be summed up the hierarchy via the summing matrix.
### Forecast reconciliation
Equation [(11.7)](https://otexts.com/fpp3/reconciliation.html#eq:SG) shows that pre-multiplying any set of base forecasts with \(\bm{S}\bm{G}\) will return a set of coherent forecasts.
The traditional methods considered so far are limited in that they only use base forecasts from a single level of aggregation which have either been aggregated or disaggregated to obtain forecasts at all other levels. Hence, they use limited information. However, in general, we could use other \(\bm{G}\) matrices, and then \(\bm{S}\bm{G}\) combines and reconciles all the base forecasts in order to produce coherent forecasts.
In fact, we can find the optimal \(\bm{G}\) matrix to give the most accurate reconciled forecasts.
### The MinT optimal reconciliation approach
Wickramasuriya et al. ([2019](#ref-Mint)) found a \(\bm{G}\) matrix that minimises the total forecast variance of the set of coherent forecasts, leading to the MinT (Minimum Trace) optimal reconciliation approach.
Suppose we generate coherent forecasts using Equation [(11.7)](https://otexts.com/fpp3/reconciliation.html#eq:SG). First we want to make sure we have unbiased forecasts. If the base forecasts \(\hat{\bm{y}}_h\) are unbiased, then the coherent forecasts \(\tilde{\bm{y}}_h\) will be unbiased provided[24](#fn24) \(\bm{S}\bm{G}\bm{S}=\bm{S}\). This provides a constraint on the matrix \(\bm{G}\). Interestingly, no top-down method satisfies this constraint, so all top-down approaches result in biased coherent forecasts.
Next we need to find the errors in our forecasts. Wickramasuriya et al. ([2019](#ref-Mint)) show that the variance-covariance matrix of the \(h\)-step-ahead coherent forecast errors is given by
\[\begin{equation\*}
\bm{V}_h = \text{Var}[\bm{y}_{T+h}-\tilde{\bm{y}}_h]=\bm{S}\bm{G}\bm{W}_h\bm{G}'\bm{S}'
\end{equation\*}\]
where \(\bm{W}_h=\text{Var}[(\bm{y}_{T+h}-\hat{\bm{y}}_h)]\) is the variance-covariance matrix of the corresponding base forecast errors.
The objective is to find a matrix \(\bm{G}\) that minimises the error variances of the coherent forecasts. These error variances are on the diagonal of the matrix \(\bm{V}_h\), and so the sum of all the error variances is given by the trace of the matrix \(\bm{V}_h\). Wickramasuriya et al. ([2019](#ref-Mint)) show that the matrix \(\bm{G}\) which minimises the trace of \(\bm{V}_h\) such that \(\bm{S}\bm{G}\bm{S}=\bm{S}\), is given by
\[
\bm{G}=(\bm{S}'\bm{W}_h^{-1}\bm{S})^{-1}\bm{S}'\bm{W}_h^{-1}.
\]
Therefore, the optimally reconciled forecasts are given by
\[\begin{equation}
\tag{11.8}
\tilde{\bm{y}}_h=\bm{S}(\bm{S}'\bm{W}_h^{-1}\bm{S})^{-1}\bm{S}'\bm{W}_h^{-1}\hat{\bm{y}}_h.
\end{equation}\]
We refer to this as the MinT (or Minimum Trace) optimal reconciliation approach. MinT is implemented by `min_trace()` within the `reconcile()` function.
To use this in practice, we need to estimate \(\bm{W}_h\), the forecast error variance of the \(h\)-step-ahead base forecasts. This can be difficult, and so we provide four simplifying approximations that have been shown to work well in both simulations and in practice.
1. Set \(\bm{W}_h=k_h\bm{I}\) for all \(h\), where \(k_{h} > 0\).[25](#fn25) This is the most simplifying assumption to make, and means that \(\bm{G}\) is independent of the data, providing substantial computational savings. The disadvantage, however, is that this specification does not account for the differences in scale between the levels of the structure, or for relationships between series.
Setting \(\bm{W}_h=k_h\bm{I}\) in [(11.8)](https://otexts.com/fpp3/reconciliation.html#eq:MinT) gives the ordinary least squares (OLS) estimator we introduced in Section [7.9](https://otexts.com/fpp3/regression-matrices.html#regression-matrices) with \(\bm{X}=\bm{S}\) and \(\bm{y}=\hat{\bm{y}}\). Hence this approach is usually referred to as OLS reconciliation. It is implemented in `min_trace()` by setting `method = "ols"`.
2. Set \(\bm{W}_{h} = k_{h}\text{diag}(\hat{\bm{W}}_{1})\) for all \(h\), where \(k_{h} > 0\),
\[
\hat{\bm{W}}_{1} = \frac{1}{T}\sum_{t=1}^{T}\bm{e}_{t}\bm{e}_{t}',
\]
and \(\bm{e}_{t}\) is an \(n\)-dimensional vector of residuals of the models that generated the base forecasts stacked in the same order as the data.
This specification scales the base forecasts using the variance of the residuals and it is therefore referred to as the WLS (weighted least squares) estimator using *variance scaling*. The approach is implemented in `min_trace()` by setting `method = "wls_var"`.
3. Set \(\bm{W}_{h}=k_{h}\bm{\Lambda}\) for all \(h\), where \(k_{h} > 0\), \(\bm{\Lambda}=\text{diag}(\bm{S}\bm{1})\), and \(\bm{1}\) is a unit vector of dimension \(m\) (the number of bottom-level series). This specification assumes that the bottom-level base forecast errors each have variance \(k_{h}\) and are uncorrelated between nodes. Hence each element of the diagonal \(\bm{\Lambda}\) matrix contains the number of forecast error variances contributing to each node. This estimator only depends on the structure of the aggregations, and not on the actual data. It is therefore referred to as *structural scaling*. Applying the structural scaling specification is particularly useful in cases where residuals are not available, and so variance scaling cannot be applied; for example, in cases where the base forecasts are generated by judgmental forecasting (Chapter [6](https://otexts.com/fpp3/judgmental.html#judgmental)). The approach is implemented in `min_trace()` by setting `method = "wls_struct"`.
4. Set \(\bm{W}_h = k_h \hat{\bm{W}}_1\) for all \(h\), where \(k_h>0\). Here we only assume that the error covariance matrices are proportional to each other, and we directly estimate the full one-step covariance matrix \(\bm{W}_1\). The most obvious and simple way would be to use the sample covariance. This is implemented in `min_trace()` by setting `method = "mint_cov"`.
However, for cases where the number of bottom-level series \(m\) is large compared to the length of the series \(T\), this is not a good estimator. Instead we use a shrinkage estimator which shrinks the sample covariance to a diagonal matrix. This is implemented in `min_trace()` by setting `method = "mint_shrink"`.
In summary, unlike any other existing approach, the optimal reconciliation forecasts are generated using all the information available within a hierarchical or a grouped structure. This is important, as particular aggregation levels or groupings may reveal features of the data that are of interest to the user and are important to be modelled. These features may be completely hidden or not easily identifiable at other levels.
For example, consider the Australian tourism data introduced in Section [11.1](https://otexts.com/fpp3/hts.html#hts), where the hierarchical structure followed the geographic division of a country into states and regions. Some areas will be largely summer destinations, while others may be winter destinations. We saw in Figure [11.4](https://otexts.com/fpp3/hts.html#fig:seasonStates) the contrasting seasonal patterns between the northern and the southern states. These differences will be smoothed at the country level due to aggregation.
### Bibliography
Hyndman, R. J., Ahmed, R. A., Athanasopoulos, G., & Shang, H. L. (2011). Optimal combination forecasts for hierarchical time series. *Computational Statistics and Data Analysis*, *55*(9), 25792589.
Panagiotelis, A., Athanasopoulos, G., Gamakumara, P., & Hyndman, R. J. (2021). Forecast reconciliation: A geometric view with new insights on bias correction. *International Journal of Forecasting*, *37*(1), 343359.
Wickramasuriya, S. L., Athanasopoulos, G., & Hyndman, R. J. (2019). Optimal forecast reconciliation for hierarchical and grouped time series through trace minimization. *Journal of the American Statistical Association*, *114*(526), 804819.
---
23. Actually, some recent nonlinear reconciliation methods require a slightly more complicated equation. This equation is for general linear reconciliation methods.[↩︎](https://otexts.com/fpp3/reconciliation.html#fnref23)
24. This “unbiasedness preserving” constraint was first introduced in Hyndman et al. ([2011](#ref-HynEtAl2011)). Panagiotelis et al. ([2021](#ref-PanEtAl2020_Geometry)) show that this is equivalent to \(\bm{S}\bm{G}\) being a projection matrix onto the \(m\)-dimensional coherent subspace for which the aggregation constraints hold.[↩︎](https://otexts.com/fpp3/reconciliation.html#fnref24)
25. Note that \(k_{h}\) is a proportionality constant. It does not need to be estimated or specified here as it gets cancelled out in [(11.8)](https://otexts.com/fpp3/reconciliation.html#eq:MinT).[↩︎](https://otexts.com/fpp3/reconciliation.html#fnref25)
## 11.4 Forecasting Australian domestic tourism
We will compute forecasts for the Australian tourism data that was described in Section [11.1](https://otexts.com/fpp3/hts.html#hts). We use the data up to the end of 2015 as a training set, withholding the final two years (eight quarters, 2016Q12017Q4) as a test set for evaluation. The code below demonstrates the full workflow for generating coherent forecasts using the bottom-up, OLS and MinT methods.
```
tourism_full <- tourism |>
aggregate_key((State/Region) * Purpose, Trips = sum(Trips))
fit <- tourism_full |>
filter(year(Quarter) <= 2015) |>
model(base = ETS(Trips)) |>
reconcile(
bu = bottom_up(base),
ols = min_trace(base, method = "ols"),
mint = min_trace(base, method = "mint_shrink")
)
```
Here, `fit` contains the `base` ETS model (discussed in Chapter [8](https://otexts.com/fpp3/expsmooth.html#expsmooth)) for each series in `tourism_full`, along with the three methods for producing coherent forecasts as specified in the `reconcile()` function.
```
fc <- fit |> forecast(h = "2 years")
```
Passing `fit` into `forecast()` generates base and coherent forecasts across all the series in the aggregation structure. Figures [11.12](https://otexts.com/fpp3/tourism.html#fig:tourism-states) and [11.13](https://otexts.com/fpp3/tourism.html#fig:tourism-purpose) plot the four point forecasts for the overnight trips for the Australian total, the states, and the purposes of travel, along with the actual observations of the test set.
```
fc |>
filter(is_aggregated(Region), is_aggregated(Purpose)) |>
autoplot(
tourism_full |> filter(year(Quarter) >= 2011),
level = NULL
) +
labs(y = "Trips ('000)") +
facet_wrap(vars(State), scales = "free_y")
```
![Forecasts of overnight trips for Australia and its states over the test period 2016Q1--2017Q4.](https://otexts.com/fpp3/fpp_files/figure-html/tourism-states-1.png)
Figure 11.12: Forecasts of overnight trips for Australia and its states over the test period 2016Q12017Q4.
```
fc |>
filter(is_aggregated(State), !is_aggregated(Purpose)) |>
autoplot(
tourism_full |> filter(year(Quarter) >= 2011),
level = NULL
) +
labs(y = "Trips ('000)") +
facet_wrap(vars(Purpose), scales = "free_y")
```
![Forecasts of overnight trips by purpose of travel over the test period 2016Q1--2017Q4.](https://otexts.com/fpp3/fpp_files/figure-html/tourism-purpose-1.png)
Figure 11.13: Forecasts of overnight trips by purpose of travel over the test period 2016Q12017Q4.
To make it easier to see the differences, we have included only the last five years of the training data, and have omitted the prediction intervals. In most panels, the increase in overnight trips, especially in the second half of the test set, is higher than what is predicted by the point forecasts. This is particularly noticeable for the mainland eastern states of ACT, New South Wales, Queensland and Victoria, and across all purposes of travel.
The accuracy of the forecasts over the test set can be evaluated using the `accuracy()` function. We summarise some results in Table [11.2](https://otexts.com/fpp3/tourism.html#tab:tourism-evaluation) using RMSE and MASE.
Table 11.2: Accuracy of forecasts for Australian overnight trips over the test set 2016Q12017Q4.
| | RMSE | | | | MASE | | | |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| | Base | Bottom-up | MinT | OLS | Base | Bottom-up | MinT | OLS |
| Total | 1720.72 | 3071.11 | 2157.55 | 1803.51 | 1.53 | 3.17 | 2.09 | 1.63 |
| Purpose | 533.02 | 802.68 | 586.45 | 513.18 | 1.33 | 2.32 | 1.51 | 1.25 |
| State | 306.85 | 417.21 | 329.74 | 294.66 | 1.40 | 1.88 | 1.45 | 1.27 |
| Regions | 52.64 | 55.13 | 47.40 | 46.95 | 1.13 | 1.18 | 1.02 | 1.00 |
| Bottom | 19.38 | 19.38 | 17.97 | 18.32 | 0.98 | 0.98 | 0.94 | 1.02 |
| All series | 45.96 | 55.28 | 45.61 | 43.19 | 1.04 | 1.08 | 0.98 | 1.03 |
The scales of the series at different levels of aggregation are quite different, due to aggregation. Hence, we need to be cautious when comparing or calculating scale dependent error measures, such as the RMSE, across levels as the aggregate series will dominate. Therefore, we compare error measures across each level of aggregation, before providing the error measures across all the series in the bottom-row. Notice, that the RMSE increases as we go from the bottom level to the aggregate levels above.
The following code generates the accuracy measures for the aggregate series shown in the first row of the table. Similar code is used to evaluate forecasts for other levels.
```
fc |>
filter(is_aggregated(State), is_aggregated(Purpose)) |>
accuracy(
data = tourism_full,
measures = list(rmse = RMSE, mase = MASE)
) |>
group_by(.model) |>
summarise(rmse = mean(rmse), mase = mean(mase))
#> # A tibble: 4 × 3
#> .model rmse mase
#> <chr> <dbl> <dbl>
#> 1 base 1721. 1.53
#> 2 bu 3071. 3.17
#> 3 mint 2158. 2.09
#> 4 ols 1804. 1.63
```
Reconciling the base forecasts using OLS and MinT results in more accurate forecasts compared to the bottom-up approach. This result is commonly observed in applications as reconciliation approaches use information from all levels of the structure, resulting in more accurate coherent forecasts compared to the older traditional methods which use limited information. Furthermore, reconciliation usually improves the incoherent base forecasts for almost all levels.
## 11.5 Reconciled distributional forecasts
So far we have only discussed the reconciliation of point forecasts. However, we are usually also interested in the forecast distributions so that we can compute prediction intervals.
Panagiotelis et al. ([2023](#ref-PanEtAl2020_Probabilistic)) present several important results for generating reconciled probabilistic forecasts. We focus here on two fundamental results that are implemented in the `reconcile()` function.
1. If the base forecasts are normally distributed, i.e.,
\[
\hat{\bm{y}}_h\sim N(\hat{\bm\mu}_h,\hat{\bm\Sigma}_h),
\]
then the reconciled forecasts are also normally distributed,
\[
\tilde{\bm{y}}_h \sim N(\bm{S}\bm{G}\hat{\bm{\mu}}_h,\bm{S}\bm{G}\hat{\bm{\Sigma}}_{h}\bm{G}'\bm{S}').
\]
2. If it is unreasonable to assume normality for the base forecasts, we can use bootstrapping. Bootstrapped prediction intervals were introduced in Section [5.5](https://otexts.com/fpp3/prediction-intervals.html#prediction-intervals). The same idea can be used here. We can simulate future sample paths from the model(s) that produce the base forecasts, and then reconcile these sample paths. Coherent prediction intervals can be computed from the reconciled sample paths.
Suppose that \((\hat{\bm{y}}_h^{[1]},\dots,\hat{\bm{y}}_h^{[B]})\) are a set of \(B\) simulated sample paths, generated independently from the models used to produce the base forecasts. Then \((\bm{S}\bm{G}\hat{\bm{y}}_h^{[1]},\dots,\bm{S}\bm{G}\hat{\bm{y}}_h^{[B]})\) provides a set of reconciled sample paths, from which percentiles can be calculated in order to construct coherent prediction intervals.
To generate bootstrapped prediction intervals in this way, we simply set `bootstrap = TRUE` in the `forecast()` function.
### Bibliography
Panagiotelis, A., Gamakumara, P., Athanasopoulos, G., & Hyndman, R. J. (2023). Probabilistic forecast reconciliation: Properties, evaluation and score optimisation. *European J Operational Research*, *306*(2), 693706.
## 11.6 Forecasting Australian prison population
Returning to the Australian prison population data (Section [11.1](https://otexts.com/fpp3/hts.html#hts)), we will compare the forecasts from bottom-up and MinT methods applied to base ETS models, using a test set comprising the final two years or eight quarters 2015Q12016Q4 of the available data.
```
fit <- prison_gts |>
filter(year(Quarter) <= 2014) |>
model(base = ETS(Count)) |>
reconcile(
bottom_up = bottom_up(base),
MinT = min_trace(base, method = "mint_shrink")
)
fc <- fit |> forecast(h = 8)
```
```
fc |>
filter(is_aggregated(State), is_aggregated(Gender),
is_aggregated(Legal)) |>
autoplot(prison_gts, alpha = 0.7, level = 90) +
labs(y = "Number of prisoners ('000)",
title = "Australian prison population (total)")
```
![Forecasts for the total Australian quarterly adult prison population for the period 2015Q1--2016Q4.](https://otexts.com/fpp3/fpp_files/figure-html/prisonforecasts-aggregate-1.png)
Figure 11.14: Forecasts for the total Australian quarterly adult prison population for the period 2015Q12016Q4.
Figure [11.14](https://otexts.com/fpp3/prison.html#fig:prisonforecasts-aggregate) shows the three sets of forecasts for the aggregate Australian prison population. The base and bottom-up forecasts from the ETS models seem to underestimate the trend over the test period. The MinT approach combines information from all the base forecasts in the aggregation structure; in this case, the base forecasts at the top level are adjusted upwards.
The MinT reconciled prediction intervals are much tighter than the base forecasts, due to MinT being based on an estimator that minimizes variances. The base forecast distributions are also incoherent, and therefore carry with them the extra uncertainty of the incoherency error.
We exclude the bottom-up forecasts from the remaining plots in order to simplify the visual exploration. However, we do revisit their accuracy in the evaluation results presented later.
Figures [11.15](https://otexts.com/fpp3/prison.html#fig:prisonforecasts-State)[11.17](https://otexts.com/fpp3/prison.html#fig:prisonforecasts-bottom) show the MinT and base forecasts at various levels of aggregation. To make it easier to see the effect, we only show the last five years of training data. In general, MinT adjusts the base forecasts in the direction of the test set, hence improving the forecast accuracy. There is no guarantee that MinT reconciled forecasts will be more accurate than the base forecasts for every series, but they will be more accurate on average (see [Panagiotelis et al., 2021](#ref-PanEtAl2020_Geometry)).
```
fc |>
filter(
.model %in% c("base", "MinT"),
!is_aggregated(State), is_aggregated(Legal),
is_aggregated(Gender)
) |>
autoplot(
prison_gts |> filter(year(Quarter) >= 2010),
alpha = 0.7, level = 90
) +
labs(title = "Prison population (by state)",
y = "Number of prisoners ('000)") +
facet_wrap(vars(State), scales = "free_y", ncol = 4) +
theme(axis.text.x = element_text(angle = 90, hjust = 1))
```
![Forecasts for the Australian quarterly adult prison population, disaggregated by state.](https://otexts.com/fpp3/fpp_files/figure-html/prisonforecasts-State-1.png)
Figure 11.15: Forecasts for the Australian quarterly adult prison population, disaggregated by state.
Figure [11.15](https://otexts.com/fpp3/prison.html#fig:prisonforecasts-State) shows forecasts for each of the eight states. There is a general upward trend during the test set period across all the states. However, there appears to be a relatively large and sudden surge in New South Wales and Tasmania, which means the test set observations are well outside the upper bound of the forecast intervals for both these states. Because New South Wales is the state with the largest prison population, this surge will have a substantial impact on the total. In contrast, Victoria shows a substantial dip in 2015Q22015Q3, before returning to an upward trend. This dip is not captured in any of the Victorian forecasts.
![Forecasts for the Australian quarterly adult prison population, disaggregated by legal status and by gender.](https://otexts.com/fpp3/fpp_files/figure-html/prisonforecasts-LegalGender-1.png)
Figure 11.16: Forecasts for the Australian quarterly adult prison population, disaggregated by legal status and by gender.
![Forecasts for bottom-level series the Australian quarterly adult prison population, disaggregated by state, by legal status and by gender.](https://otexts.com/fpp3/fpp_files/figure-html/prisonforecasts-bottom-1.png)
Figure 11.17: Forecasts for bottom-level series the Australian quarterly adult prison population, disaggregated by state, by legal status and by gender.
Figure [11.17](https://otexts.com/fpp3/prison.html#fig:prisonforecasts-bottom) shows the forecasts for some selected bottom-level series of the Australian prison population. The four largest states are represented across the columns, with legal status and gender down the rows. These allow for some interesting analysis and observations that have policy implications. The large increase observed across the states during the 2015Q12016Q4 test period appears to be driven by large increases in the remand prison population. These increases seem to be generally missed by both forecasts. In contrast to the other states, for New South Wales there is also a substantial increase in the sentenced prison population. In particular, the increase in numbers of sentenced males in NSW contributes substantially to the rise in state and national prison numbers.
Using the `accuracy()` function, we evaluate the forecast accuracy across the grouped structure. The code below evaluates the forecast accuracy for only the top-level national aggregate of the Australian prison population time series. Similar code is used for the rest of the results shown in Table [11.3](https://otexts.com/fpp3/prison.html#tab:tab-crime-evaluation).
```
fc |>
filter(is_aggregated(State), is_aggregated(Gender),
is_aggregated(Legal)) |>
accuracy(data = prison_gts,
measures = list(mase = MASE,
ss = skill_score(CRPS)
)
) |>
group_by(.model) |>
summarise(mase = mean(mase), sspc = mean(ss) * 100)
#> # A tibble: 3 × 3
#> .model mase sspc
#> <chr> <dbl> <dbl>
#> 1 MinT 0.895 76.8
#> 2 base 1.72 55.9
#> 3 bottom_up 1.84 33.5
```
Table [11.3](https://otexts.com/fpp3/prison.html#tab:tab-crime-evaluation) summarises the accuracy of the base, bottom-up and the MinT reconciled forecasts over the 2015Q12016Q4 test period across each of the levels of the grouped aggregation structure as well as all the levels.
Table 11.3: Accuracy of Australian prison population forecasts for different groups of series.
| | MASE | | | Skill Score (CRPS) | | |
| --- | --- | --- | --- | --- | --- | --- |
| | Base | Bottom-up | MinT | Base | Bottom-up | MinT |
| Total | 1.72 | 1.84 | 0.90 | 55.91 | 33.46 | 76.80 |
| State | 2.12 | 1.88 | 1.78 | 6.40 | 24.10 | 22.46 |
| Legal status | 2.89 | 2.68 | 2.32 | 22.22 | 50.27 | 45.23 |
| Gender | 0.89 | 1.76 | 0.91 | 68.98 | 27.49 | 71.06 |
| Bottom | 2.23 | 2.23 | 2.06 | 0.93 | 0.93 | -3.23 |
| All series | 2.19 | 2.16 | 1.96 | 6.70 | 11.29 | 8.69 |
We use scaled measures because the numbers of prisoners vary substantially across the groups. The MASE gives a scaled measure of point-forecast accuracy (see Section [5.8](https://otexts.com/fpp3/accuracy.html#accuracy)), while the CRPS skill score gives a scaled measure of distributional forecast accuracy (see Section [5.9](https://otexts.com/fpp3/distaccuracy.html#distaccuracy)). A low value of MASE indicates a good forecast, while a high value of the skill score indicates a good forecast.
The results show that the MinT reconciled forecasts improve on the accuracy of the base forecasts and are also more accurate than the bottom-up forecasts. As the MinT optimal reconciliation approach uses information from all levels in the structure, it generates more accurate forecasts than the traditional approaches (such as bottom-up) which use limited information.
### Bibliography
Panagiotelis, A., Athanasopoulos, G., Gamakumara, P., & Hyndman, R. J. (2021). Forecast reconciliation: A geometric view with new insights on bias correction. *International Journal of Forecasting*, *37*(1), 343359.
## 11.7 Exercises
1. Consider the `PBS` data which has aggregation structure `ATC1/ATC2 * Concession * Type`.
1. Produce plots of the aggregated Scripts data by `Concession`, `Type` and `ATC1`.
2. Forecast the PBS Scripts data using ETS, ARIMA and SNAIVE models, applied to all but the last three years of data.
3. Reconcile each of the forecasts using MinT.
4. Which type of model works best on the test set?
5. Does the reconciliation improve the forecast accuracy?
6. Why doesnt the reconciliation make any difference to the SNAIVE forecasts?
2. Repeat the `tourism` example from Section [11.4](https://otexts.com/fpp3/tourism.html#tourism), but also evaluate the forecast distribution accuracy using CRPS skill scores. Which method does best on this measure?
3. Repeat the `prison` example from Section [11.6](https://otexts.com/fpp3/prison.html#prison), but using a bootstrap to generate the forecast distributions rather than assuming normality. Does it make much difference to the CRPS skill scores?
## 11.8 Further reading
There are no other textbooks which cover hierarchical forecasting in any depth, so interested readers will need to tackle the original research papers for further information.
* Gross & Sohl ([1990](#ref-GroSoh1990)) provide a good introduction to the top-down approaches.
* A recent survey of forecast reconciliation is provided by Athanasopoulos et al. ([2020](#ref-macrohts)).
* The reconciliation methods were developed in a series of papers. The later papers summarise previous results and present the most general theory: Wickramasuriya et al. ([2019](#ref-Mint)), Panagiotelis et al. ([2021](#ref-PanEtAl2020_Geometry)), Panagiotelis et al. ([2023](#ref-PanEtAl2020_Probabilistic)).
* Athanasopoulos et al. ([2017](#ref-AthEtAl2017)) extends the reconciliation approach to deal with temporal hierarchies.
* The tourism example is discussed in more detail in Athanasopoulos et al. ([2009](#ref-AthEtAl2009)), Wickramasuriya et al. ([2019](#ref-Mint)), and Kourentzes & Athanasopoulos ([2019](#ref-KouAth2019)).
### Bibliography
Athanasopoulos, G., Ahmed, R. A., & Hyndman, R. J. (2009). Hierarchical forecasts for Australian domestic tourism. *International Journal of Forecasting*, *25*, 146166.
Athanasopoulos, G., Gamakumara, P., Panagiotelis, A., Hyndman, R. J., & Affan, M. (2020). Hierarchical forecasting. In P. Fuleky (Ed.), *Macroeconomic forecasting in the era of big data* (pp. 689719). Springer.
Athanasopoulos, G., Hyndman, R. J., Kourentzes, N., & Petropoulos, F. (2017). Forecasting with temporal hierarchies. *European Journal of Operational Research*, *262*(1), 6074.
Gross, C. W., & Sohl, J. E. (1990). Disaggregation methods to expedite product line forecasting. *Journal of Forecasting*, *9*, 233254.
Kourentzes, N., & Athanasopoulos, G. (2019). Cross-temporal coherent forecasts for Australian tourism. *Annals of Tourism Research*, *75*, 393409.
Panagiotelis, A., Athanasopoulos, G., Gamakumara, P., & Hyndman, R. J. (2021). Forecast reconciliation: A geometric view with new insights on bias correction. *International Journal of Forecasting*, *37*(1), 343359.
Panagiotelis, A., Gamakumara, P., Athanasopoulos, G., & Hyndman, R. J. (2023). Probabilistic forecast reconciliation: Properties, evaluation and score optimisation. *European J Operational Research*, *306*(2), 693706.
Wickramasuriya, S. L., Athanasopoulos, G., & Hyndman, R. J. (2019). Optimal forecast reconciliation for hierarchical and grouped time series through trace minimization. *Journal of the American Statistical Association*, *114*(526), 804819.
+702
View File
@@ -0,0 +1,702 @@
Source: https://otexts.com/fpp3/advanced.html (chapter advanced, 8 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 12-advanced-methods
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 12 Advanced forecasting methods
In this chapter, we briefly discuss several more advanced forecasting methods that build on the models discussed in earlier chapters.
## 12.1 Complex seasonality
So far, we have mostly considered relatively simple seasonal patterns such as quarterly and monthly data. However, higher frequency time series often exhibit more complicated seasonal patterns. For example, daily data may have a weekly pattern as well as an annual pattern. Hourly data usually has three types of seasonality: a daily pattern, a weekly pattern, and an annual pattern. Even weekly data can be challenging to forecast as there are not a whole number of weeks in a year, so the annual pattern has a seasonal period of \(365.25/7\approx 52.179\) on average. Most of the methods we have considered so far are unable to deal with these seasonal complexities.
We dont necessarily want to include all of the possible seasonal periods in our models — just the ones that are likely to be present in the data. For example, if we have only 180 days of data, we may ignore the annual seasonality. If the data are measurements of a natural phenomenon (e.g., temperature), we can probably safely ignore any weekly seasonality.
Figure [12.1](https://otexts.com/fpp3/complexseasonality.html#fig:calls) shows the number of calls to a North American commercial bank per 5-minute interval between 7:00am and 9:05pm each weekday over a 33 week period. The lower panel shows the first four weeks of the same time series. There is a strong daily seasonal pattern with period 169 (there are 169 5-minute intervals per day), and a weak weekly seasonal pattern with period \(169 \times 5=845\). (Call volumes on Mondays tend to be higher than the rest of the week.) If a longer series of data were available, we may also have observed an annual seasonal pattern.
```
bank_calls |>
fill_gaps() |>
autoplot(Calls) +
labs(y = "Calls",
title = "Five-minute call volume to bank")
```
![Five-minute call volume handled on weekdays between 7:00am and 9:05pm in a large North American commercial bank. Top panel: data from 3 March -- 24 October 2003. Bottom panel: first four weeks of data.](https://otexts.com/fpp3/fpp_files/figure-html/calls-1.png)
Figure 12.1: Five-minute call volume handled on weekdays between 7:00am and 9:05pm in a large North American commercial bank. Top panel: data from 3 March 24 October 2003. Bottom panel: first four weeks of data.
Apart from the multiple seasonal periods, this series has the additional complexity of missing values between the working periods.
### STL with multiple seasonal periods
The `STL()` function is designed to deal with multiple seasonality. It will return multiple seasonal components, as well as a trend and remainder component. In this case, we need to re-index the tsibble to avoid the missing values, and then explicitly give the seasonal periods.
```
calls <- bank_calls |>
mutate(t = row_number()) |>
update_tsibble(index = t, regular = TRUE)
```
```
calls |>
model(
STL(sqrt(Calls) ~ season(period = 169) +
season(period = 5*169),
robust = TRUE)
) |>
components() |>
autoplot() + labs(x = "Observation")
```
![STL decomposition with multiple seasonality for the call volume data.](https://otexts.com/fpp3/fpp_files/figure-html/callsmstl-1.png)
Figure 12.2: STL decomposition with multiple seasonality for the call volume data.
There are two seasonal patterns shown, one for the time of day (the third panel), and one for the time of week (the fourth panel). To properly interpret this graph, it is important to notice the vertical scales. In this case, the trend and the weekly seasonality have wider bars (and therefore relatively narrower ranges) compared to the other components, because there is little trend seen in the data, and the weekly seasonality is weak.
The decomposition can also be used in forecasting, with each of the seasonal components forecast using a seasonal naïve method, and the seasonally adjusted data forecast using ETS.
The code is slightly more complicated than usual because we have to add back the time stamps that were lost when we re-indexed the tsibble to handle the periods of missing observations. The square root transformation used in the STL decomposition has ensured the forecasts remain positive.
```
# Forecasts from STL+ETS decomposition
my_dcmp_spec <- decomposition_model(
STL(sqrt(Calls) ~ season(period = 169) +
season(period = 5*169),
robust = TRUE),
ETS(season_adjust ~ season("N"))
)
fc <- calls |>
model(my_dcmp_spec) |>
forecast(h = 5 * 169)
# Add correct time stamps to fable
fc_with_times <- bank_calls |>
new_data(n = 7 * 24 * 60 / 5) |>
mutate(time = format(DateTime, format = "%H:%M:%S")) |>
filter(
time %in% format(bank_calls$DateTime, format = "%H:%M:%S"),
wday(DateTime, week_start = 1) <= 5
) |>
mutate(t = row_number() + max(calls$t)) |>
left_join(fc, by = "t") |>
as_fable(response = "Calls", distribution = Calls)
# Plot results with last 3 weeks of data
fc_with_times |>
fill_gaps() |>
autoplot(bank_calls |> tail(14 * 169) |> fill_gaps()) +
labs(y = "Calls",
title = "Five-minute call volume to bank")
```
![Forecasts of the call volume data using an STL decomposition with the seasonal components forecast using a seasonal naïve method, and the seasonally adjusted data forecast using ETS.](https://otexts.com/fpp3/fpp_files/figure-html/callsmstlf-1.png)
Figure 12.3: Forecasts of the call volume data using an STL decomposition with the seasonal components forecast using a seasonal naïve method, and the seasonally adjusted data forecast using ETS.
### Dynamic harmonic regression with multiple seasonal periods
With multiple seasonalities, we can use Fourier terms as we did in earlier chapters (see Sections [7.4](https://otexts.com/fpp3/useful-predictors.html#useful-predictors) and [10.5](https://otexts.com/fpp3/dhr.html#dhr)). Because there are multiple seasonalities, we need to add Fourier terms for each seasonal period. In this case, the seasonal periods are 169 and 845, so the Fourier terms are of the form
\[
\sin\left(\frac{2\pi kt}{169}\right), \quad
\cos\left(\frac{2\pi kt}{169}\right), \quad
\sin\left(\frac{2\pi kt}{845}\right), \quad \text{and} \quad
\cos\left(\frac{2\pi kt}{845}\right),
\]
for \(k=1,2,\dots\). As usual, the `fourier()` function can generate these for you.
We will fit a dynamic harmonic regression model with an ARIMA error structure. The total number of Fourier terms for each seasonal period could be selected to minimise the AICc. However, for high seasonal periods, this tends to over-estimate the number of terms required, so we will use a more subjective choice with 10 terms for the daily seasonality and 5 for the weekly seasonality. Again, we will use a square root transformation to ensure the forecasts and prediction intervals remain positive. We set \(D=d=0\) in order to handle the non-stationarity through the regression terms, and \(P=Q=0\) in order to handle the seasonality through the regression terms.
```
fit <- calls |>
model(
dhr = ARIMA(sqrt(Calls) ~ PDQ(0, 0, 0) + pdq(d = 0) +
fourier(period = 169, K = 10) +
fourier(period = 5*169, K = 5)))
fc <- fit |> forecast(h = 5 * 169)
# Add correct time stamps to fable
fc_with_times <- bank_calls |>
new_data(n = 7 * 24 * 60 / 5) |>
mutate(time = format(DateTime, format = "%H:%M:%S")) |>
filter(
time %in% format(bank_calls$DateTime, format = "%H:%M:%S"),
wday(DateTime, week_start = 1) <= 5
) |>
mutate(t = row_number() + max(calls$t)) |>
left_join(fc, by = "t") |>
as_fable(response = "Calls", distribution = Calls)
```
```
# Plot results with last 3 weeks of data
fc_with_times |>
fill_gaps() |>
autoplot(bank_calls |> tail(14 * 169) |> fill_gaps()) +
labs(y = "Calls",
title = "Five-minute call volume to bank")
```
![Forecasts from a dynamic harmonic regression applied to the call volume data.](https://otexts.com/fpp3/fpp_files/figure-html/callsharmonics-1.png)
Figure 12.4: Forecasts from a dynamic harmonic regression applied to the call volume data.
This is a large model, containing 33 parameters: 4 ARMA coefficients, 20 Fourier coefficients for period 169, and 8 Fourier coefficients for period 845. Not all of the Fourier terms for period 845 are used because there is some overlap with the terms of period 169 (since \(845=5\times169\)).
### Example: Electricity demand
One common application of such models is electricity demand modelling. Figure [12.5](https://otexts.com/fpp3/complexseasonality.html#fig:elecdemand) shows half-hourly electricity demand (MWh) in Victoria, Australia, during 20122014, along with temperatures (degrees Celsius) for the same period for Melbourne (the largest city in Victoria).
```
vic_elec |>
pivot_longer(Demand:Temperature, names_to = "Series") |>
ggplot(aes(x = Time, y = value)) +
geom_line() +
facet_grid(rows = vars(Series), scales = "free_y") +
labs(y = "")
```
![Half-hourly electricity demand and corresponding temperatures in 2012--2014, Victoria, Australia.](https://otexts.com/fpp3/fpp_files/figure-html/elecdemand-1.png)
Figure 12.5: Half-hourly electricity demand and corresponding temperatures in 20122014, Victoria, Australia.
Plotting electricity demand against temperature (Figure [12.6](https://otexts.com/fpp3/complexseasonality.html#fig:elecdemand2)) shows that there is a nonlinear relationship between the two, with demand increasing for low temperatures (due to heating) and increasing for high temperatures (due to cooling).
```
elec <- vic_elec |>
mutate(
DOW = wday(Date, label = TRUE),
Working_Day = !Holiday & !(DOW %in% c("Sat", "Sun")),
Cooling = pmax(Temperature, 18)
)
elec |>
ggplot(aes(x=Temperature, y=Demand, col=Working_Day)) +
geom_point(alpha = 0.6) +
labs(x="Temperature (degrees Celsius)", y="Demand (MWh)")
```
![Half-hourly electricity demand for Victoria, plotted against temperatures for the same times in Melbourne, the largest city in Victoria.](https://otexts.com/fpp3/fpp_files/figure-html/elecdemand2-1.png)
Figure 12.6: Half-hourly electricity demand for Victoria, plotted against temperatures for the same times in Melbourne, the largest city in Victoria.
We will fit a regression model with a piecewise linear function of temperature (containing a knot at 18 degrees), and harmonic regression terms to allow for the daily seasonal pattern. Again, we set the orders of the Fourier terms subjectively, while using the AICc to select the order of the ARIMA errors.
```
fit <- elec |>
model(
ARIMA(Demand ~ PDQ(0, 0, 0) + pdq(d = 0) +
Temperature + Cooling + Working_Day +
fourier(period = "day", K = 10) +
fourier(period = "week", K = 5) +
fourier(period = "year", K = 3))
)
```
Forecasting with such models is difficult because we require future values of the predictor variables. Future values of the Fourier terms are easy to compute, but future temperatures are, of course, unknown. If we are only interested in forecasting up to a week ahead, we could use temperature forecasts obtained from a meteorological model. Alternatively, we could use scenario forecasting (Section [6.5](https://otexts.com/fpp3/scenarios.html#scenarios)) and plug in possible temperature patterns. In the following example, we have used a repeat of the last two days of temperatures to generate future possible demand values.
```
elec_newdata <- new_data(elec, 2*48) |>
mutate(
Temperature = tail(elec$Temperature, 2 * 48),
Date = lubridate::as_date(Time),
DOW = wday(Date, label = TRUE),
Working_Day = (Date != "2015-01-01") &
!(DOW %in% c("Sat", "Sun")),
Cooling = pmax(Temperature, 18)
)
fc <- fit |>
forecast(new_data = elec_newdata)
fc |>
autoplot(elec |> tail(10 * 48)) +
labs(title="Half hourly electricity demand: Victoria",
y = "Demand (MWh)", x = "Time [30m]")
```
![Forecasts from a dynamic harmonic regression model applied to half-hourly electricity demand data.](https://otexts.com/fpp3/fpp_files/figure-html/elecdemand4-1.png)
Figure 12.7: Forecasts from a dynamic harmonic regression model applied to half-hourly electricity demand data.
Although the short-term forecasts look reasonable, this is a crude model for a complicated process. The residuals, plotted in Figure [12.8](https://otexts.com/fpp3/complexseasonality.html#fig:elecdemand5), demonstrate that there is a lot of information that has not been captured with this model.
```
fit |> gg_tsresiduals()
```
![Residual diagnostics for the dynamic harmonic regression model.](https://otexts.com/fpp3/fpp_files/figure-html/elecdemand5-1.png)
Figure 12.8: Residual diagnostics for the dynamic harmonic regression model.
More sophisticated versions of this model which provide much better forecasts are described in Hyndman & Fan ([2010](#ref-HF2010)) and Fan & Hyndman ([2012](#ref-FH2012)).
### Bibliography
Fan, S., & Hyndman, R. J. (2012). Short-term load forecasting based on a semi-parametric additive model. *IEEE Transactions on Power Systems*, *27*(1), 134141.
Hyndman, R. J., & Fan, S. (2010). Density forecasting for long-term peak electricity demand. *IEEE Transactions on Power Systems*, *25*(2), 11421153.
## 12.2 Prophet model
A recent proposal is the Prophet model, available via the `fable.prophet` package. This model was introduced by Facebook ([S. J. Taylor & Letham, 2018](#ref-prophet)), originally for forecasting daily data with weekly and yearly seasonality, plus holiday effects. It was later extended to cover more types of seasonal data. It works best with time series that have strong seasonality and several seasons of historical data.
Prophet can be considered a nonlinear regression model (Chapter [7](https://otexts.com/fpp3/regression.html#regression)), of the form
\[
y_t = g(t) + s(t) + h(t) + \varepsilon_t,
\]
where \(g(t)\) describes a piecewise-linear trend (or “growth term”), \(s(t)\) describes the various seasonal patterns, \(h(t)\) captures the holiday effects, and \(\varepsilon_t\) is a white noise error term.
* The knots (or changepoints) for the piecewise-linear trend are automatically selected if not explicitly specified. Optionally, a logistic function can be used to set an upper bound on the trend.
* The seasonal component consists of Fourier terms of the relevant periods. By default, order 10 is used for annual seasonality and order 3 is used for weekly seasonality.
* Holiday effects are added as simple dummy variables.
* The model is estimated using a Bayesian approach to allow for automatic selection of the changepoints and other model characteristics.
We illustrate the approach using two data sets: a simple quarterly example, and then the electricity demand data described in the previous section.
### Example: Quarterly cement production
For the simple quarterly example, we will repeat the analysis from Section [9.10](https://otexts.com/fpp3/arima-ets.html#arima-ets) in which we compared an ARIMA and ETS model, but we will add in a prophet model for comparison.
```
library(fable.prophet)
cement <- aus_production |>
filter(year(Quarter) >= 1988)
train <- cement |>
filter(year(Quarter) <= 2007)
fit <- train |>
model(
arima = ARIMA(Cement),
ets = ETS(Cement),
prophet = prophet(Cement ~ season(period = 4, order = 2,
type = "multiplicative"))
)
```
Note that the seasonal term must have the `period` fully specified for quarterly and monthly data, as the default values assume the data are observed at least daily.
```
fc <- fit |> forecast(h = "2 years 6 months")
fc |> autoplot(cement)
```
![Prophet compared to ETS and ARIMA on the Cement production data, with a 10-quarter test set.](https://otexts.com/fpp3/fpp_files/figure-html/prophetegfc-1.png)
Figure 12.9: Prophet compared to ETS and ARIMA on the Cement production data, with a 10-quarter test set.
In this example, the Prophet forecasts are worse than either the ETS or ARIMA forecasts.
```
fc |> accuracy(cement)
#> # A tibble: 3 × 10
#> .model .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 arima Test -161. 216. 186. -7.71 8.68 1.27 1.26 0.387
#> 2 ets Test -171. 222. 191. -8.07 8.85 1.30 1.29 0.579
#> 3 prophet Test -176. 248. 215. -8.36 9.89 1.47 1.44 0.698
```
### Example: Half-hourly electricity demand
We will fit a similar model to the dynamic harmonic regression (DHR) model from the previous section, but this time using a Prophet model. For daily and sub-daily data, the default periods are correctly specified, so that we can simply specify the period using a character string as follows.
```
fit <- elec |>
model(
prophet(Demand ~ Temperature + Cooling + Working_Day +
season(period = "day", order = 10) +
season(period = "week", order = 5) +
season(period = "year", order = 3))
)
fit |>
components() |>
autoplot()
```
![Components of a Prophet model fitted to the Victorian electricity demand data.](https://otexts.com/fpp3/fpp_files/figure-html/prophetelec-1.png)
Figure 12.10: Components of a Prophet model fitted to the Victorian electricity demand data.
Figure [12.10](https://otexts.com/fpp3/prophet.html#fig:prophetelec) shows the trend and seasonal components of the fitted model.
The model specification is very similar to the DHR model in the previous section, although the result is different in several important ways. The Prophet model adds a piecewise linear time trend which is not really appropriate here as we dont expect the long term forecasts to continue to follow the downward linear trend at the end of the series.
There is also substantial remaining autocorrelation in the residuals,
```
fit |> gg_tsresiduals()
```
![Residuals from the Prophet model for Victorian electricity demand.](https://otexts.com/fpp3/fpp_files/figure-html/prophetelecres-1.png)
Figure 12.11: Residuals from the Prophet model for Victorian electricity demand.
The prediction intervals would be narrower if the autocorrelations were taken into account.
```
fc <- fit |>
forecast(new_data = elec_newdata)
```
```
fc |>
autoplot(elec |> tail(10 * 48)) +
labs(x = "Date", y = "Demand (MWh)")
```
![Two day forecasts from the Prophet model for Victorian electricity demand.](https://otexts.com/fpp3/fpp_files/figure-html/prophetfc-1.png)
Figure 12.12: Two day forecasts from the Prophet model for Victorian electricity demand.
Prophet has the advantage of being much faster to estimate than the DHR models we have considered previously, and it is completely automated. However, it rarely gives better forecast accuracy than the alternative approaches, as these two examples have illustrated.
### Bibliography
Taylor, S. J., & Letham, B. (2018). Forecasting at scale. *The American Statistician*, *72*(1), 3745.
## 12.3 Vector autoregressions
One limitation of the models that we have considered so far is that they impose a unidirectional relationship — the forecast variable is influenced by the predictor variables, but not vice versa. However, there are many cases where the reverse should also be allowed for — where all variables affect each other. In Section [10.2](https://otexts.com/fpp3/regarima.html#regarima), the changes in personal consumption expenditure (\(C_t\)) were forecast based on the changes in personal disposable income (\(I_t\)). However, in this case a bi-directional relationship may be more suitable: an increase in \(I_t\) will lead to an increase in \(C_t\) and vice versa.
An example of such a situation occurred in Australia during the Global Financial Crisis of 20082009. The Australian government issued stimulus packages that included cash payments in December 2008, just in time for Christmas spending. As a result, retailers reported strong sales and the economy was stimulated. Consequently, incomes increased.
Such feedback relationships are allowed for in the vector autoregressive (VAR) framework. In this framework, all variables are treated symmetrically. They are all modelled as if they all influence each other equally. In more formal terminology, all variables are now treated as “endogenous”. To signify this, we now change the notation and write all variables as \(y\)s: \(y_{1,t}\) denotes the \(t\)th observation of variable \(y_1\), \(y_{2,t}\) denotes the \(t\)th observation of variable \(y_2\), and so on.
A VAR model is a generalisation of the univariate autoregressive model for forecasting a vector of time series.[26](#fn26) It comprises one equation per variable in the system. The right hand side of each equation includes a constant and lags of all of the variables in the system. To keep it simple, we will consider a two variable VAR with one lag. We write a 2-dimensional VAR(1) model as
\[\begin{align}
y_{1,t} &= c_1+\phi _{11,1}y_{1,t-1}+\phi _{12,1}y_{2,t-1}+\varepsilon_{1,t} \tag{12.1}\\
y_{2,t} &= c_2+\phi _{21,1}y_{1,t-1}+\phi _{22,1}y_{2,t-1}+\varepsilon_{2,t}, \tag{12.2}
\end{align}\]
where \(\varepsilon_{1,t}\) and \(\varepsilon_{2,t}\) are white noise processes that may be contemporaneously correlated. The coefficient \(\phi_{ii,\ell}\) captures the influence of the \(\ell\)th lag of variable \(y_i\) on itself, while the coefficient \(\phi_{ij,\ell}\) captures the influence of the \(\ell\)th lag of variable \(y_j\) on \(y_i\).
If the series are stationary, we forecast them by fitting a VAR to the data directly (known as a “VAR in levels”). If the series are non-stationary, we take differences of the data in order to make them stationary, then fit a VAR model (known as a “VAR in differences”). In both cases, the models are estimated equation by equation using the principle of least squares. For each equation, the parameters are estimated by minimising the sum of squared \(\varepsilon_{i,t}\) values.
The other possibility, which is beyond the scope of this book and therefore we do not explore here, is that the series may be non-stationary but cointegrated, which means that there exists a linear combination of them that is stationary. In this case, a VAR specification that includes an error correction mechanism (usually referred to as a vector error correction model) should be included, and alternative estimation methods to least squares estimation should be used.[27](#fn27)
Forecasts are generated from a VAR in a recursive manner. The VAR generates forecasts for *each* variable included in the system. To illustrate the process, assume that we have fitted the 2-dimensional VAR(1) model described in Equations [(12.1)](https://otexts.com/fpp3/VAR.html#eq:var1a)[(12.2)](https://otexts.com/fpp3/VAR.html#eq:var1b), for all observations up to time \(T\). Then the one-step-ahead forecasts are generated by
\[\begin{align\*}
\hat y_{1,T+1|T} &=\hat{c}_1+\hat\phi_{11,1}y_{1,T}+\hat\phi_{12,1}y_{2,T} \\
\hat y_{2,T+1|T} &=\hat{c}_2+\hat\phi _{21,1}y_{1,T}+\hat\phi_{22,1}y_{2,T}.
\end{align\*}\]
This is the same form as [(12.1)](https://otexts.com/fpp3/VAR.html#eq:var1a)[(12.2)](https://otexts.com/fpp3/VAR.html#eq:var1b), except that the errors have been set to zero and parameters have been replaced with their estimates. For \(h=2\), the forecasts are given by
\[\begin{align\*}
\hat y_{1,T+2|T} &=\hat{c}_1+\hat\phi_{11,1}\hat y_{1,T+1|T}+\hat\phi_{12,1}\hat y_{2,T+1|T}\\
\hat y_{2,T+2|T}&=\hat{c}_2+\hat\phi_{21,1}\hat y_{1,T+1|T}+\hat\phi_{22,1}\hat y_{2,T+1|T}.
\end{align\*}\]
Again, this is the same form as [(12.1)](https://otexts.com/fpp3/VAR.html#eq:var1a)[(12.2)](https://otexts.com/fpp3/VAR.html#eq:var1b), except that the errors have been set to zero, the parameters have been replaced with their estimates, and the unknown values of \(y_1\) and \(y_2\) have been replaced with their forecasts. The process can be iterated in this manner for all future time periods.
There are two decisions one has to make when using a VAR to forecast, namely how many variables (denoted by \(K\)) and how many lags (denoted by \(p\)) should be included in the system. The number of coefficients to be estimated in a VAR is equal to \(K+pK^2\) (or \(1+pK\) per equation). For example, for a VAR with \(K=5\) variables and \(p=3\) lags, there are 16 coefficients per equation, giving a total of 80 coefficients to be estimated. The more coefficients that need to be estimated, the larger the estimation error entering the forecast.
In practice, it is usual to keep \(K\) small and include only variables that are correlated with each other, and therefore useful in forecasting each other. Information criteria are commonly used to select the number of lags to be included. Care should be taken when using the AICc as it tends to choose large numbers of lags; instead, for VAR models, we often use the BIC instead. A more sophisticated version of the model is a “sparse VAR” (where many coefficients are set to zero); another approach is to use “shrinkage estimation” (where coefficients are smaller).
A criticism that VARs face is that they are atheoretical; that is, they are not built on some economic theory that imposes a theoretical structure on the equations. Every variable is assumed to influence every other variable in the system, which makes a direct interpretation of the estimated coefficients difficult. Despite this, VARs are useful in several contexts:
1. forecasting a collection of related variables where no explicit interpretation is required;
2. testing whether one variable is useful in forecasting another (the basis of Granger causality tests);
3. impulse response analysis, where the response of one variable to a sudden but temporary change in another variable is analysed;
4. forecast error variance decomposition, where the proportion of the forecast variance of each variable is attributed to the effects of the other variables.
### Example: A VAR model for forecasting US consumption
```
fit <- us_change |>
model(
aicc = VAR(vars(Consumption, Income)),
bic = VAR(vars(Consumption, Income), ic = "bic")
)
fit
#> # A mable: 1 x 2
#> aicc bic
#> <model> <model>
#> 1 <VAR(5) w/ mean> <VAR(1) w/ mean>
```
```
glance(fit)
#> # A tibble: 2 × 6
#> .model sigma2 log_lik AIC AICc BIC
#> <chr> <list> <dbl> <dbl> <dbl> <dbl>
#> 1 aicc <dbl [2 × 2]> -373. 798. 806. 883.
#> 2 bic <dbl [2 × 2]> -408. 836. 837. 869.
```
A VAR(5) model is selected using the AICc (the default), while a VAR(1) model is selected using the BIC. This is not unusual — the BIC will always select a model that has fewer parameters than the AICc model as it imposes a stronger penalty for the number of parameters.
```
fit |>
augment() |>
ACF(.innov) |>
autoplot()
```
![ACF of the residuals from the two VAR models. A VAR(5) model is selected by the AICc, while a VAR(1) model is selected using the BIC.](https://otexts.com/fpp3/fpp_files/figure-html/varplots-1.png)
Figure 12.13: ACF of the residuals from the two VAR models. A VAR(5) model is selected by the AICc, while a VAR(1) model is selected using the BIC.
We see that the residuals from the VAR(1) model (`bic`) have significant autocorrelation for Consumption, while the VAR(5) model has effectively captured all the information in the data.
The forecasts generated by the VAR(5) model are plotted in Figure [12.14](https://otexts.com/fpp3/VAR.html#fig:VAR5).
```
fit |>
select(aicc) |>
forecast() |>
autoplot(us_change |> filter(year(Quarter) > 2010))
```
![Forecasts for US consumption and income generated from a VAR(5) model.](https://otexts.com/fpp3/fpp_files/figure-html/VAR5-1.png)
Figure 12.14: Forecasts for US consumption and income generated from a VAR(5) model.
### Bibliography
Athanasopoulos, G., Poskitt, D. S., & Vahid, F. (2012). Two canonical VARMA forms: Scalar component models vis-à-vis the echelon form. *Econometric Reviews*, *31*(1), 6083.
Hamilton, J. D. (1994). *Time series analysis*. Princeton University Press, Princeton.
Lütkepohl, H. (2007). General-to-specific or specific-to-general modelling? An opinion on current econometric terminology. *Journal of Econometrics*, *136*(1), 234319.
---
26. A more flexible generalisation would be a Vector ARMA process. However, the relative simplicity of VARs has led to their dominance in forecasting. Interested readers may refer to Athanasopoulos et al. ([2012](#ref-AthEtAl2012)).[↩︎](https://otexts.com/fpp3/VAR.html#fnref26)
27. Interested readers should refer to Hamilton ([1994](#ref-Ham1994)) and Lütkepohl ([2007](#ref-Lut2007)).[↩︎](https://otexts.com/fpp3/VAR.html#fnref27)
## 12.4 Neural network models
Artificial neural networks are forecasting methods that are based on simple mathematical models of the brain. They allow complex nonlinear relationships between the response variable and its predictors.
### Neural network architecture
A neural network can be thought of as a network of “neurons” which are organised in layers. The predictors (or inputs) form the bottom layer, and the forecasts (or outputs) form the top layer. There may also be intermediate layers containing “hidden neurons”.
![ A simple neural network equivalent to a linear regression.](https://otexts.com/fpp3/figs/nnet1-1.png)
Figure 12.15: A simple neural network equivalent to a linear regression.
The simplest networks contain no hidden layers and are equivalent to linear regressions. Figure [12.15](https://otexts.com/fpp3/nnetar.html#fig:nnet1) shows the neural network version of a linear regression with four predictors. The coefficients attached to these predictors are called “weights”. The forecasts are obtained by a linear combination of the inputs. The weights are selected in the neural network framework using a “learning algorithm” that minimises a “cost function” such as the MSE. Of course, in this simple example, we can use linear regression which is a much more efficient method of training the model.
Once we add an intermediate layer with hidden neurons, the neural network becomes non-linear. A simple example is shown in Figure [12.16](https://otexts.com/fpp3/nnetar.html#fig:nnet2).
![A neural network with four inputs and one hidden layer with three hidden neurons.](https://otexts.com/fpp3/figs/nnet2-1.png)
Figure 12.16: A neural network with four inputs and one hidden layer with three hidden neurons.
This is known as a *multilayer feed-forward network*, where each layer of nodes receives inputs from the previous layers. The outputs of the nodes in one layer are inputs to the next layer. The inputs to each node are combined using a weighted linear combination. The result is then modified by a nonlinear function before being output. For example, the inputs into each hidden neuron in Figure [12.16](https://otexts.com/fpp3/nnetar.html#fig:nnet2) are combined linearly to give
\[
z_j = b_j + \sum_{i=1}^4 w_{i,j} x_i.
\]
In the hidden layer, this is then modified using a nonlinear function such as a sigmoid,
\[
s(z) = \frac{1}{1+e^{-z}},
\]
to give the input for the next layer. This tends to reduce the effect of extreme input values, thus making the network somewhat robust to outliers.
The parameters \(b_1,b_2,b_3\) and \(w_{1,1},\dots,w_{4,3}\) are “learned” (or estimated) from the data. The values of the weights are often restricted to prevent them from becoming too large. The parameter that restricts the weights is known as the “decay parameter”, and is often set to be equal to 0.1.
The weights take random values to begin with, and these are then updated using the observed data. Consequently, there is an element of randomness in the predictions produced by a neural network. Therefore, the network is usually trained several times using different random starting points, and the results are averaged.
The number of hidden layers, and the number of nodes in each hidden layer, must be specified in advance. Usually, these would be selected using cross-validation.
### Neural network autoregression
With time series data, lagged values of the time series can be used as inputs to a neural network, just as we used lagged values in a linear autoregression model (Chapter [9](https://otexts.com/fpp3/arima.html#arima)). We call this a neural network autoregression or NNAR model.
In this book, we only consider feed-forward networks with one hidden layer, and we use the notation NNAR(\(p,k\)) to indicate there are \(p\) lagged inputs and \(k\) nodes in the hidden layer. For example, a NNAR(9,5) model is a neural network with the last nine observations \((y_{t-1},y_{t-2},\dots,y_{t-9}\)) used as inputs for forecasting the output \(y_t\), and with five neurons in the hidden layer. A NNAR(\(p,0\)) model is equivalent to an ARIMA(\(p,0,0\)) model, but without the restrictions on the parameters to ensure stationarity.
With seasonal data, it is useful to also add the last observed values from the same season as inputs. For example, an NNAR(3,1,2)\(_{12}\) model has inputs \(y_{t-1}\), \(y_{t-2}\), \(y_{t-3}\) and \(y_{t-12}\), and two neurons in the hidden layer. More generally, an NNAR(\(p,P,k\))\(_m\) model has inputs \((y_{t-1},y_{t-2},\dots,y_{t-p},y_{t-m},y_{t-2m},\dots,y_{t-Pm})\) and \(k\) neurons in the hidden layer. A NNAR(\(p,P,0\))\(_m\) model is equivalent to an ARIMA(\(p,0,0\))(\(P\),0,0)\(_m\) model but without the restrictions on the parameters that ensure stationarity.
The `NNETAR()` function fits an NNAR(\(p,P,k\))\(_m\) model. If the values of \(p\) and \(P\) are not specified, they are selected automatically. For non-seasonal time series, the default is the optimal number of lags (according to the AIC) for a linear AR(\(p\)) model. For seasonal time series, the default values are \(P=1\) and \(p\) is chosen from the optimal linear model fitted to the seasonally adjusted data. If \(k\) is not specified, it is set to \(k=(p+P+1)/2\) (rounded to the nearest integer).
When it comes to forecasting, the network is applied iteratively. For forecasting one step ahead, we simply use the available historical inputs. For forecasting two steps ahead, we use the one-step forecast as an input, along with the historical data. This process proceeds until we have computed all the required forecasts.
### Example: Sunspots
The surface of the sun contains magnetic regions that appear as dark spots. These affect the propagation of radio waves, and so telecommunication companies like to predict sunspot activity in order to plan for any future difficulties. Sunspots follow a cycle of length between 9 and 14 years. In Figure [12.17](https://otexts.com/fpp3/nnetar.html#fig:sunspotnnetar), forecasts from an NNAR(9,5) are shown for the next 30 years. We have used a square root transformation to ensure the forecasts stay positive.
```
sunspots <- sunspot.year |> as_tsibble()
fit <- sunspots |>
model(NNETAR(sqrt(value)))
fit |>
forecast(h = 30) |>
autoplot(sunspots) +
labs(x = "Year", y = "Counts", title = "Yearly sunspots")
```
![Forecasts from a neural network with nine lagged inputs and one hidden layer containing five neurons.](https://otexts.com/fpp3/fpp_files/figure-html/sunspotnnetar-1.png)
Figure 12.17: Forecasts from a neural network with nine lagged inputs and one hidden layer containing five neurons.
Here, the last 9 observations are used as predictors, and there are 5 neurons in the hidden layer. The cyclicity in the data has been modelled well. We can also see the asymmetry of the cycles has been captured by the model, where the increasing part of the cycle is steeper than the decreasing part of the cycle. This is one difference between a NNAR model and a linear AR model — while linear AR models can model cyclicity, the modelled cycles are always symmetric.
### Prediction intervals
Unlike most of the methods considered in this book, neural networks are not based on a well-defined stochastic model, and so it is not straightforward to derive prediction intervals for the resultant forecasts. However, we can still compute prediction intervals using simulation where future sample paths are generated using bootstrapped residuals (as described in Section [5.5](https://otexts.com/fpp3/prediction-intervals.html#prediction-intervals)).
The neural network fitted to the sunspot data can be written as
\[
y_t = f(\bm{y}_{t-1}) + \varepsilon_t
\]
where \(\bm{y}_{t-1} = (y_{t-1},y_{t-2},\dots,y_{t-9})'\) is a vector containing lagged values of the series, and \(f\) is a neural network with 5 hidden nodes in a single layer. The error series \(\{\varepsilon_t\}\) is assumed to be homoscedastic (and possibly also normally distributed).
We can simulate future sample paths of this model iteratively, by randomly generating a value for \(\varepsilon_t\), either from a normal distribution, or by resampling from the historical values. So if \(\varepsilon^\*_{T+1}\) is a random draw from the distribution of errors at time \(T+1\), then
\[
y^\*_{T+1} = f(\bm{y}_{T}) + \varepsilon^\*_{T+1}
\]
is one possible draw from the forecast distribution for \(y_{T+1}\). Setting
\(\bm{y}_{T+1}^\* = (y^\*_{T+1}, y_{T}, \dots, y_{T-7})'\), we can then repeat the process to get
\[
y^\*_{T+2} = f(\bm{y}^\*_{T+1}) + \varepsilon^\*_{T+2}.
\]
In this way, we can iteratively simulate a future sample path. By repeatedly simulating sample paths, we build up knowledge of the distribution for all future values based on the fitted neural network.
Here is a simulation of 9 possible future sample paths for the sunspot data. Each sample path covers the next 30 years after the observed data.
```
fit |>
generate(times = 9, h = 30) |>
autoplot(.sim) +
autolayer(sunspots, value) +
theme(legend.position = "none")
```
![Future sample paths for the annual sunspot data.](https://otexts.com/fpp3/fpp_files/figure-html/nnetarsim-1.png)
Figure 12.18: Future sample paths for the annual sunspot data.
If we do this many times, we can get a good picture of the forecast distributions. This is how the `forecast()` function produces prediction intervals for NNAR models. The `times` argument in `forecast()` controls how many simulations are done (default 1000). By default, the errors are drawn from a normal distribution. The `bootstrap` argument allows the errors to be “bootstrapped” (i.e., randomly drawn from the historical errors).
## 12.5 Bootstrapping and bagging
### Bootstrapping time series
In the preceding section, and in Section [5.5](https://otexts.com/fpp3/prediction-intervals.html#prediction-intervals), we bootstrap the residuals of a time series in order to simulate future values of a series using a model.
More generally, we can generate new time series that are similar to our observed series, using another type of bootstrap.
First, the time series is transformed if necessary, and then decomposed into trend, seasonal and remainder components using STL. Then we obtain shuffled versions of the remainder component to get bootstrapped remainder series. Because there may be autocorrelation present in an STL remainder series, we cannot simply use the re-draw procedure that was described in Section [5.5](https://otexts.com/fpp3/prediction-intervals.html#prediction-intervals). Instead, we use a “blocked bootstrap”, where contiguous sections of the time series are selected at random and joined together. These bootstrapped remainder series are added to the trend and seasonal components, and the transformation is reversed to give variations on the original time series.
Consider the quarterly cement production in Australia from 1988 Q1 to 2010 Q2. First we check, see Figure [12.19](https://otexts.com/fpp3/bootstrap.html#fig:cementstl) that the decomposition has adequately captured the trend and seasonality, and that there is no obvious remaining signal in the remainder series.
```
cement <- aus_production |>
filter(year(Quarter) >= 1988) |>
select(Quarter, Cement)
cement_stl <- cement |>
model(stl = STL(Cement))
cement_stl |>
components() |>
autoplot()
```
![STL decomposition of quarterly Australian cement production.](https://otexts.com/fpp3/fpp_files/figure-html/cementstl-1.png)
Figure 12.19: STL decomposition of quarterly Australian cement production.
Now we can generate several bootstrapped versions of the data. Usually, `generate()` produces simulations of the future from a model. But here we want simulations for the period of the historical data. So we use the `new_data` argument to pass in the original data so that the same time periods are used for the simulated data. We will use a block size of 8 to cover two years of data.
```
cement_stl |>
generate(new_data = cement, times = 10,
bootstrap_block_size = 8) |>
autoplot(.sim) +
autolayer(cement, Cement) +
guides(colour = "none") +
labs(title = "Cement production: Bootstrapped series",
y="Tonnes ('000)")
```
![Ten bootstrapped versions of quarterly Australian cement production (coloured), along with the original data (black).](https://otexts.com/fpp3/fpp_files/figure-html/cementbootstrapped-1.png)
Figure 12.20: Ten bootstrapped versions of quarterly Australian cement production (coloured), along with the original data (black).
### Bagged forecasts
One use for these bootstrapped time series is to improve forecast accuracy. If we produce forecasts from each of the additional time series, and average the resulting forecasts, we get better forecasts than if we simply forecast the original time series directly. This is called “bagging” which stands for “**b**ootstrap **agg**regatin**g**”.
We demonstrate the idea using the `cement` data. First, we simulate many time series that are similar to the original data, using the block-bootstrap described above.
```
sim <- cement_stl |>
generate(new_data = cement, times = 100,
bootstrap_block_size = 8) |>
select(-.model, -Cement)
```
For each of these series, we fit an ETS model. A different ETS model may be selected in each case, although it will most likely select the same model because the series are similar. However, the estimated parameters will be different, so the forecasts will be different even if the selected model is the same. This is a time-consuming process as there are a large number of series.
```
ets_forecasts <- sim |>
model(ets = ETS(.sim)) |>
forecast(h = 12)
ets_forecasts |>
update_tsibble(key = .rep) |>
autoplot(.mean) +
autolayer(cement, Cement) +
guides(colour = "none") +
labs(title = "Cement production: bootstrapped forecasts",
y="Tonnes ('000)")
```
![Forecasts of 100 bootstrapped series obtained using ETS models.](https://otexts.com/fpp3/fpp_files/figure-html/cementnboot-1.png)
Figure 12.21: Forecasts of 100 bootstrapped series obtained using ETS models.
Finally, we average these forecasts for each time period to obtain the “bagged forecasts” for the original data.
```
bagged <- ets_forecasts |>
summarise(bagged_mean = mean(.mean))
cement |>
model(ets = ETS(Cement)) |>
forecast(h = 12) |>
autoplot(cement) +
autolayer(bagged, bagged_mean, col = "#D55E00") +
labs(title = "Cement production in Australia",
y="Tonnes ('000)")
```
![Comparing bagged ETS forecasts (the average of 100 bootstrapped forecasts in orange) and ETS applied directly to the data (in blue).](https://otexts.com/fpp3/fpp_files/figure-html/baggedf-1.png)
Figure 12.22: Comparing bagged ETS forecasts (the average of 100 bootstrapped forecasts in orange) and ETS applied directly to the data (in blue).
Bergmeir et al. ([2016](#ref-baggedETS)) show that, on average, bagging gives better forecasts than just applying `ETS()` directly. Of course, it is slower because a lot more computation is required.
### Bibliography
Bergmeir, C., Hyndman, R. J., & Benítez, J. M. (2016). Bagging exponential smoothing methods using STL decomposition and Box-Cox transformation. *International Journal of Forecasting*, *32*(2), 303312.
## 12.6 Exercises
1. Compare STL and Dynamic Harmonic Regression forecasts for one of the series in the `pedestrian` data set.
1. Try modifying the order of the Fourier terms to minimize the AICc value.
2. Check the residuals for each model. Do they capture the available information in the data?
3. Which of the two sets of forecasts are best? Explain.
2. Consider the weekly data on US finished motor gasoline products supplied (millions of barrels per day) (series `us_gasoline`):
1. Fit a dynamic harmonic regression model to these data. How does it compare to the regression model you fitted in Exercise 5 in Section [7.10](https://otexts.com/fpp3/regression-exercises.html#regression-exercises)?
2. Check the residuals from both models and comment on what you see.
3. Could you model these data using any of the other methods we have considered in this book? Explain why/why not.
3. Experiment with using `NNETAR()` on your retail data and other data we have considered in previous chapters.
## 12.7 Further reading
* The Prophet model is described in S. J. Taylor & Letham ([2018](#ref-prophet)).
* Pfaff ([2008](#ref-Pfaff2008)) provides a book-length overview of VAR modelling and other multivariate time series models.
* A current survey of the use of recurrent neural networks for forecasting is provided by Hewamalage et al. ([2021](#ref-HBB2021rnn)).
* Bootstrapping for time series is discussed in Lahiri ([2003](#ref-Lahiri2013)).
* Bagging for time series forecasting is relatively new. Bergmeir et al. ([2016](#ref-baggedETS)) is one of the few papers which addresses this topic.
### Bibliography
Bergmeir, C., Hyndman, R. J., & Benítez, J. M. (2016). Bagging exponential smoothing methods using STL decomposition and Box-Cox transformation. *International Journal of Forecasting*, *32*(2), 303312.
Hewamalage, H., Bergmeir, C., & Bandara, K. (2021). Recurrent neural networks for time series forecasting: Current status and future directions. *International Journal of Forecasting*, *37*(1), 388427.
Lahiri, S. N. (2003). *Resampling methods for dependent data*. Springer Science & Business Media.
Pfaff, B. (2008). *Analysis of integrated and cointegrated time series with R*. Springer Science & Business Media.
Taylor, S. J., & Letham, B. (2018). Forecasting at scale. *The American Statistician*, *72*(1), 3745.
+717
View File
@@ -0,0 +1,717 @@
Source: https://otexts.com/fpp3/practical.html (chapter practical, 11 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 13-practical-issues
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Chapter 13 Some practical forecasting issues
In this final chapter, we address many practical issues that arise in forecasting, and discuss some possible solutions.
## 13.1 Weekly, daily and sub-daily data
Weekly, daily and sub-daily data can be challenging for forecasting, although for different reasons.
### Weekly data
Weekly data is difficult to work with because the seasonal period (the number of weeks in a year) is both large and non-integer. The average number of weeks in a year is 52.18. Most of the methods we have considered require the seasonal period to be an integer. Even if we approximate it by 52, most of the methods will not handle such a large seasonal period efficiently.
The simplest approach is to use an STL decomposition along with a non-seasonal method applied to the seasonally adjusted data (as discussed in Chapter [3](https://otexts.com/fpp3/decomposition.html#decomposition)). Here is an example using weekly data on US finished motor gasoline products supplied (in millions of barrels per day) from February 1991 to May 2005.
```
my_dcmp_spec <- decomposition_model(
STL(Barrels),
ETS(season_adjust ~ season("N"))
)
us_gasoline |>
model(stl_ets = my_dcmp_spec) |>
forecast(h = "2 years") |>
autoplot(us_gasoline) +
labs(y = "Millions of barrels per day",
title = "Weekly US gasoline production")
```
![Forecasts for weekly US gasoline production using an STL decomposition with an ETS model for the seasonally adjusted data.](https://otexts.com/fpp3/fpp_files/figure-html/gasstl-1.png)
Figure 13.1: Forecasts for weekly US gasoline production using an STL decomposition with an ETS model for the seasonally adjusted data.
An alternative approach is to use a dynamic harmonic regression model, as discussed in Section [10.5](https://otexts.com/fpp3/dhr.html#dhr). In the following example, the number of Fourier terms was selected by minimising the AICc. The order of the ARIMA model is also selected by minimising the AICc, although that is done within the `ARIMA()` function. We use `PDQ(0,0,0)` to prevent `ARIMA()` trying to handle the seasonality using seasonal ARIMA components.
```
gas_dhr <- us_gasoline |>
model(dhr = ARIMA(Barrels ~ PDQ(0, 0, 0) + fourier(K = 6)))
```
```
gas_dhr |>
forecast(h = "2 years") |>
autoplot(us_gasoline) +
labs(y = "Millions of barrels per day",
title = "Weekly US gasoline production")
```
![Forecasts for weekly US gasoline production using a dynamic harmonic regression model.](https://otexts.com/fpp3/fpp_files/figure-html/gasforecast-1.png)
Figure 13.2: Forecasts for weekly US gasoline production using a dynamic harmonic regression model.
The fitted model has 6 pairs of Fourier terms and can be written as
\[
y_t = bt + \sum_{j=1}^{6}
\left[
\alpha_j\sin\left(\frac{2\pi j t}{52.18}\right) +
\beta_j\cos\left(\frac{2\pi j t}{52.18}\right)
\right] +
\eta_t
\]
where \(\eta_t\) is an ARIMA(0,1,1) process. Because \(\eta_t\) is non-stationary, the model is actually estimated on the differences of the variables on both sides of this equation. There are 12 parameters to capture the seasonality, while the total number of degrees of freedom is 14 (the other two coming from the MA parameter and the drift parameter).
The STL approach is preferable when the seasonality changes over time. The dynamic harmonic regression approach is preferable if there are covariates that are useful predictors as these can be added as additional regressors.
### Daily and sub-daily data
Daily and sub-daily (such as hourly) data are challenging for a different reason — they often involve multiple seasonal patterns, and so we need to use a method that handles such complex seasonality.
Of course, if the time series is relatively short so that only one type of seasonality is present, then it will be possible to use one of the single-seasonal methods we have discussed in previous chapters (e.g., ETS or a seasonal ARIMA model). But when the time series is long enough so that some of the longer seasonal periods become apparent, it will be necessary to use STL, dynamic harmonic regression or Prophet, as discussed in Section [12.1](https://otexts.com/fpp3/complexseasonality.html#complexseasonality).
However, these methods only allow for regular seasonality. Capturing seasonality associated with moving events such as Easter, Eid, or the Chinese New Year is more difficult. Even with monthly data, this can be tricky as the festivals can fall in either March or April (for Easter), in January or February (for the Chinese New Year), or at any time of the year (for Eid).
The best way to deal with moving holiday effects is to include dummy variables in the model. This can be done within the `ARIMA()` or `prophet()` functions, for example, but not within `ETS()`. In fact, `prophet()` has a `holiday()` special to easily incorporate holiday effects.
## 13.2 Time series of counts
All of the methods discussed in this book assume that the data have a continuous sample space. But often data comes in the form of counts. For example, we may wish to forecast the number of customers who enter a store each day. We could have \(0, 1, 2, \dots\), customers, but we cannot have 3.45693 customers.
In practice, this rarely matters provided our counts are sufficiently large. If the minimum number of customers is at least 100, then the difference between a continuous sample space \([100,\infty)\) and the discrete sample space \(\{100,101,102,\dots\}\) has no perceivable effect on our forecasts. However, if our data contains small counts \((0, 1, 2, \dots)\), then we need to use forecasting methods that are more appropriate for a sample space of non-negative integers.
Such models are beyond the scope of this book. However, there is one simple method which gets used in this context, that we would like to mention. It is “Crostons method”, named after its British inventor, John Croston, and first described in Croston ([1972](#ref-Croston72)). Actually, this method does not properly deal with the count nature of the data either, but it is used so often, that it is worth knowing about it.
With Crostons method, we construct two new series from our original time series by noting which time periods contain zero values, and which periods contain non-zero values. Let \(q_i\) be the \(i\)th non-zero quantity, and let \(a_i\) be the time between \(q_{i-1}\) and \(q_i\). Crostons method involves separate simple exponential smoothing forecasts on the two new series \(a\) and \(q\). Because the method is usually applied to time series of demand for items, \(q\) is often called the “demand” and \(a\) the “inter-arrival time”.
If \(\hat{q}_{i+1|i}\) and \(\hat{a}_{i+1|i}\) are the one-step forecasts of the \((i+1)\)th demand and inter-arrival time respectively, based on data up to demand \(i\), then Crostons method gives
\[\begin{align}
\hat{q}_{i+1|i} & = (1-\alpha_q)\hat{q}_{i|i-1} + \alpha_q q_i, \tag{13.1}\\
\hat{a}_{i+1|i} & = (1-\alpha_a)\hat{a}_{i|i-1} + \alpha_a a_i. \tag{13.2}
\end{align}\]
The smoothing parameters \(\alpha_a\) and \(\alpha_q\) take values between 0 and 1. Let \(j\) be the time for the last observed positive observation. Then the \(h\)-step ahead forecast for the demand at time \(T+h\), is given by the ratio
\[
\hat{y}_{T+h|T} = \hat{q}_{j+1|j}/\hat{a}_{j+1|j}.
\]
There are no algebraic results allowing us to compute prediction intervals for this method, because the method does not correspond to any statistical model ([Shenstone & Hyndman, 2005](#ref-SH05)). Forecasts obtained from Crostons method are also known to be biased ([Syntetos & Boylan, 2001](#ref-SB01)).
The `CROSTON()` function produces forecasts using Crostons method. The two smoothing parameters \(\alpha_a\) and \(\alpha_q\) are estimated from the data. This is different from the way Croston envisaged the method being used. He would simply use \(\alpha_a=\alpha_q=0.1\), and set \(a_0\) and \(q_0\) to be equal to the first observation in each of the series.
### Example: Pharmaceutical sales
Figure [13.3](https://otexts.com/fpp3/counts.html#fig:j06) shows the numbers of scripts sold each month for immune sera and immunoglobulin products in Australia. The data contain small counts, with many months registering no sales at all, and only small numbers of items sold in other months.
```
j06 <- PBS |>
filter(ATC2 == "J06") |>
summarise(Scripts = sum(Scripts))
j06 |> autoplot(Scripts) +
labs(y="Number of scripts",
title = "Sales for immune sera and immunoglobulins")
```
![Numbers of scripts sold for Immune sera and immunoglobulins on the Australian Pharmaceutical Benefits Scheme.](https://otexts.com/fpp3/fpp_files/figure-html/j06-1.png)
Figure 13.3: Numbers of scripts sold for Immune sera and immunoglobulins on the Australian Pharmaceutical Benefits Scheme.
Tables [13.1](https://otexts.com/fpp3/counts.html#tab:j06table) and [13.2](https://otexts.com/fpp3/counts.html#tab:j06table2) shows the first 10 non-zero demand values, with their corresponding inter-arrival times.
Table 13.1: The first 10 non-zero demand values.
| Month | Scripts |
| --- | --- |
| 1991 Jul | 1 |
| 1991 Aug | 1 |
| 1991 Sep | 1 |
| 1991 Oct | 0 |
| 1991 Nov | 0 |
| 1991 Dec | 1 |
| 1992 Jan | 3 |
| 1992 Feb | 1 |
| 1992 Mar | 1 |
| 1992 Apr | 1 |
| 1992 May | 1 |
| 1992 Jun | 1 |
Table 13.2: The first 10 non-zero demand values shown as demand and inter-arrival series.
| | | | | | | | | | | |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| \(i\) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| \(q_i\) | 1 | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 |
| \(a_i\) | | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 | 1 |
In this example, the smoothing parameters are estimated to be \(\alpha_a = 0.08\), \(\alpha_q = 0.71\), \(\hat{q}_{1|0}=4.17\), and \(\hat{a}_{1|0}=3.52\). The final forecasts for the two series are \(\hat{q}_{T+1|T} = 2.419\) and \(\hat{a}_{T+1|T} = 2.484\). So the forecasts are all equal to
\(\hat{y}_{T+h|T} = 2.419/2.484 = 0.974\).
In practice, `fable` does these calculations for you:
```
j06 |>
model(CROSTON(Scripts)) |>
forecast(h = 6)
#> # A fable: 6 x 4 [1M]
#> # Key: .model [1]
#> .model Month Scripts .mean
#> <chr> <mth> <dist> <dbl>
#> 1 CROSTON(Scripts) 2008 Jul 0.9735 0.974
#> 2 CROSTON(Scripts) 2008 Aug 0.9735 0.974
#> 3 CROSTON(Scripts) 2008 Sep 0.9735 0.974
#> 4 CROSTON(Scripts) 2008 Oct 0.9735 0.974
#> 5 CROSTON(Scripts) 2008 Nov 0.9735 0.974
#> 6 CROSTON(Scripts) 2008 Dec 0.9735 0.974
```
The `Scripts` column repeats the mean rather than provide a full distribution, because there is no underlying stochastic model.
Forecasting models that deal more directly with the count nature of the data, and allow for a forecasting distribution, are described in Christou & Fokianos ([2015](#ref-christou2015count)).
### Bibliography
Christou, V., & Fokianos, K. (2015). On count time series prediction. *Journal of Statistical Computation and Simulation*, *85*(2), 357373.
Croston, J. D. (1972). Forecasting and stock control for intermittent demands. *Operational Research Quarterly*, *23*(3), 289303.
Shenstone, L., & Hyndman, R. J. (2005). Stochastic models underlying Crostons method for intermittent demand forecasting. *Journal of Forecasting*, *24*(6), 389402.
Syntetos, A. A., & Boylan, J. E. (2001). On the bias of intermittent demand estimates. *International Journal of Production Economics*, *71*, 457466.
## 13.3 Ensuring forecasts stay within limits
It is common to want forecasts to be positive, or to require them to be within some specified range \([a,b]\). Both of these situations are relatively easy to handle using transformations.
### Positive forecasts
To impose a positivity constraint, we can simply work on the log scale. For example, consider the real price of a dozen eggs (1900-1993; in cents) shown in Figure [13.4](https://otexts.com/fpp3/limits.html#fig:positiveeggs). Because of the log transformation, the forecast distributions are constrained to stay positive, and so they will become progressively more skewed as the mean decreases.
```
egg_prices <- prices |> filter(!is.na(eggs))
egg_prices |>
model(ETS(log(eggs) ~ trend("A"))) |>
forecast(h = 50) |>
autoplot(egg_prices) +
labs(title = "Annual egg prices",
y = "$US (in cents adjusted for inflation) ")
```
![Forecasts for the price of a dozen eggs, constrained to be positive using a log transformation.](https://otexts.com/fpp3/fpp_files/figure-html/positiveeggs-1.png)
Figure 13.4: Forecasts for the price of a dozen eggs, constrained to be positive using a log transformation.
### Forecasts constrained to an interval
To see how to handle data constrained to an interval, imagine that the egg prices were constrained to lie within \(a=50\) and \(b=400\). Then we can transform the data using a scaled logit transform which maps \((a,b)\) to the whole real line:
\[
y = \log\left(\frac{x-a}{b-x}\right),
\]
where \(x\) is on the original scale and \(y\) is the transformed data. To reverse the transformation, we will use
\[
x = \frac{(b-a)e^y}{1+e^y} + a.
\]
This is not a built-in transformation, so we will need to first setup the transformation functions.
```
scaled_logit <- function(x, lower = 0, upper = 1) {
log((x - lower) / (upper - x))
}
inv_scaled_logit <- function(x, lower = 0, upper = 1) {
(upper - lower) * exp(x) / (1 + exp(x)) + lower
}
my_scaled_logit <- new_transformation(
scaled_logit, inv_scaled_logit)
egg_prices |>
model(
ETS(my_scaled_logit(eggs, lower = 50, upper = 400)
~ trend("A"))
) |>
forecast(h = 50) |>
autoplot(egg_prices) +
labs(title = "Annual egg prices",
y = "$US (in cents adjusted for inflation) ")
```
![Forecasts for the price of a dozen eggs, constrained to be lie between 50 and 400 cents US.](https://otexts.com/fpp3/fpp_files/figure-html/constrained-1.png)
Figure 13.5: Forecasts for the price of a dozen eggs, constrained to be lie between 50 and 400 cents US.
The bias-adjustment is automatically applied here, and the prediction intervals from these transformations have the same coverage probability as on the transformed scale, because quantiles are preserved under monotonically increasing transformations.
The prediction intervals lie above 50 due to the transformation. As a result of this artificial (and unrealistic) constraint, the forecast distributions have become extremely skewed.
## 13.4 Forecast combinations
An easy way to improve forecast accuracy is to use several different methods on the same time series, and to average the resulting forecasts. Over 50 years ago, John Bates and Clive Granger wrote a famous paper ([Bates & Granger, 1969](#ref-BatesGranger1969)), showing that combining forecasts often leads to better forecast accuracy. Twenty years later, Clemen ([1989](#ref-Clemen89)) wrote
> The results have been virtually unanimous: combining multiple forecasts leads to increased forecast accuracy. In many cases one can make dramatic performance improvements by simply averaging the forecasts.
While there has been considerable research on using weighted averages, or some other more complicated combination approach, using a simple average has proven hard to beat ([Wang et al., 2023](#ref-combinations)).
Here is an example using monthly revenue from take-away food in Australia, from April 1982 to December 2018. We use forecasts from the following models: ETS, STL-ETS, and ARIMA; and we compare the results using the last 5 years (60 months) of observations.
```
auscafe <- aus_retail |>
filter(stringr::str_detect(Industry, "Takeaway")) |>
summarise(Turnover = sum(Turnover))
train <- auscafe |>
filter(year(Month) <= 2013)
STLF <- decomposition_model(
STL(log(Turnover) ~ season(window = Inf)),
ETS(season_adjust ~ season("N"))
)
cafe_models <- train |>
model(
ets = ETS(Turnover),
stlf = STLF,
arima = ARIMA(log(Turnover))
) |>
mutate(combination = (ets + stlf + arima) / 3)
cafe_fc <- cafe_models |>
forecast(h = "5 years")
```
Notice that we form a combination in the `mutate()` function by simply taking a linear function of the estimated models. This very simple syntax will automatically handle the forecast distribution appropriately by taking account of the correlation between the forecast errors of the models that are included. However, to keep the next plot simple, we will omit the prediction intervals.
```
cafe_fc |>
autoplot(auscafe |> filter(year(Month) > 2008),
level = NULL) +
labs(y = "$ billion",
title = "Australian monthly expenditure on eating out")
```
![Point forecasts from various methods applied to Australian monthly expenditure on eating out.](https://otexts.com/fpp3/fpp_files/figure-html/combineplot-1.png)
Figure 13.6: Point forecasts from various methods applied to Australian monthly expenditure on eating out.
```
cafe_fc |>
accuracy(auscafe) |>
arrange(RMSE)
#> # A tibble: 4 × 10
#> .model .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 combination Test 8.09 41.0 31.8 0.401 2.19 0.776 0.790 0.747
#> 2 arima Test -25.4 46.2 38.9 -1.77 2.65 0.949 0.890 0.786
#> 3 stlf Test -36.9 64.1 51.7 -2.55 3.54 1.26 1.23 0.775
#> 4 ets Test 86.5 122. 101. 5.51 6.66 2.46 2.35 0.880
```
ARIMA does particularly well with this series, while the combination approach does even better (based on most measures including RMSE and MAE). For other data, ARIMA may be quite poor, while the combination approach is usually not far off, or better than, the best component method.
### Forecast combination distributions
The `cafe_fc` object contains forecast distributions, from which any prediction interval can usually be computed. Lets look at the intervals for the first period.
```
cafe_fc |> filter(Month == min(Month))
#> # A fable: 4 x 4 [1M]
#> # Key: .model [4]
#> .model Month
#> <chr> <mth>
#> 1 ets 2014 Jan
#> 2 stlf 2014 Jan
#> 3 arima 2014 Jan
#> 4 combination 2014 Jan
#> # 2 more variables: Turnover <dist>, .mean <dbl>
```
The first three are a mixture of normal and transformed normal distributions. The package does not yet combine such diverse distributions, so the `combination` output is simply the mean instead.
However, if we work with simulated sample paths, it is possible to create forecast distributions for the combination forecast as well.
```
cafe_futures <- cafe_models |>
# Generate 1000 future sample paths
generate(h = "5 years", times = 1000) |>
# Compute forecast distributions from future sample paths
as_tibble() |>
group_by(Month, .model) |>
summarise(
dist = distributional::dist_sample(list(.sim))
) |>
ungroup() |>
# Create fable object
as_fable(index = Month, key = .model,
distribution = dist, response = "Turnover")
```
```
# Forecast distributions for h=1
cafe_futures |> filter(Month == min(Month))
#> # A fable: 4 x 3 [1M]
#> # Key: .model [4]
#> Month .model dist
#> <mth> <chr> <dist>
#> 1 2014 Jan arima sample[1000]
#> 2 2014 Jan combination sample[1000]
#> 3 2014 Jan ets sample[1000]
#> 4 2014 Jan stlf sample[1000]
```
Now all four models, including the combination, are stored as empirical distributions, and we can plot prediction intervals for the combination forecast, as shown in Figure [13.7](https://otexts.com/fpp3/combinations.html#fig:auscafecombPI).
```
cafe_futures |>
filter(.model == "combination") |>
autoplot(auscafe |> filter(year(Month) > 2008)) +
labs(y = "$ billion",
title = "Australian monthly expenditure on eating out")
```
![Prediction intervals for the combination forecast of Australian monthly expenditure on eating out.](https://otexts.com/fpp3/fpp_files/figure-html/auscafecombPI-1.png)
Figure 13.7: Prediction intervals for the combination forecast of Australian monthly expenditure on eating out.
To check the accuracy of the 95% prediction intervals, we can use a Winkler score (defined in Section [5.9](https://otexts.com/fpp3/distaccuracy.html#distaccuracy)).
```
cafe_futures |>
accuracy(auscafe, measures = interval_accuracy_measures,
level = 95) |>
arrange(winkler)
#> # A tibble: 4 × 5
#> .model .type winkler pinball scaled_pinball
#> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 combination Test 427. 17.8 0.217
#> 2 stlf Test 590. 29.4 0.358
#> 3 ets Test 712. 22.6 0.276
#> 4 arima Test 760. 36.9 0.450
```
Lower is better, so the `combination` forecast is again better than any of the component models.
### Bibliography
Bates, J. M., & Granger, C. W. J. (1969). The combination of forecasts. *Operational Research Quarterly*, *20*(4), 451468.
Clemen, R. (1989). Combining forecasts: A review and annotated bibliography. *International Journal of Forecasting*, *5*(4), 559583.
Wang, X., Hyndman, R. J., Li, F., & Kang, Y. (2023). Forecast combinations: An over 50-year review. *International J Forecasting*, *39*(4), 15181547.
## 13.5 Prediction intervals for aggregates
A common problem is to forecast the aggregate of several time periods of data, using a model fitted to the disaggregated data. For example, we may have monthly data but wish to forecast the total for the next year. Or we may have weekly data, and want to forecast the total for the next four weeks.
If the point forecasts are means, then adding them up will give a good estimate of the total. But prediction intervals are more tricky due to the correlations between forecast errors.
A general solution is to use simulations. Here is an example using ETS models applied to Australian take-away food sales, assuming we wish to forecast the aggregate revenue in the next 12 months.
```
fit <- auscafe |>
# Fit a model to the data
model(ETS(Turnover))
futures <- fit |>
# Simulate 10000 future sample paths, each of length 12
generate(times = 10000, h = 12) |>
# Sum the results for each sample path
as_tibble() |>
group_by(.rep) |>
summarise(.sim = sum(.sim)) |>
# Store as a distribution
summarise(total = distributional::dist_sample(list(.sim)))
```
We can compute the mean of the simulations, along with prediction intervals:
```
futures |>
mutate(
mean = mean(total),
pi80 = hilo(total, 80),
pi95 = hilo(total, 95)
)
#> # A tibble: 1 × 4
#> total mean pi80 pi95
#> <dist> <dbl> <hilo> <hilo>
#> 1 sample[10000] 19212. [18307, 20134]80 [17846, 20639]95
```
As expected, the mean of the simulated data is close to the sum of the individual forecasts.
```
forecast(fit, h = 12) |>
as_tibble() |>
summarise(total = sum(.mean))
#> # A tibble: 1 × 1
#> total
#> <dbl>
#> 1 19212.
```
## 13.6 Backcasting
Sometimes it is useful to “backcast” a time series — that is, forecast in reverse time. Although there are no in-built R functions to do this, it is easy to implement by creating a new time index.
Suppose we want to extend our Australian takeaway to the start of 1981 (the actual data starts in April 1982).
```
backcasts <- auscafe |>
mutate(reverse_time = rev(row_number())) |>
update_tsibble(index = reverse_time) |>
model(ets = ETS(Turnover ~ season(period = 12))) |>
forecast(h = 15) |>
mutate(Month = auscafe$Month[1] - (1:15)) |>
as_fable(index = Month, response = "Turnover",
distribution = "Turnover")
backcasts |>
autoplot(auscafe |> filter(year(Month) < 1990)) +
labs(title = "Backcasts of Australian food expenditure",
y = "$ (billions)")
```
![Backcasts for Australian monthly expenditure on cafés, restaurants and takeaway food services using an ETS model.](https://otexts.com/fpp3/fpp_files/figure-html/backcasting-1.png)
Figure 13.8: Backcasts for Australian monthly expenditure on cafés, restaurants and takeaway food services using an ETS model.
Most of the work here is in re-indexing the `tsibble` object and then re-indexing the `fable` object.
## 13.7 Very long and very short time series
### Forecasting very short time series
We often get asked how *few* data points can be used to fit a time series model. As with almost all sample size questions, there is no easy answer. It depends on the *number of model parameters to be estimated and the amount of randomness in the data*. The sample size required increases with the number of parameters to be estimated, and the amount of noise in the data.
Some textbooks provide rules-of-thumb giving minimum sample sizes for various time series models. These are misleading and unsubstantiated in theory or practice. Further, they ignore the underlying variability of the data and often overlook the number of parameters to be estimated as well. There is, for example, no justification for the magic number of 30 often given as a minimum for ARIMA modelling. The only theoretical limit is that we need more observations than there are parameters in our forecasting model. However, in practice, we usually need substantially more observations than that.
Ideally, we would test if our chosen model performs well out-of-sample compared to some simpler approaches. However, with short series, there is not enough data to allow some observations to be withheld for testing purposes, and even time series cross validation can be difficult to apply. The AICc is particularly useful here, because it is a proxy for the one-step forecast out-of-sample MSE. Choosing the model with the minimum AICc value allows both the number of parameters and the amount of noise to be taken into account.
What tends to happen with short series is that the AICc suggests simple models because anything with more than one or two parameters will produce poor forecasts due to the estimation error. We will fit an ARIMA model to the annual series from the M3-competition with fewer than 20 observations. First we need to create a tsibble, containing the relevant series.
```
m3totsibble <- function(z) {
bind_rows(
as_tsibble(z$x) |> mutate(Type = "Training"),
as_tsibble(z$xx) |> mutate(Type = "Test")
) |>
mutate(
st = z$st,
type = z$type,
period = z$period,
description = z$description,
sn = z$sn
) |>
as_tibble()
}
short <- Mcomp::M3 |>
subset("yearly") |>
purrr::map_dfr(m3totsibble) |>
group_by(sn) |>
mutate(n = max(row_number())) |>
filter(n <= 20) |>
ungroup() |>
as_tsibble(index = index, key = c(sn, period, st))
```
Now we can apply an ARIMA model to each series.
```
short_fit <- short |>
model(arima = ARIMA(value))
```
Of the 152 series,
21 had models with zero parameters (white noise and random walks),
86 had models with one parameter,
31 had models with two parameters,
13 had models with three parameters, and only
1 series had a model with four parameters.
### Forecasting very long time series
Most time series models do not work well for very long time series. The problem is that real data do not come from the models we use. When the number of observations is not large (say up to about 200) the models often work well as an approximation to whatever process generated the data. But eventually we will have enough data that the difference between the true process and the model starts to become more obvious. An additional problem is that the optimisation of the parameters becomes more time consuming because of the number of observations involved.
What to do about these issues depends on the purpose of the model. A more flexible and complicated model could be used, but this still assumes that the model structure will work over the whole period of the data. A better approach is usually to allow the model itself to change over time. ETS models are designed to handle this situation by allowing the trend and seasonal terms to evolve over time. ARIMA models with differencing have a similar property. But dynamic regression models do not allow any evolution of model components.
If we are only interested in forecasting the next few observations, one simple approach is to throw away the earliest observations and only fit a model to the most recent observations. Then an inflexible model can work well because there is not enough time for the relationships to change substantially.
For example, we fitted a dynamic harmonic regression model to 26 years of weekly gasoline production in Section [13.1](https://otexts.com/fpp3/weekly.html#weekly). It is, perhaps, unrealistic to assume that the seasonal pattern remains the same over nearly three decades. So we could simply fit a model to the most recent years instead.
## 13.8 Forecasting on training and test sets
Typically, we compute one-step forecasts on the training data (the “fitted values”) and multi-step forecasts on the test data. However, occasionally we may wish to compute multi-step forecasts on the training data, or one-step forecasts on the test data.
### Multi-step forecasts on training data
We normally define fitted values to be one-step forecasts on the training set (see Section [5.3](https://otexts.com/fpp3/residuals.html#residuals)), but a similar idea can be used for multi-step forecasts. We will illustrate the method using an ARIMA model for the Australian take-away food expenditure. The last five years are used for a test set, and the forecasts are plotted in Figure [13.9](https://otexts.com/fpp3/training-test.html#fig:isms).
```
training <- auscafe |> filter(year(Month) <= 2013)
test <- auscafe |> filter(year(Month) > 2013)
cafe_fit <- training |>
model(ARIMA(log(Turnover)))
cafe_fit |>
forecast(h = 60) |>
autoplot(auscafe) +
labs(title = "Australian food expenditure",
y = "$ (billions)")
```
![Forecasts from an ARIMA model fitted to the Australian monthly expenditure on cafés, restaurants and takeaway food services.](https://otexts.com/fpp3/fpp_files/figure-html/isms-1.png)
Figure 13.9: Forecasts from an ARIMA model fitted to the Australian monthly expenditure on cafés, restaurants and takeaway food services.
The `fitted()` function has an `h` argument to allow for \(h\)-step “fitted values” on the training set. Figure [13.10](https://otexts.com/fpp3/training-test.html#fig:isms2) is a plot of 12-step (one year) forecasts on the training set. Because the model involves both seasonal (lag 12) and first (lag 1) differencing, it is not possible to compute these forecasts for the first few observations.
```
fits12 <- fitted(cafe_fit, h = 12)
training |>
autoplot(Turnover) +
autolayer(fits12, .fitted, col = "#D55E00") +
labs(title = "Australian food expenditure",
y = "$ (billions)")
```
![Twelve-step fitted values from an ARIMA model fitted to the Australian café training data.](https://otexts.com/fpp3/fpp_files/figure-html/isms2-1.png)
Figure 13.10: Twelve-step fitted values from an ARIMA model fitted to the Australian café training data.
### One-step forecasts on test data
It is common practice to fit a model using training data, and then to evaluate its performance on a test data set. The way this is usually done means the comparisons on the test data use different forecast horizons. In the above example, we have used the last sixty observations for the test data, and estimated our forecasting model on the training data. Then the forecast errors will be for 1-step, 2-steps, …, 60-steps ahead. The forecast variance usually increases with the forecast horizon, so if we are simply averaging the absolute or squared errors from the test set, we are combining results with different variances.
One solution to this issue is to obtain 1-step errors on the test data. That is, we still use the training data to estimate any parameters, but when we compute forecasts on the test data, we use all of the data preceding each observation (both training and test data). So our training data are for times \(1,2,\dots,T-60\). We estimate the model on these data, but then compute \(\hat{y}_{T-60+h|T-61+h}\), for \(h=1,\dots,T-1\). Because the test data are not used to estimate the parameters, this still gives us a “fair” forecast.
Using the same ARIMA model used above, we now apply the model to the test data.
```
cafe_fit |>
refit(test) |>
accuracy()
#> # A tibble: 1 × 10
#> .model .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 ARIMA(log(Turnover… Trai… -2.49 20.5 15.4 -0.169 1.06 0.236 0.259 -0.0502
```
Note that model is not re-estimated in this case. Instead, the model obtained previously (and stored as `cafe_fit`) is applied to the `test` data. Because the model was not re-estimated, the “residuals” obtained here are actually one-step forecast errors. Consequently, the results produced from the `accuracy()` command are actually on the test set (despite the output saying “Training set”). This approach can be used to compare one-step forecasts from different models.
## 13.9 Dealing with outliers and missing values
Real data often contains missing values, outlying observations, and other messy features. Dealing with them can sometimes be troublesome.
### Outliers
Outliers are observations that are very different from the majority of the observations in the time series. They may be errors, or they may simply be unusual. (See Section [7.3](https://otexts.com/fpp3/regression-evaluation.html#regression-evaluation) for a discussion of outliers in a regression context.) None of the methods we have considered in this book will work well if there are extreme outliers in the data. In this case, we may wish to replace them with missing values, or with an estimate that is more consistent with the majority of the data.
Simply replacing outliers without thinking about why they have occurred is a dangerous practice. They may provide useful information about the process that produced the data, which should be taken into account when forecasting. However, if we are willing to assume that the outliers are genuinely errors, or that they wont occur in the forecasting period, then replacing them can make the forecasting task easier.
Figure [13.11](https://otexts.com/fpp3/missing-outliers.html#fig:ahoutlier) shows the number of visitors to the Adelaide Hills region of South Australia. There appears to be an unusual observation in 2002 Q4.
```
tourism |>
filter(
Region == "Adelaide Hills", Purpose == "Visiting"
) |>
autoplot(Trips) +
labs(title = "Quarterly overnight trips to Adelaide Hills",
y = "Number of trips")
```
![Number of overnight trips to the Adelaide Hills region of South Australia.](https://otexts.com/fpp3/fpp_files/figure-html/ahoutlier-1.png)
Figure 13.11: Number of overnight trips to the Adelaide Hills region of South Australia.
One useful way to find outliers is to apply `STL()` to the series with the argument `robust=TRUE`. Then any outliers should show up in the remainder series. The data in Figure [13.11](https://otexts.com/fpp3/missing-outliers.html#fig:ahoutlier) have almost no visible seasonality, so we will apply STL without a seasonal component by setting `period=1`.
```
ah_decomp <- tourism |>
filter(
Region == "Adelaide Hills", Purpose == "Visiting"
) |>
# Fit a non-seasonal STL decomposition
model(
stl = STL(Trips ~ season(period = 1), robust = TRUE)
) |>
components()
ah_decomp |> autoplot()
```
![STL decomposition of visitors to the Adelaide Hills region of South Australia, with no seasonal component.](https://otexts.com/fpp3/fpp_files/figure-html/stlahdecomp-1.png)
Figure 13.12: STL decomposition of visitors to the Adelaide Hills region of South Australia, with no seasonal component.
In the above example the outlier was easy to identify. In more challenging cases, using a boxplot of the remainder series would be useful. We can identify as outliers those that are greater than 1.5 interquartile ranges (IQRs) from the central 50% of the data. If the remainder was normally distributed, this would show 7 in every 1000 observations as “outliers”. A stricter rule is to define outliers as those that are greater than 3 interquartile ranges (IQRs) from the central 50% of the data, which would make only 1 in 500,000 normally distributed observations to be outliers. This is the rule we prefer to use.
```
outliers <- ah_decomp |>
filter(
remainder < quantile(remainder, 0.25) - 3*IQR(remainder) |
remainder > quantile(remainder, 0.75) + 3*IQR(remainder)
)
outliers
#> # A dable: 1 x 9 [1Q]
#> # Key: Region, State, Purpose, .model [1]
#> # : Trips = trend + remainder
#> Region State Purpose .model Quarter Trips trend remainder season_adjust
#> <chr> <chr> <chr> <chr> <qtr> <dbl> <dbl> <dbl> <dbl>
#> 1 Adelaide H… Sout… Visiti… stl 2002 Q4 81.1 11.1 70.0 81.1
```
This finds the one outlier that we suspected from Figure [13.11](https://otexts.com/fpp3/missing-outliers.html#fig:ahoutlier). Something similar could be applied to the full data set to identify unusual observations in other series.
### Missing values
Missing data can arise for many reasons, and it is worth considering whether the missingness will induce bias in the forecasting model. For example, suppose we are studying sales data for a store, and missing values occur on public holidays when the store is closed. The following day may have increased sales as a result. If we fail to allow for this in our forecasting model, we will most likely under-estimate sales on the first day after the public holiday, but over-estimate sales on the days after that. One way to deal with this kind of situation is to use a dynamic regression model, with dummy variables indicating if the day is a public holiday or the day after a public holiday. No automated method can handle such effects as they depend on the specific forecasting context.
In other situations, the missingness may be essentially random. For example, someone may have forgotten to record the sales figures, or the data recording device may have malfunctioned. If the timing of the missing data is not informative for the forecasting problem, then the missing values can be handled more easily.
Finally, we might remove some unusual observations, thus creating missing values in the series.
Some methods allow for missing values without any problems. For example, the naïve forecasting method continues to work, with the most recent non-missing value providing the forecast for the future time periods. Similarly, the other benchmark methods introduced in Section [5.2](https://otexts.com/fpp3/simple-methods.html#simple-methods) will all produce forecasts when there are missing values present in the historical data. The `fable` functions for ARIMA models, dynamic regression models and NNAR models will also work correctly without causing errors. However, other modelling functions do not handle missing values including `ETS()` and `STL()`.
When missing values cause errors, there are at least two ways to handle the problem. First, we could just take the section of data after the last missing value, assuming there is a long enough series of observations to produce meaningful forecasts. Alternatively, we could replace the missing values with estimates. To do this, we first fit an ARIMA model to the data containing missing values, and then use the model to interpolate the missing observations.
We will replace the outlier identified in Figure [13.12](https://otexts.com/fpp3/missing-outliers.html#fig:stlahdecomp) by an estimate using an ARIMA model.
```
ah_miss <- tourism |>
filter(
Region == "Adelaide Hills",
Purpose == "Visiting"
) |>
# Remove outlying observations
anti_join(outliers) |>
# Replace with missing values
fill_gaps()
ah_fill <- ah_miss |>
# Fit ARIMA model to the data containing missing values
model(ARIMA(Trips)) |>
# Estimate Trips for all periods
interpolate(ah_miss)
ah_fill |>
# Only show outlying periods
right_join(outliers |> select(-Trips))
#> # A tsibble: 1 x 9 [?]
#> # Key: Region, State, Purpose [1]
#> Region State Purpose Quarter Trips .model trend remainder season_adjust
#> <chr> <chr> <chr> <qtr> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 Adelaide H… Sout… Visiti… 2002 Q4 8.50 stl 11.1 70.0 81.1
```
The `interpolate()` function uses the ARIMA model to estimate any missing values in the series. In this case, the outlier of 81.1 has been replaced with 8.5. The resulting series is shown in Figure [13.13](https://otexts.com/fpp3/missing-outliers.html#fig:replacement-plot).
The `ah_fill` data could now be modeled with a function that does not allow missing values.
```
ah_fill |>
autoplot(Trips) +
autolayer(ah_fill |> filter_index("2002 Q3"~"2003 Q1"),
Trips, colour="#D55E00") +
labs(title = "Quarterly overnight trips to Adelaide Hills",
y = "Number of trips")
```
![Number of overnight trips to the Adelaide Hills region of South Australia with the 2002Q4 outlier being replaced using an ARIMA model for interpolation.](https://otexts.com/fpp3/fpp_files/figure-html/replacement-plot-1.png)
Figure 13.13: Number of overnight trips to the Adelaide Hills region of South Australia with the 2002Q4 outlier being replaced using an ARIMA model for interpolation.
## 13.10 Further reading
So many diverse topics are discussed in this chapter, that it is not possible to point to specific references on all of them. The last chapter in Ord et al. ([2017](#ref-Ord2017)) also covers “Forecasting in practice” and discusses other issues that might be of interest to readers.
### Bibliography
Ord, J. K., Fildes, R., & Kourentzes, N. (2017). *Principles of business forecasting* (2nd ed.). Wessex Press Publishing Co.
+318
View File
@@ -0,0 +1,318 @@
Source: https://otexts.com/fpp3/translations.html (chapter translations, 6 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - 99-back-matter
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Translations
### Second edition
A [**Chinese translation**](https://otexts.com/fppcn) is available, thanks to [Professor Yanfei Kang](https://yanfei.site/) and [Professor Feng Li](https://feng.li/), and their students.
A [**Korean translation**](https://otexts.com/fppkr) is available, thanks to [Dr Daniel Young Ho Kim](http://danielykim.me/).
### Third edition
A [**Chinese translation**](https://otexts.com/fpp3cn) is available, thanks to [Professor Yanfei Kang](https://yanfei.site/) and [Professor Feng Li](https://feng.li/), and their students.
A [**Greek translation**](https://otexts.com/fppgr) is available, thanks to [Dr Ioannis Nikas](http://tourism.upatras.gr/nikas/) and [Dr Athanasios Koutras](https://thanasiskoutras.com).
An [**Italian translation**](https://otexts.com/fppit) is available, thanks to [Professor Domenico Vistocco](http://domenicovistocco.it/) and [Professor Tommaso Di Fonzo](https://homes.stat.unipd.it/tommasodifonzo/), and their colleagues and students at the University of Naples Federico II and the University of Padua.
A [**Japanese translation**](https://otexts.com/fppjp) is available, thanks to [Mitsuo Shiota](https://mitsuoxv.rbind.io/) and [Professor Tomoo Inoue](https://www-cv01.ufinity.jp/seikei/cvclients/researchers/tomoo-inoue?frame_id=348&lang=en).
A [**Portuguese translation**](https://otexts.com/fpppg) is available, thanks to Matheus Henrique Dal Molin Ribeiro, Gilson Adamczuk Oliveira, Bruno Luis Barbosa Cavalcante, José Donizetti de Lima, Manuel Pereira Lopes, Sandra Cristina De Faria Ramos, Ricardo Puziol de Oliveira, amd Tatiane Teixeira Leal.
A [**Russian translation**](https://dmkpress.com/catalog/computer/data/978-5-93700-151-1/) is available in print from DMK Press.
A [**Spanish translation**](https://otexts.com/fppsp) is available, thanks to [José Manuel Benítez Sánchez](https://scholar.google.com/citations?user=1iSTbIkAAAAJ&hl=en).
### In progress
Translations into Farsi, French, German, Tamil, Turkish, and Arabic, are already underway. If you think you can help with any of these, please let Rob Hyndman know.
If anyone is interested in creating a translation of the book into another language, please contact Rob Hyndman.
# About the authors
![](https://otexts.com/fpp3/figs/Hyndman.png) [**Rob J Hyndman**](https://robjhyndman.com) is the Vice-Chancellors Distinguished Professor of Statistics in the Department of Econometrics and Business Statistics at Monash University, Australia. He is author of 6 books and over 250 research papers, and an elected Fellow of the Australian Academy of Science, the Academy for the Social Sciences in Australia, and the International Institute of Forecasters. He was Editor-in-Chief of the *International Journal of Forecasting* from 2005 to 2018. For over 40 years, Rob has maintained an active consulting practice, assisting hundreds of companies and organisations on forecasting problems. He has won awards for his research, teaching, consulting and graduate supervision.
![](https://otexts.com/fpp3/figs/Athanasopoulos.png) [**George Athanasopoulos**](https://research.monash.edu/en/persons/george-athanasopoulos) is a Professor and Head of the Department of Econometrics and Business Statistics at Monash University, Australia. He has been a Director of the International Institute of Forecasters (IIF) since 2014, and was President from 2020 to 2024. George has received multiple awards and distinctions for his research and teaching. He is on the Editorial Boards of the *Journal of Travel Research* and the *International Journal of Forecasting*.
# Buy a print version
![](https://otexts.com/fpp3/figs/fpp3_front_cover.jpg) | Paperback [Amazon Australia](https://www.amazon.com.au/dp/0987507133?tag=otexts04-22) [Amazon Canada](https://www.amazon.ca/dp/0987507133?tag=otexts08-20) [Amazon France](https://www.amazon.fr/dp/0987507133?tag=otexts0e-21) [Amazon Germany](https://www.amazon.de/dp/0987507133?tag=otexts0c-21) [Amazon Italy](https://www.amazon.it/dp/0987507133?tag=otexts08-21) [Amazon Japan](https://www.amazon.co.jp/dp/0987507133?tag=otexts-22) [Amazon Spain](https://www.amazon.es/dp/0987507133?tag=otexts07-21) [Amazon UK](https://www.amazon.co.uk/dp/0987507133?tag=wwwotextsorg-21) [Amazon USA](https://www.amazon.com/dp/0987507133?tag=otexts-20) *(As an Amazon Associate, OTexts earns from purchases obtained by clicking these links.)* |
# Help and feedback
**Got a problem with *Forecasting: Principles and Practice*?**
If youre looking for help with your forecasting, please ask on the [OTexts discussion forum](https://github.com/orgs/OTexts/discussions). If youve found an error in the book (even a tiny typo), you can [let us know](https://github.com/orgs/OTexts/discussions/categories/error-report) on the forum.
# Changelog
**Changes made since the last print edition (2021)**
* YouTube videos added to start of many sections.
* Typos fixed, and some wording improved for clarification or accuracy.
* Switched pipe from `%>%` to `|>`.
* Packages updated to latest CRAN versions.
* `ggtime` package now used for graphics (instead of `feasts`)
* Code updated to ensure it works with latest CRAN packages, and to use new features of some packages.
### Preface
* Link to YouTube playlist added.
* Link to discussion forum added.
### Chapter 1
* Corrected description of Babylonian sheep liver forecasting (was “distribution of maggots in a rotten sheeps liver”; now “appearance of a sheeps liver”). Thanks to Srikanth Reddy for pointing out the error.
* Corrected statement about Emperor Constantius II, and provided footnote to source.
* Fixed date of the Vagrancy Act and provided a quote and footnote to source.
### Chapter 2
* **Section 2.10**: Merged two exercises (now Exercise 1).
### Chapter 3
* **Section 3.6**: Added reference to Bandara et al. ([2025](#ref-mstl)).
### Chapter 5
* **Section 5.4**: Discussion of portmanteau tests no longer uses degrees of freedom based on model parameters, except for ARIMA models.
* **Section 5.5**: Corrected the residual standard deviation formula to include \(M\) (the number of missing residuals) in the denominator; corrected the drift method forecast standard deviation formula.
* **Section 5.5**: Clarified the bootstrapped prediction intervals section, introducing \(y^\*\) notation to distinguish simulated from observed values.
### Chapter 9
* **Section 9.1**: Updated explanation of KPSS unit root test p-values.
* **Section 9.7**: Added subsection on portmanteau tests of residuals for ARIMA models.
* **Section 9.11**: Removed Exercise 17 (which used Quandl).
### Chapter 13
* **Section 13.2**: Added a reference to Syntetos & Boylan ([2001](#ref-SB01)).
* **Section 13.4**: Added a reference to Wang et al. ([2023](#ref-combinations)).
### Appendix: For instructors
* All solutions rewritten using quarto.
* Slides used in videos added.
* Past exams added.
* Link to Python edition added.
### Translations
* Page added.
### About the authors
* Updated photos and bios.
### Buy a print version
* Updated to include many more Amazon sites.
### Help and feedback
* Form removed and link added to discussion forum.
### Changelog
* Page added.
### Bibliography
* Added Bandara et al. ([2025](#ref-mstl)).
* Updated Panagiotelis et al. ([2023](#ref-PanEtAl2020_Probabilistic)).
* Added Syntetos & Boylan ([2001](#ref-SB01)).
* Added Wang et al. ([2023](#ref-combinations)).
* Added DOI or Amazon links to bibliography entries where available.
### Bibliography
Bandara, K., Hyndman, R. J., & Bergmeir, C. (2025). MSTL: A seasonal-trend decomposition algorithm for time series with multiple seasonal patterns. *International J Operational Research*, *52*(1).
Panagiotelis, A., Gamakumara, P., Athanasopoulos, G., & Hyndman, R. J. (2023). Probabilistic forecast reconciliation: Properties, evaluation and score optimisation. *European J Operational Research*, *306*(2), 693706.
Syntetos, A. A., & Boylan, J. E. (2001). On the bias of intermittent demand estimates. *International Journal of Production Economics*, *71*, 457466.
Wang, X., Hyndman, R. J., Li, F., & Kang, Y. (2023). Forecast combinations: An over 50-year review. *International J Forecasting*, *39*(4), 15181547.
# Bibliography
Anscombe, F. J. (1973). Graphs in statistical analysis. *The American Statistician*, *27*(1), 1721.
Armstrong, J. S. (1978). *Long-range forecasting: From crystal ball to computer*. John Wiley & Sons.
Armstrong, J. S. (Ed.). (2001). *Principles of forecasting: A handbook for researchers and practitioners*. Kluwer Academic Publishers.
Athanasopoulos, G., Ahmed, R. A., & Hyndman, R. J. (2009). Hierarchical forecasts for Australian domestic tourism. *International Journal of Forecasting*, *25*, 146166.
Athanasopoulos, G., Gamakumara, P., Panagiotelis, A., Hyndman, R. J., & Affan, M. (2020). Hierarchical forecasting. In P. Fuleky (Ed.), *Macroeconomic forecasting in the era of big data* (pp. 689719). Springer.
Athanasopoulos, G., & Hyndman, R. J. (2008). Modelling and forecasting Australian domestic tourism. *Tourism Management*, *29*(1), 1931.
Athanasopoulos, G., Hyndman, R. J., Kourentzes, N., & Petropoulos, F. (2017). Forecasting with temporal hierarchies. *European Journal of Operational Research*, *262*(1), 6074.
Athanasopoulos, G., Poskitt, D. S., & Vahid, F. (2012). Two canonical VARMA forms: Scalar component models vis-à-vis the echelon form. *Econometric Reviews*, *31*(1), 6083.
Bandara, K., Hyndman, R. J., & Bergmeir, C. (2025). MSTL: A seasonal-trend decomposition algorithm for time series with multiple seasonal patterns. *International J Operational Research*, *52*(1).
Bates, J. M., & Granger, C. W. J. (1969). The combination of forecasts. *Operational Research Quarterly*, *20*(4), 451468.
Bergmeir, C., Hyndman, R. J., & Benítez, J. M. (2016). Bagging exponential smoothing methods using STL decomposition and Box-Cox transformation. *International Journal of Forecasting*, *32*(2), 303312.
Bergmeir, C., Hyndman, R. J., & Koo, B. (2018). A note on the validity of cross-validation for evaluating autoregressive time series prediction. *Computational Statistics and Data Analysis*, *120*, 7083.
Bickel, P. J., & Doksum, K. A. (1981). An analysis of transformations revisited. *Journal of the American Statistical Association*, *76*(374), 296311.
Box, G. E. P., & Cox, D. R. (1964). An analysis of transformations. *Journal of the Royal Statistical Society. Series B, Statistical Methodology*, *26*(2), 211252.
Box, G. E. P., & Jenkins, G. M. (1970). *Time series analysis: Forecasting and control*. Holden-Day.
Box, G. E. P., Jenkins, G. M., Reinsel, G. C., & Ljung, G. M. (2015). *Time series analysis: Forecasting and control* (5th ed). John Wiley & Sons.
Brockwell, P. J., & Davis, R. A. (2016). *Introduction to time series and forecasting* (3rd ed). Springer.
Brown, R. G. (1959). *Statistical forecasting for inventory control*. McGraw/Hill.
Buehler, R., Messervey, D., & Griffin, D. (2005). Collaborative planning and prediction: Does group discussion affect optimistic biases in time estimation? *Organizational Behavior and Human Decision Processes*, *97*(1), 4763.
Christou, V., & Fokianos, K. (2015). On count time series prediction. *Journal of Statistical Computation and Simulation*, *85*(2), 357373.
Clemen, R. (1989). Combining forecasts: A review and annotated bibliography. *International Journal of Forecasting*, *5*(4), 559583.
Cleveland, R. B., Cleveland, W. S., McRae, J. E., & Terpenning, I. J. (1990). STL: A seasonal-trend decomposition procedure based on loess. *Journal of Official Statistics*, *6*(1), 333.
Cleveland, W. S. (1993). *Visualizing data*. Hobart Press.
Croston, J. D. (1972). Forecasting and stock control for intermittent demands. *Operational Research Quarterly*, *23*(3), 289303.
Dagum, E. B., & Bianconcini, S. (2016). *Seasonal adjustment methods and real time trend-cycle estimation*. Springer.
Eroglu, C., & Croxton, K. L. (2010). Biases in judgmental adjustments of statistical forecasts: The role of individual differences. *International Journal of Forecasting*, *26*(1), 116133.
Fan, S., & Hyndman, R. J. (2012). Short-term load forecasting based on a semi-parametric additive model. *IEEE Transactions on Power Systems*, *27*(1), 134141.
Fildes, R., & Goodwin, P. (2007a). Against your better judgment? How organizations can improve their use of management judgment in forecasting. *Interfaces*, *37*(6), 570576.
Fildes, R., & Goodwin, P. (2007b). Good and bad judgment in forecasting: Lessons from four companies. *Foresight: The International Journal of Applied Forecasting*, *8*, 510.
Franses, P. H., & Legerstee, R. (2013). Do statistical forecasting models for SKU-level data benefit from including past expert knowledge? *International Journal of Forecasting*, *29*(1), 8087.
Gardner, E. S. (1985). Exponential smoothing: The state of the art. *Journal of Forecasting*, *4*(1), 128.
Gardner, E. S. (2006). Exponential smoothing: The state of the art — Part II. *International Journal of Forecasting*, *22*, 637666.
Gardner, E. S., & McKenzie, E. (1985). Forecasting trends in time series. *Management Science*, *31*(10), 12371246.
Gneiting, T., & Katzfuss, N. (2014). Probabilistic forecasting. *Annual Review of Statistics and Its Application*, *1*(1), 125151.
Goodwin, P., & Wright, G. (2009). *Decision analysis for management judgment* (4th ed). John Wiley & Sons.
Green, K. C., & Armstrong, J. S. (2007). Structured analogies for forecasting. *International Journal of Forecasting*, *23*(3), 365376.
Gross, C. W., & Sohl, J. E. (1990). Disaggregation methods to expedite product line forecasting. *Journal of Forecasting*, *9*, 233254.
Groves, R. M., Fowler, F. J., Couper, M. P., Lepkowski, J. M., Singer, E., & Tourangeau, R. (2009). *Survey methodology* (2nd ed). John Wiley & Sons.
Guerrero, V. M. (1993). Time-series analysis supported by power transformations. *Journal of Forecasting*, *12*(1), 3748.
Hamilton, J. D. (1994). *Time series analysis*. Princeton University Press, Princeton.
Harrell, F. E. (2015). *Regression modeling strategies: With applications to linear models, logistic and ordinal regression, and survival analysis* (2nd ed). Springer.
Harris, R., & Sollis, R. (2003). *Applied time series modelling and forecasting*. John Wiley & Sons.
Harvey, N. (2001). Improving judgment in forecasting. In J. S. Armstrong (Ed.), *Principles of forecasting: A handbook for researchers and practitioners* (pp. 5980). Kluwer Academic Publishers.
Hewamalage, H., Bergmeir, C., & Bandara, K. (2021). Recurrent neural networks for time series forecasting: Current status and future directions. *International Journal of Forecasting*, *37*(1), 388427.
Holt, C. C. (1957). *Forecasting seasonals and trends by exponentially weighted averages* (ONR Memorandum No. 52). Carnegie Institute of Technology, Pittsburgh USA. Reprinted in the *International Journal of Forecasting*, 2004.
Hyndman, R. J., Ahmed, R. A., Athanasopoulos, G., & Shang, H. L. (2011). Optimal combination forecasts for hierarchical time series. *Computational Statistics and Data Analysis*, *55*(9), 25792589.
Hyndman, R. J., & Fan, S. (2010). Density forecasting for long-term peak electricity demand. *IEEE Transactions on Power Systems*, *25*(2), 11421153.
Hyndman, R. J., & Khandakar, Y. (2008). Automatic time series forecasting: The forecast package for R. *Journal of Statistical Software*, *27*(1), 122.
Hyndman, R. J., & Koehler, A. B. (2006). Another look at measures of forecast accuracy. *International Journal of Forecasting*, *22*(4), 679688.
Hyndman, R. J., Koehler, A. B., Ord, J. K., & Snyder, R. D. (2008). *Forecasting with exponential smoothing: The state space approach*. Springer-Verlag.
Hyndman, R. J., Wang, E., & Laptev, N. (2015). Large-scale unusual time series detection. *Proceedings of the IEEE International Conference on Data Mining*, 16161619.
Izenman, A. J. (2008). *Modern multivariate statistical techniques: Regression, classification and manifold learning*. Springer.
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2021). *An introduction to statistical learning: With applications in R*. Springer.
Kahn, K. B. (2006). *New product forecasting: An applied approach*. M.E. Sharp.
Kahneman, D., & Lovallo, D. (1993). Timid choices and bold forecasts: A cognitive perspective on risk taking. *Management Science*, *39*(1), 1731.
Kang, Y., Hyndman, R. J., & Smith-Miles, K. (2017). Visualising forecasting algorithm performance using time series instance spaces. *International Journal of Forecasting*, *33*(2), 345358.
Kourentzes, N., & Athanasopoulos, G. (2019). Cross-temporal coherent forecasts for Australian tourism. *Annals of Tourism Research*, *75*, 393409.
Kwiatkowski, D., Phillips, P. C. B., Schmidt, P., & Shin, Y. (1992). Testing the null hypothesis of stationarity against the alternative of a unit root: How sure are we that economic time series have a unit root? *Journal of Econometrics*, *54*(1-3), 159178.
Lahiri, S. N. (2003). *Resampling methods for dependent data*. Springer Science & Business Media.
Lawrence, M., Goodwin, P., OConnor, M., & Önkal, D. (2006). Judgmental forecasting: A review of progress over the last 25 years. *International Journal of Forecasting*, *22*(3), 493518.
Lütkepohl, H. (2007). General-to-specific or specific-to-general modelling? An opinion on current econometric terminology. *Journal of Econometrics*, *136*(1), 234319.
Morwitz, V. G., Steckel, J. H., & Gupta, A. (2007). When do purchase intentions predict sales? *International Journal of Forecasting*, *23*(3), 347364.
Önkal, D., Sayım, K. Z., & Gönül, M. S. (2013). Scenarios as channels of forecast advice. *Technological Forecasting and Social Change*, *80*(4), 772788.
Ord, J. K., Fildes, R., & Kourentzes, N. (2017). *Principles of business forecasting* (2nd ed.). Wessex Press Publishing Co.
Panagiotelis, A., Athanasopoulos, G., Gamakumara, P., & Hyndman, R. J. (2021). Forecast reconciliation: A geometric view with new insights on bias correction. *International Journal of Forecasting*, *37*(1), 343359.
Panagiotelis, A., Gamakumara, P., Athanasopoulos, G., & Hyndman, R. J. (2023). Probabilistic forecast reconciliation: Properties, evaluation and score optimisation. *European J Operational Research*, *306*(2), 693706.
Pankratz, A. E. (1991). *Forecasting with dynamic regression models*. John Wiley & Sons.
Pegels, C. C. (1969). Exponential forecasting: Some new variations. *Management Science*, *15*(5), 311315.
Peña, D., Tiao, G. C., & Tsay, R. S. (Eds.). (2001). *A course in time series analysis*. John Wiley & Sons.
Pfaff, B. (2008). *Analysis of integrated and cointegrated time series with R*. Springer Science & Business Media.
Randall, D. M., & Wolff, J. A. (1994). The time interval in the intention-behaviour relationship: Meta-analysis. *British Journal of Social Psychology*, *33*(4), 405418.
Rowe, G. (2007). A guide to Delphi. *Foresight: The International Journal of Applied Forecasting*, *8*, 1116.
Rowe, G., & Wright, G. (1999). The Delphi technique as a forecasting tool: Issues and analysis. *International Journal of Forecasting*, *15*(4), 353375.
Sanders, N., Goodwin, P., Önkal, D., Gönül, M. S., Harvey, N., Lee, A., & Kjolso, L. (2005). When and how should statistical forecasts be judgmentally adjusted? *Foresight: The International Journal of Applied Forecasting*, *1*(1), 523.
Sheather, S. J. (2009). *A modern approach to regression with R*. Springer.
Shenstone, L., & Hyndman, R. J. (2005). Stochastic models underlying Crostons method for intermittent demand forecasting. *Journal of Forecasting*, *24*(6), 389402.
Syntetos, A. A., & Boylan, J. E. (2001). On the bias of intermittent demand estimates. *International Journal of Production Economics*, *71*, 457466.
Taylor, J. W. (2003). Exponential smoothing with a damped multiplicative trend. *International Journal of Forecasting*, *19*(4), 715725.
Taylor, S. J., & Letham, B. (2018). Forecasting at scale. *The American Statistician*, *72*(1), 3745.
Theodosiou, M. (2011). Forecasting monthly and quarterly time series using STL decomposition. *International Journal of Forecasting*, *27*(4), 11781195.
Unwin, A. (2015). *Graphical data analysis with R*. Chapman; Hall/CRC.
Wang, X., Hyndman, R. J., Li, F., & Kang, Y. (2023). Forecast combinations: An over 50-year review. *International J Forecasting*, *39*(4), 15181547.
Wang, X., Smith, K. A., & Hyndman, R. J. (2006). Characteristic-based clustering for time series data. *Data Mining and Knowledge Discovery*, *13*(3), 335364.
Wickramasuriya, S. L., Athanasopoulos, G., & Hyndman, R. J. (2019). Optimal forecast reconciliation for hierarchical and grouped time series through trace minimization. *Journal of the American Statistical Association*, *114*(526), 804819.
Winkler, R. L. (1972). A decision-theoretic approach to interval estimation. *Journal of the American Statistical Association*, *67*(337), 187191.
Winters, P. R. (1960). Forecasting sales by exponentially weighted moving averages. *Management Science*, *6*(3), 324342.
Young, P. C., Pedregal, D. J., & Tych, W. (1999). Dynamic harmonic regression. *Journal of Forecasting*, *18*, 369394.
+40
View File
@@ -0,0 +1,40 @@
Source: https://otexts.com/fpp3/appendix-for-instructors.html (chapter appendix-for-instructors, 1 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - app-for-instructors
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Appendix: For instructors
### Solutions to exercises
Solutions to exercises are password protected and only available to instructors. Please [complete this request form](https://goo.gl/forms/nJsXgojZlGPhZ6uu1). You will need to provide evidence that you are an instructor and not a student (e.g., a link to a university website listing you as a member of faculty). Please also use your university email address on the form.
* Chapter 1 [qmd](https://OTexts.com/fpp3/solutions/Chapter1.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter1.html)
* Chapter 2 [qmd](https://OTexts.com/fpp3/solutions/Chapter2.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter2.html)
* Chapter 3 [qmd](https://OTexts.com/fpp3/solutions/Chapter3.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter3.html)
* Chapter 4 [qmd](https://OTexts.com/fpp3/solutions/Chapter4.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter4.html)
* Chapter 5 [qmd](https://OTexts.com/fpp3/solutions/Chapter5.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter5.html)
* Chapter 7 [qmd](https://OTexts.com/fpp3/solutions/Chapter7.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter7.html)
* Chapter 8 [qmd](https://OTexts.com/fpp3/solutions/Chapter8.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter8.html)
* Chapter 9 [qmd](https://OTexts.com/fpp3/solutions/Chapter9.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter9.html)
* Chapter 10 [qmd](https://OTexts.com/fpp3/solutions/Chapter10.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter10.html)
* Chapter 11 [qmd](https://OTexts.com/fpp3/solutions/Chapter11.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter11.html)
* Chapter 12 [qmd](https://OTexts.com/fpp3/solutions/Chapter12.qmd) [html](https://OTexts.com/fpp3/solutions/Chapter12.html)
The qmd files use [this theme](https://OTexts.com/fpp3/solutions/fpp3.scss).
### Slides
[The slides used in the embedded videos](https://github.com/robjhyndman/fpp3_slides) are available via github. You are welcome to adapt these slides for your own purposes.
### Past exams
Here are three exams written by the authors for our own forecasting courses:
* [Sample exam 1](https://OTexts.com/fpp3/solutions/sample_exam_1.pdf)
* [Sample exam 2](https://OTexts.com/fpp3/solutions/sample_exam_2.pdf)
* [Sample exam 3](https://OTexts.com/fpp3/solutions/sample_exam_3.pdf)
### Python resources
For those teaching using Python, there is now a [Python edition of “*Forecasting Principles and Practice*”](https://OTexts.com/fpppy).
+51
View File
@@ -0,0 +1,51 @@
Source: https://otexts.com/fpp3/appendix-reviews.html (chapter appendix-reviews, 1 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - app-reviews
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Appendix: Reviews
* [Amazon reviews 1st ed](https://www.amazon.com/dp/0987507109?tag=otexts-20#averageCustomerReviewsAnchor)
* [Amazon reviews 2nd ed](https://www.amazon.com/dp/0987507117?tag=otexts-20#averageCustomerReviewsAnchor)
* [Amazon reviews 3rd ed](https://www.amazon.com/dp/0987507133?tag=otexts-20#averageCustomerReviewsAnchor)
* [Review from Sandro Saitta in Swiss Analytics, April 2015, p.5. Republished at Data Mining Research.](https://OTexts.com/fpp2/extrafiles/SwissAnalytics201501.pdf)
* [Review from Steve Miller on Information Management, April 2015](https://web.archive.org/web/20200220174633/https%3A//www.information-management.com/opinion/business-analytics-and-forecasting-revisited)
* [Review from Stephan Kolassa in Foresight, Fall 2010.](https://otexts.com/fpp3/extrafiles/Kolassa-review.pdf)
### Testimonials from fellow educators
*Added August 2020*
> “This book is an essential resource for students and practitioners alike. It takes a fresh look on important time series and forecasting concepts. The illustration of theoretical concepts in R is invaluable: it not only helps readers gain hands-on experience but also makes learning the material more fun. I enjoyed teaching from the book, and my students loved the class!”
> “This text provides a wonderful overview of time series methods for the practitioner. Indeed it is an excellent book for training MBAs and MSBAs in the basics of using Time Series models which served as an elective class in both programs. The examples are easy to follow and the R-scripts work well and are effective. The explanation of the methods is clear and concise. Im sure it helped me win a teaching award!”
> “I have been teaching financial econometrics for over 10 years and FPP is one of the best applied books I have come across. It encapsulates a sound introduction to time series forecasting, capturing the statistical principles via coherent”learning by doing” processes in the R language. Feedback from former students suggests it is always a useful reference for them as they start their career in data analytics and financial forecasting. Finally, the authors are very approachable and have provided fantastic help and guidance on teaching time series forecasting.”
> “The text is a great resource as at provides a hands on approach to learning forecasting. I wish more texts would follow this format and philosophy.”
> “This is a great online textbook. I used several sections for my own course which introduces forecasting techniques for time series in the energy field, and I found the material, including the examples and exercises, extremely helpful. Thank you for the great effort of compiling this resource!”
> “This book provides students with little knowledge of mathematics or statistics with an understanding of forecasting methods through an accessible, well-written and practice-oriented presentation. This book is a must for my students following a Master in Business Administration.”
> “I use this textbook for a short workshop course on forecasting for practitioners, and the structure of the book - overview of topics followed by examples in R really helps my students understand concepts well. Highly recommended.”
> “After having been introduced to the world of forecasting myself as a student with the book Forecasting: methods and applications (Makridakis, Wheelwright & Hyndman, 1998), I have been using the successor Forecasting Principles & Practice of Rob Hyndman and George Athanasopoulos for master students in Business Engineering and Business Administration for many years now. It is a very accessible book, which is very easy to use due to its online format, and it is always kept up to date. The students very much appreciate the seamless intertwining of the theory, the many examples and the applications in R. The book is ideal to introduce students to the most important forecasting techniques through interesting examples, with a healthy balance between theoretical depth and relevant applications.”
> “I chose it as a prescribed text book for the Business Forecasting course, which is a core course for Masters of Information Technology and Analytics program in our Business School. Excellent book IMHO.”
> “The book covers basic forecasting tools, like exponential smoothing, and more complex forecasting methods. All with practical R examples such that the students after the course are well prepared for a future in practical forecasting. The book is also very well received by the students.”
> “This book is a great support for students and teachers. With its focus on forecasting and the practical applications in R it is indispensable for business students at our university. And the integration with tidyverse is highly appreciated. Thank You!”
### Testimonials from practitioners and students
* Practitioner, August 2020.
> The book allows someone like me, a complete beginner in forecasting, to learn, gain confidence, and practice skills that are not only valuable, but greatly interesting. Within the realm of forecasting, Im not sure where Id be without this wonderful resource made available to the public.
* [ETC3550, Applied forecasting](https://handbook.monash.edu/2020/units/ETC3550?year=2020) student, Semester 1, 2020.
> Forecasting: Principles and Practice was a pleasant surprise right from the beginning. It is very rare to have such plentiful amount of information available for free within the University environment. Allowing students such as myself to gain free access is something that encourages individuals to read through and learn more about the subject. Furthermore, the easy to use online format made this one of (if not) the most accessible University textbook Ive read. Moreover, the practicality and hands on approach with direct examples (and real-world data) reinforces concepts in an enjoyable way. Being able to show the applications of what you are learning interested me to delve deeper and foster a curious attitude towards each topic. I also appreciated the concise nature which allowed me to read without feeling overloaded or exhausted. Overall, a fantastic resource for those with even the slightest interest in forecasting and data science.
* [ETF3231, Business forecasting](https://handbook.monash.edu/2020/units/ETF3231?year=2020) student, Semester 1, 2020.
> The textbook used in the Business forecasting course is an online book that contains all the materials seen in class. The course content is based on slides but the book is a good additional support. It has been very useful for me to be able to reiterate certain points that I had less understood during the lecture. Moreover, the book is very well constructed, and the content well explained with practical examples, as seen in the course, which made my study very smooth. Finally, the exercises practised during the tutorials are from the textbook. I would recommend everyone to browse the book for the more complicated points of the material!
+46
View File
@@ -0,0 +1,46 @@
Source: https://otexts.com/fpp3/appendix-using-r.html (chapter appendix-using-r, 1 section pages merged)
Title: Forecasting: Principles and Practice 3rd ed - app-using-r
Fetched-via: urllib + markitdown (content div.page-inner section.normal), 2026-07-26
Fetch-status: full content; images/links point to absolute otexts.com URLs
# Appendix: Using R
This book uses R and is designed to be used with R. R is free, available on almost every operating system, and there are thousands of add-on packages to do almost anything you could ever want to do. We recommend you use R with RStudio.
### Installing R and RStudio
1. [Download and install R.](https://cran.r-project.org/)
2. [Download and install RStudio.](https://bit.ly/rstudiodownload)
3. Run RStudio. On the “Packages” tab, click on “Install” and install the package `fpp3` (make sure “install dependencies” is checked).
Thats it! You should now be ready to go.
### R examples in this book
We provide R code for most examples in shaded boxes like this:
```
# Load required packages
library(fpp3)
# Plot one time series
aus_retail |>
filter(`Series ID`=="A3349640L") |>
autoplot(Turnover)
# Produce some forecasts
aus_retail |>
filter(`Series ID`=="A3349640L") |>
model(ETS(Turnover)) |>
forecast(h = "2 years")
```
These examples assume that you have the `fpp3` package loaded as shown above. This needs to be done at the start of every R session, but it wont be included in our examples.
Sometimes we assume that the R code that appears earlier in the same chapter of the book has also been run; so it is best to work through the R code in the order provided within each chapter.
### Getting started with R
If you have never previously used R, please work through the first section (chapters 1-8) of [“R for Data Science”](https://r4ds.hadley.nz) by Garrett Grolemund and Hadley Wickham. While this does not cover time series or forecasting, it will get you used to the basics of the R language, and the `tidyverse` packages. The [Coursera R Programming](https://www.coursera.org/learn/r-programming) course is also highly recommended.
You will learn how to use R for forecasting using the exercises in this book.