── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ tsibble::interval() masks lubridate::interval()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
#Model selectionfit_population <- aus_population |>model(RW(Population ~drift()))#generate and forecast in 3 yearspopulation_fc <- fit_population |>forecast(h ="3 years")#plot the forecastpopulation_fc |>autoplot(aus_population)
Interpretation:
Australian population shows a clear upward trend and no seasonal pattern. Therefore, I selected the random walk with drift model.
#Bricks (aus_production)
# Data preparation (tidy) and Plot (visualization)aus_prod <- aus_production |>select(Bricks)bricks_fit <- aus_prod |>model(SNAIVE(Bricks))bricks_fc <- bricks_fit |>forecast(h =12)bricks_fc |>autoplot(aus_prod, level =NULL) +labs(y ="Bricks",title ="Forecast for Quarterly Bricks Production" )
Warning: Removed 12 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 20 rows containing missing values or values outside the scale range
(`geom_line()`).
Interpretation:
Since bricks is a quarterly data and a strong seasonality a SNAIVE is fit to use.
##NSW Lambs (aus_livestock)
aus_livestock |>distinct(State)
# A tibble: 8 × 1
State
<fct>
1 Australian Capital Territory
2 New South Wales
3 Northern Territory
4 Queensland
5 South Australia
6 Tasmania
7 Victoria
8 Western Australia
nsw_lambs <- aus_livestock |>filter(State =="New South Wales", Animal =="Lambs")nsw_lambs
# A tsibble: 558 x 4 [1M]
# Key: Animal, State [1]
Month Animal State Count
<mth> <fct> <fct> <dbl>
1 1972 Jul Lambs New South Wales 587600
2 1972 Aug Lambs New South Wales 553700
3 1972 Sep Lambs New South Wales 494900
4 1972 Oct Lambs New South Wales 533500
5 1972 Nov Lambs New South Wales 574300
6 1972 Dec Lambs New South Wales 517500
7 1973 Jan Lambs New South Wales 562600
8 1973 Feb Lambs New South Wales 426900
9 1973 Mar Lambs New South Wales 496300
10 1973 Apr Lambs New South Wales 496000
# ℹ 548 more rows
RW model is good fit for the forecast of this datasets because the models makes sense for a series dominated by a trend without a strong seasonal pattern.
Retail
aus_retail |>distinct(State)
# A tibble: 8 × 1
State
<chr>
1 Australian Capital Territory
2 New South Wales
3 Northern Territory
4 Queensland
5 South Australia
6 Tasmania
7 Victoria
8 Western Australia
aus_retail |>distinct(Industry)
# A tibble: 20 × 1
Industry
<chr>
1 Cafes, restaurants and catering services
2 Cafes, restaurants and takeaway food services
3 Clothing retailing
4 Clothing, footwear and personal accessory retailing
5 Department stores
6 Electrical and electronic goods retailing
7 Food retailing
8 Footwear and other personal accessory retailing
9 Furniture, floor coverings, houseware and textile goods retailing
10 Hardware, building and garden supplies retailing
11 Household goods retailing
12 Liquor retailing
13 Newspaper and book retailing
14 Other recreational goods retailing
15 Other retailing
16 Other retailing n.e.c.
17 Other specialised food retailing
18 Pharmaceutical, cosmetic and toiletry goods retailing
19 Supermarket and grocery stores
20 Takeaway food services
The Australian takeaway food turnover series shows a recurring seasonal pattern. Therefore, I selected the seasonal naïve method, which uses the corresponding observation from the previous year to forecast each month.
5.2 Use the Facebook stock price (data set gafa_stock) to do the following:
Looking at the forecasts, I think the drift method is more appropriate. The Facebook stock price shows an overall increasing trend over the observed period. The mean method does not account for this trend, while the naïve method assumes that future prices will remain at the last observed value. The drift method accounts for the overall upward movement by extending the average change between the first and last observations.
5.3. Apply a seasonal naïve method to the quarterly Australian beer production data from 1992. Check if the residuals look like white noise, and plot the forecasts. The following code will help.
# Extract data of interestrecent_production <- aus_production |>filter(year(Quarter) >=1992)# Define and estimate a modelfit <- recent_production |>model(SNAIVE(Beer))# Look at the residualsfit |>gg_tsresiduals()
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_point()`).
Warning: Removed 4 rows containing non-finite outside the scale range
(`stat_bin()`).
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_rug()`).
# Look a some forecastsfit |>forecast() |>autoplot(recent_production)
Interpretation:
The residuals do not appear to be completely white noise. The ACF plot shows a significant negative spike at lag 4 and a positive spike around lag 3 that exceeds the significance bounds. Since the data are quarterly, lag 4 represents one year, suggesting that some seasonal information remains in the residuals. Therefore, the seasonal naïve model captures the general seasonal pattern, but it does not capture all of the information in the series.
5.4 Repeat the previous exercise using the Australian Exports series from global_economy and the Bricks series from aus_production. Use whichever of NAIVE() or SNAIVE() is more appropriate in each case.
# Extract data of interestaustralian_export <- global_economy |>filter(Country =="Australia")# Define and estimate a modelfit <- australian_export |>model(NAIVE(Exports))# Look at the residualsfit |>gg_tsresiduals()
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_point()`).
Warning: Removed 1 row containing non-finite outside the scale range
(`stat_bin()`).
Warning: Removed 1 row containing missing values or values outside the scale range
(`geom_rug()`).
# Look a some forecastsfit |>forecast() |>autoplot(australian_export)
# Extract data of interestaustralian_bricks <- aus_production |>filter(year(Quarter) >=1970) |>filter(!is.na(Bricks))# Define and estimate a modelfit_brick <- australian_bricks |>model(SNAIVE(Bricks))# Look at the residualsfit_brick |>gg_tsresiduals()
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_line()`).
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_point()`).
Warning: Removed 4 rows containing non-finite outside the scale range
(`stat_bin()`).
Warning: Removed 4 rows containing missing values or values outside the scale range
(`geom_rug()`).
# Look a some forecastsfit_brick |>forecast() |>autoplot(australian_bricks)
Interpretation:
For the Australian Exports series, I used the naïve method because the data are annual and do not have a seasonal pattern. The naïve method forecasts future exports using the most recent observed value. For the Bricks series, I used the seasonal naïve method because the quarterly data show a recurring seasonal pattern. The seasonal naïve method forecasts each quarter using the value from the corresponding quarter of the previous year.
The residuals for both datasets do not appear to be completely white noise. For Australian Exports, the ACF plot shows a significant negative spike at lag 1, indicating that some autocorrelation remains in the residuals. For Bricks production, the ACF plot shows several significant positive and negative spikes that exceed the significance bounds. This indicates that there is still autocorrelation in the residuals. Therefore, although the seasonal naïve method captures the general seasonal pattern in Bricks production, it does not capture all of the information in the series.
5.7 For your retail time series (from Exercise 7 in Section 2.10):
# A tibble: 1 × 12
.model State Industry .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 SNAIVE(T… Nort… Clothin… Test 0.836 1.55 1.24 5.94 9.06 1.36 1.28 0.601
fc2 |>accuracy(myseries)
# A tibble: 1 × 12
.model State Industry .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 SNAIVE(T… Nort… Clothin… Test 0.836 1.55 1.24 5.94 9.06 1.36 1.28 0.601
fc3 |>accuracy(myseries)
# A tibble: 1 × 12
.model State Industry .type ME RMSE MAE MPE MAPE MASE RMSSE ACF1
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 SNAIVE(T… Nort… Clothin… Test 0.836 1.55 1.24 5.94 9.06 1.36 1.28 0.601
#range(myseries$Month)
Interpretation:
I tested the seasonal naïve model using different amounts of training data by starting the training period in 1990, 2000, and 2005, while keeping the end of the training period at 2010. The test accuracy measures were identical for all three training sets, with an RMSE of 1.552, MAE of 1.241, and MAPE of 9.064%. Therefore, the forecast accuracy of the seasonal naïve method is not sensitive to the amount of older training data used in this case. This occurs because the seasonal naïve method bases its forecasts on the most recent seasonal observations, which are the same for all three training sets.