5.11.1 - Produce forecasts for the following series using whichever of NAIVE(y), SNAIVE(y) or RW(y ~ drift()) is more appropriate in each case:

Australian Population (global_economy)

library(tidyverse) 
## Warning: package 'ggplot2' was built under R version 4.3.2
## Warning: package 'tidyr' was built under R version 4.3.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(fpp3)
## Warning: package 'fpp3' was built under R version 4.3.3
## Registered S3 method overwritten by 'tsibble':
##   method               from 
##   as_tibble.grouped_df dplyr
## ── Attaching packages ──────────────────────────────────────────── fpp3 1.0.1 ──
## ✔ tsibble     1.1.5     ✔ feasts      0.4.1
## ✔ tsibbledata 0.4.1     ✔ fable       0.4.1
## Warning: package 'tsibble' was built under R version 4.3.3
## Warning: package 'feasts' was built under R version 4.3.3
## Warning: package 'fabletools' was built under R version 4.3.3
## Warning: package 'fable' was built under R version 4.3.3
## ── 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()
library(plotly)
## 
## Attaching package: 'plotly'
## 
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following object is masked from 'package:graphics':
## 
##     layout
ausie_pop <- global_economy |>
  filter(Country == 'Australia') |>
  select(Population)

ausie_pop |>
  model(NAIVE(Population), Drift = RW(Population ~ drift())) |>
  forecast(h=15) |>
  autoplot(ausie_pop, level= NULL)

Bricks (aus_production)

bricks <- aus_production %>% 
  select(Quarter,Bricks) %>% 
  filter(!is.na(Bricks))

bricks %>% 
  model(NAIVE(Bricks)) %>% 
  forecast(h=10) %>% 
  autoplot(bricks)

NSW Lambs (aus_livestock)

nsw_lambs <- aus_livestock |>
  filter(Animal=='Lambs') |>
  select(Count, State)

nsw_lambs %>% 
  model(SNAIVE(Count), NAIVE(Count), Drift = RW(Count ~ drift())) |>
  forecast(h=15) |> 
  autoplot(nsw_lambs)

nsw_lambs <- aus_livestock |>
  filter(Animal=='Lambs', State == 'South Australia') |>
  select(Count, State)

nsw_lambs %>% 
  model(SNAIVE(Count)) |>
  forecast(h=15) |> 
  autoplot(nsw_lambs, level= NULL)

household wealth

aus_hh_wealth <- hh_budget |> 
     select(Country, Year, Wealth)

fit_household <- aus_hh_wealth |>
     model(`Naïve` = NAIVE(Wealth),Drift = RW(Wealth ~ drift()))

household_forcast <- fit_household |> 
     forecast(h = 10)

household_forcast |> 
     autoplot(aus_hh_wealth, level = NULL) + 
     guides(color = guide_legend(title = "Forecast"))

Australian takeaway food turnover (aus_retail).

aus_tak_food_to <- aus_retail|>
  filter(Industry=='Takeaway food services') |>
  select(Turnover)

aus_take_mod <- aus_tak_food_to |>
  model(SNAIVE(Turnover)) |> 
  forecast(h=10)
  autoplot(aus_tak_food_to) + labs(title = "Australian Takeaway Food Turnover") +
  facet_wrap(~State, scales = "free")
## Plot variable not specified, automatically selected `.vars = Turnover`

5.11.2 - Use the Facebook stock price (data set gafa_stock) to do the following:

fb_stock <- gafa_stock |>
  filter(Symbol == "FB") |>
  mutate(day = row_number()) |>
  update_tsibble(index = day, regular = TRUE)

fb_stock |>
  autoplot(Close) + labs(title= "Facebook stock price ")

fb_stock |>
  model(RW(Close ~ drift())) |>
  forecast(h = 60) |>
  autoplot(fb_stock) + labs(title = "Facebook stock price Drift method")

fb_stock |>
  model(RW(Close ~ drift())) |>
  forecast(h = 60) |>
  autoplot(fb_stock) +labs(title = "Facebook stock identical forcast") +
  geom_segment(aes(x = 1, y = 54.83, xend = 1258, yend = 134.45),
               color = "red", linetype = "dashed")
## Warning in geom_segment(aes(x = 1, y = 54.83, xend = 1258, yend = 134.45), : All aesthetics have length 1, but the data has 1258 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
##   a single row.

fb_stock %>%
  model(Mean = MEAN(Close),
        `Naïve` = NAIVE(Close),
        Drift = NAIVE(Close ~ drift())) %>%
  forecast(h = 60) %>%
  autoplot(fb_stock, level = NULL) +
  labs(title = "Facebook stock with multiple benchmarks")

5.11.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 interest
aus_beer_prod <- aus_production |>
     filter(year(Quarter) >= 1992)

aus_beer_prod |> autoplot(Beer)

decomp <- aus_beer_prod |> model(stl = STL(Beer))

components(decomp) |> autoplot()

# Define and estimate a model
fit <- aus_beer_prod |> model(SNAIVE(Beer))

# Look at the residuals
fit |> 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()`).

# Look a some forecasts
fit |> forecast() |> autoplot(aus_beer_prod)

The ACF plot shows a strong autocorrelation at lag 4, suggesting a repeating pattern in the data.

5.11.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.

# Australian exports
aus_exprt <- global_economy |> 
     select(Country, Year, Exports) |> 
     filter(Country == 'Australia')

aus_exprt |> 
     autoplot() + labs(title = "Australian Exports")
## Plot variable not specified, automatically selected `.vars = Exports`

fit_aus_exprt <- aus_exprt |> 
     model(NAIVE(Exports))

fit_aus_exprt |>
     forecast() |> 
     autoplot(aus_exprt)

# Australian bricks production
bricks |>
     autoplot() + labs(title = "Australian Brick Production")
## Plot variable not specified, automatically selected `.vars = Bricks`

fit_brick <- bricks |> 
     model(SNAIVE(Bricks))

fit_brick |> 
     forecast() |> 
     autoplot(bricks)

5.11.7 – For your retail time series (from Exercise 7 in Section 2.10):

# Create a training dataset consiseting of observations before 2011 using

set.seed(9171973)
myseries <- aus_retail |>
  filter(`Series ID` == sample(aus_retail$`Series ID`,1))
         
myseries_train <- myseries |>
  filter(year(Month) < 2011)

# Check that your data have been split appropriately by producing the following plot.

autoplot(myseries, Turnover) +
  autolayer(myseries_train, Turnover, colour = "blue")

aus_retail
## # A tsibble: 64,532 x 5 [1M]
## # Key:       State, Industry [152]
##    State                        Industry           `Series ID`    Month Turnover
##    <chr>                        <chr>              <chr>          <mth>    <dbl>
##  1 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Apr      4.4
##  2 Australian Capital Territory Cafes, restaurant… A3349849A   1982 May      3.4
##  3 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Jun      3.6
##  4 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Jul      4  
##  5 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Aug      3.6
##  6 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Sep      4.2
##  7 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Oct      4.8
##  8 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Nov      5.4
##  9 Australian Capital Territory Cafes, restaurant… A3349849A   1982 Dec      6.9
## 10 Australian Capital Territory Cafes, restaurant… A3349849A   1983 Jan      3.8
## # ℹ 64,522 more rows
# Fit a seasonal naïve model using SNAIVE() applied to your training data (myseries_train).

fit <- myseries_train |>
  model(SNAIVE(Turnover))

# Check the residuals.

fit |> gg_tsresiduals()
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_line()`).
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 12 rows containing non-finite outside the scale range
## (`stat_bin()`).

# Produce forecasts for the test data

fc <- fit |>
  forecast(new_data = anti_join(myseries, myseries_train))
## Joining with `by = join_by(State, Industry, `Series ID`, Month, Turnover)`
fc |> autoplot(myseries, level = NULL)

## Compare the accuracy of your forecasts against the actual values.

fit |> accuracy()
## # A tibble: 1 × 12
##   State    Industry .model .type    ME  RMSE   MAE   MPE  MAPE  MASE RMSSE  ACF1
##   <chr>    <chr>    <chr>  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Austral… Other r… SNAIV… Trai… 0.213 0.906 0.705  3.66  10.6     1     1 0.699
fc |> 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… Aust… Other r… Test   5.53  7.18  5.54  34.3  34.4  7.86  7.92 0.925