-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathChapter_3.Rmd
362 lines (267 loc) · 13.5 KB
/
Chapter_3.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
---
Title: Chapter 3 Exericses - FPP2
output: rmarkdown::github_document
editor_options:
chunk_output_type: console
---
```{r, echo = FALSE, warning = FALSE, message = FALSE}
knitr::opts_chunk$set(collapse = TRUE, fig.width = 6, fig.height = 4 , fig.path = "Figures/Ch3/Ch3-")
library(forecast)
library(fpp2)
```
## Forecasting: Principles and Practice - Chapter 3
### Exercise 1
For the following series, find an appropriate Box-Cox transformation in order to stabilise the variance.
* `usnetelec`
* `usgdp`
* `mcopper`
* `enplanements`
```{r, Exercise_1, out.width ='50%', fig.show='hold'}
lambda <- BoxCox.lambda(usnetelec)
cbind(raw = usnetelec, transform = BoxCox(usnetelec, lambda)) %>%
autoplot(facets = TRUE) +
ggtitle("Annual US Net Electricity Generation")
lambda <- BoxCox.lambda(usgdp)
cbind(raw = usgdp, transform = BoxCox(usgdp, lambda)) %>%
autoplot(facets = TRUE) +
ggtitle("Quarterly US GDP")
lambda <- BoxCox.lambda(mcopper)
cbind(raw = mcopper, transform = BoxCox(mcopper, lambda)) %>%
autoplot(facets = TRUE) +
ggtitle("Monthly Copper Prices")
lambda <- BoxCox.lambda(enplanements)
cbind(raw = enplanements, transform = BoxCox(enplanements, lambda)) %>%
autoplot(facets = TRUE) +
ggtitle("Monthly US domestic enplanements")
```
### Exercise 2
Why is a Box-Cox transformation unhelpful for the cangas data?
* A Box-Cox transformation is not useful for `cangas` because the variation in the seasonality does not change much in the raw data
```{r, Exercise_2}
lambda <- BoxCox.lambda(cangas)
cbind(raw = cangas, transform = BoxCox(cangas, lambda)) %>%
autoplot(facets = TRUE) +
ggtitle("Monthly Canadian Gas Production")
```
### Exercise 3
What Box-Cox transformation would you select for your retail data (from Exercise 3 in Section 2.10)?
* A lambda of .1276 transforms the seasonality nicely.
```{r, Exercise_3}
retaildata <- readxl::read_excel("Data/retail.xlsx", skip = 1)
myts <- ts(retaildata[,"A3349873A"], frequency = 12, start = c(1982, 4))
lambda <- BoxCox.lambda(myts)
cbind(raw = myts, transform = BoxCox(myts, lambda)) %>%
autoplot(facets = TRUE)
```
### Exercise 4
For each of the following series, make a graph of the data. If transforming seems appropriate, do so and describe the effect. `dole`, `usdeaths`, `bricksq`.
* `dole`: Box-Cox transformation with lambda = .33
* `usdeaths`: no transformation applied (transformation appears meaningless)
* `bricksq`: no transformation applied (transformation appears meaningless)
```{r, Exercise_4, out.width='50%', fig.show='hold'}
autoplot(dole)
lambda <- BoxCox.lambda(dole)
cbind(raw = dole, transform = BoxCox(dole, lambda)) %>%
autoplot(facets = TRUE)
autoplot(usdeaths)
autoplot(bricksq)
```
### Exercise 5
Calculate the residuals from a seasonal naïve forecast applied to the quarterly Australian beer production data from 1992. The following code will help.
* The residuals seem to have a right skew. Autocorrelation is also present in the residuals as seen in the ACF and supported by the Ljung-Box Test's p-value of 8.3e-05, which rejects the null hypothesis of no autocorrelation.
```{r, Exercise_5}
beer <- window(ausbeer, start=1992)
fc <- snaive(beer)
checkresiduals(fc)
```
### Exercise 6
Repeat the exercise for the `WWWusage` and `bricksq` data. Use whichever of naive() or snaive() is more appropriate in each case.
For `WWWusage` both the `naive` and `snaive` methods yield non-normal, autocorrelated errors. Both the ACF and Ljung-Box test reflect autocorrelation in the resiudals of both methods. Given the lack of a seasonal pattern in the series, the `naive` method should be choosen versus the `snaive` method.
```{r, Exercise_6a, out.width = '50%', fig.show = 'hold'}
autoplot(naive(WWWusage))
fc <- naive(WWWusage)
checkresiduals(fc)
autoplot(snaive(WWWusage))
fc2 <- snaive(WWWusage)
checkresiduals(fc2)
```
Similarly, for `bricksq` both the `naive` and `snaive` forecast methods result in residuals the are autocorrelated and non-normally distributed. The Ljung-Box test rejects non-autocorrelated residuals for both methods.
```{r, Exercise_6b, out.width = '50%', fig.show = 'hold'}
autoplot(naive(bricksq)) +
ggtitle("Australian Quarterly Clay Brick Production")
fc <- naive(bricksq)
checkresiduals(fc)
autoplot(snaive(bricksq)) +
ggtitle("Australian Quarterly Clay Brick Production")
fc2 <- snaive(bricksq)
checkresiduals(fc2)
```
### Exercise 7
Are the following statements true or false? Explain your answer.
1. Good forecast methods should have normally distributed residuals.
* TRUE: good forecast methods should have normally distributed residuals, but this is not strictly required. Much more importantly, good forecasts should have uncorrelated residuals with mean 0.
2. A model with small residuals will give good forecasts.
* FALSE: Residuals relate to fitted values, not forecast performance, and it may be the case that a particular model fits the insample data too well, resulting in "small" residuals. Nevertheless, out-of-sample performance from over-fit models may be poor. Good forecasts should produce mean-zero and uncorrelated errors.
3. The best measure of forecast accuracy is MAPE.
* FALSE: While the MAPE is a popular measure of forecast error, it has some disadvantages. Mainly, the MAPE struggles with when actuals are very small or even 0.
4. If your model doesn’t forecast well, you should make it more complicated.
* FALSE: more complicated methods do not necessarily improve forecasts. There is also a cost to more complex models: they are hard to interpret. Interpretibility may be an important factor when forming forecasts.
5. Always choose the model with the best forecast accuracy as measured on the test set.
* While out of sample performance is an important factor in choosing a model, it is not the *only* factor. Good models should also produce mean-zero and uncorrelated and homoskedastic errors.
### Exercise 8
For your retail time series (from Exercise 3 in Section 2.10):
* Split the data into two parts using:
```{r}
retaildata <- readxl::read_excel("Data/retail.xlsx", skip = 1)
myts <- ts(retaildata[,"A3349873A"], frequency = 12, start = c(1982, 4))
myts.train <- window(myts, end = c(2010,12))
myts.test <- window(myts, start = 2011)
```
* Check that your data have been split appropriately by producing the following plot.
```{r}
autoplot(myts) +
autolayer(myts.train, series = "Training") +
autolayer(myts.test, series = "Test")
```
* Calculate forecasts using snaive applied to myts.train.
```{r}
fc <- snaive(myts.train)
```
* Compare the accuracy of your forecasts against the actual values stored in myts.test.
```{r}
accuracy(fc,myts.test)
```
* Check the residuals.
```{r}
checkresiduals(fc)
```
Do the residuals appear to be uncorrelated and normally distributed?
* The residuals are highly autocorelated as seen in the ACF and in the Ljung-Box test. The residuals seem to follow a normal distribution, but also have slightly heavier tails and a higher peak around the mean, suggesting a t-distribution.
How sensitive are the accuracy measures to the training/test split?
* The accuracy measures are very sensitive to the training/test split. In sample performance is significantly better than out of sample.
### Exercise 9
`visnights` contains quarterly visitor nights (in millions) from 1998 to 2016 for twenty regions of Australia.
* Use `window()` to create three training sets for `visnights[,"QLDMetro"]`, omitting the last 1, 2 and 3 years; call these train1, train2, and train3, respectively. For example `train1 <- window(visnights[, "QLDMetro"], end = c(2015, 4))`.
```{r, Exercise_9a}
train1 <- window(visnights[, "QLDMetro"], start = 1998, end = c(2015,4))
train2 <- window(visnights[, "QLDMetro"], start = 1998, end = c(2014,4))
train3 <- window(visnights[, "QLDMetro"], start = 1998, end = c(2013,4))
```
* Compute one year of forecasts for each training set using the `snaive()` method. Call these `fc1`, `fc2` and `fc3`, respectively.
```{r, Exercise_9b}
fc1 <- snaive(train1, h = 4)
fc2 <- snaive(train2, h = 4)
fc3 <- snaive(train3, h = 4)
```
* Use `accuracy()` to compare the MAPE over the three test sets. Comment on these.
```{r, Exercise_9c}
accuracy(fc1, visnights[, "QLDMetro"] )
accuracy(fc2, visnights[, "QLDMetro"])
accuracy(fc3, visnights[, "QLDMetro"])
```
### Exercise 10
Use the Dow Jones index (data set dowjones) to do the following:
* Produce a time plot of the series.
```{r, Exercise_10a}
autoplot(dowjones)
```
* Produce forecasts using the drift method and plot them.
* Show that the forecasts are identical to extending the line drawn between the first and last observations.
```{r, Exercise_10b, out.width='50%', fig.show='hold'}
fc <- rwf(dowjones, drift = TRUE, h = 10)
autoplot(fc)
first <- dowjones[1]
last<- dowjones[length(dowjones)]
slope <- (last - first) / (length(dowjones) - 1)
autoplot(dowjones) +
geom_abline(slope = slope, intercept = first-slope, colour = "red", alpha = 0.8) +
autolayer(rwf(dowjones, drift = TRUE), PI = FALSE)
```
* Try using some of the other benchmark functions to forecast the same data set. Which do you think is best? Why?
* The naive method seems to produce the best forecasts. The mean forecasts is simply too far off from the recent actuals to be reasonable. The drift method seems to aggresive.
```{r, Exercise_10c}
autoplot(dowjones) +
autolayer(meanf(dowjones, h = 10),
series = "Mean", PI = FALSE) +
autolayer(rwf(dowjones, h = 10),
series = "Naïve", PI = FALSE) +
autolayer(rwf(dowjones, drift = TRUE, h = 10),
series = "Drift", PI = FALSE) +
ggtitle("Dow-Jones index, 28 Aug - 18 Dec 1972") +
xlab("Day") + ylab("Closing Price (US$)") +
guides(colour=guide_legend(title="Forecast"))
```
### Exercise 11
Consider the daily closing IBM stock prices (data set `ibmclose`).
* Produce some plots of the data in order to become familiar with it.
```{r, Exercise_11a, out.width='50%', fig.show='hold'}
autoplot(ibmclose)
autoplot(diff(ibmclose))
```
* Split the data into a training set of 300 observations and a test set of 69 observations.
```{r, Exercise_11b}
train <- window(ibmclose, start = 1, end = 300)
test <- window(ibmclose, start = 301)
```
* Try using various benchmark methods to forecast the training set and compare the results on the test set. Which method did best?
* Both the `naive` and `rwf` methods lend good out of sample forecasts. However, `rwf` yields lower RMSE, MAE, and MAPE statistics, reflecting its superior out of sample performance. A look at the residuals mights also help choose the best model.
```{r, Exercise_11c}
fc_naive <- naive(train, h = 69)
fc_rwf <- rwf(train, drift = TRUE, h = 69)
fc_mean <- meanf(train, h = 69)
autoplot(ibmclose) +
autolayer(fc_naive, series = "naive", PI = FALSE) +
autolayer(fc_mean, series = "mean", PI = FALSE) +
autolayer(fc_rwf, series = "drift", PI = FALSE)
```
```{r}
accuracy(fc_naive, test)
accuracy(fc_mean, test)
accuracy(fc_rwf, test)
```
* Check the residuals of your preferred method. Do they resemble white noise?
* None of the methods yield residuals resembiling white noise. For each mehtod, there is statistically significant autocorrelation in the resiudals. Furthermore, none of the residual distributins seem to fulfill normality (which is not required for good forecasts). However, the `naive` method's residuals come closest to the normal distribution.
```{r, Exercise_11d, out.width = '33.3%', fig.show = 'hold'}
checkresiduals(fc_naive)
checkresiduals(fc_mean)
checkresiduals(fc_rwf)
```
### Exercise 12
Consider the sales of new one-family houses in the USA, Jan 1973 – Nov 1995 (data set hsales).
* Produce some plots of the data in order to become familiar with it.
```{r, Exercise_12a, out.width = '33.3%', fig.show = 'hold'}
autoplot(hsales) +
ggtitle("Monthly sales of new one-family\nhouses sold in the USA since 1973")
ggseasonplot(hsales)
ggsubseriesplot(hsales)
```
* Split the hsales data set into a training set and a test set, where the test set is the last two years of data.
```{r, Exercise_12b}
train <- window(hsales, start = 1973, end = c(1993, 11))
test <- window(hsales, start = c(1993, 12))
```
* Try using various benchmark methods to forecast the training set and compare the results on the test set. Which method did best?
* the `snaive` methods produces the best out-of-sample forecasts according to the RMSE, MAE and MAPE.
```{r, Exericse_12c}
fc_mean <- meanf(train, h = 24)
fc_naive <- naive(train, h = 24)
fc_snaive <- snaive(train, h = 24)
fc_rwf <- rwf(train, drift = TRUE, h = 24)
autoplot(hsales) +
autolayer(fc_mean, series = "mean", PI = FALSE) +
autolayer(fc_naive, series = "naive", PI = FALSE) +
autolayer(fc_snaive, series = "snaive", PI = FALSE) +
autolayer(fc_rwf, series = "drift", PI = FALSE)
accuracy(fc_mean, test)
accuracy(fc_naive, test)
accuracy(fc_snaive, test)
accuracy(fc_rwf, test)
```
* Check the residuals of your preferred method. Do they resemble white noise?
* None of the methods provide white noise residuals. Each method's residuals have some degree of statistically significant autocorrelation, suggesting that additional predictors can capture this information to provide better forcasts. Only the residuals of the Seasonal naive method seem to follow a normal distribution.
```{r, Exercise_12d, out.width = '50%', fig.show = 'hold'}
checkresiduals(fc_mean)
checkresiduals(fc_naive)
checkresiduals(fc_snaive)
checkresiduals(fc_rwf)
```