Produce forecasts for the following series using whichever of NAIVE(y), SNAIVE(y) or RW(y ~ drift()) is more appropriate in each case:
a) Produce the forecast for the Australian Population (global_economy)
head(global_economy)
# A tsibble: 6 x 9 [1Y]
# Key: Country [1]
Country Code Year GDP Growth CPI Imports Exports Population
<fct> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Afghanistan AFG 1960 537777811. NA NA 7.02 4.13 8996351
2 Afghanistan AFG 1961 548888896. NA NA 8.10 4.45 9166764
3 Afghanistan AFG 1962 546666678. NA NA 9.35 4.88 9345868
4 Afghanistan AFG 1963 751111191. NA NA 16.9 9.17 9533954
5 Afghanistan AFG 1964 800000044. NA NA 18.1 8.89 9731361
6 Afghanistan AFG 1965 1006666638. NA NA 21.4 11.3 9938414
Aus_population|>model(Naive =NAIVE(Population),Drift =RW(Population~drift())) |>forecast(h =20) |># we are forecasting 20 observations autoplot(Aus_population)
Interpretation:
We did not test the seasonal Naive model because the dataset does not exhibit any seasonality. The drift benchmark is the most suitable model because it forecasts an extended line which explicitly shows a clear overall upward trend over time connecting the first observation to the last observation and it is more realistic to the Australian population plot.
b)Produce the forecast for the Bricks (aus_production)
head(aus_production) # we visualize the top rows of the data set.
Bricks <- aus_production |>filter(!is.na(Bricks)) # we are removing the missing dataBricks |>model(Seasonal_naive =SNAIVE(Bricks),Naive =NAIVE(Bricks),Drift =RW(Bricks ~drift())) |>forecast(h ="5 years") |># we forecasts in 5 years aheadautoplot(Bricks)
Interpretation:
Quarterly Bricks production shows a strong seasonal patterns. The Seasonal Naive benchmark is the best model for this dataset because it is the only one that takes into account seasonality despite the other two models.
c) Produce the forecast for the NSW Lambs (aus_livestock)
head(aus_livestock) # We visualize the dataset
# A tsibble: 6 x 4 [1M]
# Key: Animal, State [1]
Month Animal State Count
<mth> <fct> <fct> <dbl>
1 1976 Jul Bulls, bullocks and steers Australian Capital Territory 2300
2 1976 Aug Bulls, bullocks and steers Australian Capital Territory 2100
3 1976 Sep Bulls, bullocks and steers Australian Capital Territory 2100
4 1976 Oct Bulls, bullocks and steers Australian Capital Territory 1900
5 1976 Nov Bulls, bullocks and steers Australian Capital Territory 2100
6 1976 Dec Bulls, bullocks and steers Australian Capital Territory 1800
NSW_Lambs <- aus_livestock |>filter(State=="New South Wales",Animal=="Lambs")fit_NSW_Lambs <- NSW_Lambs |>model(Seasonal_naive =SNAIVE(Count),Naive =NAIVE(Count),Drift =RW(Count ~drift())) |>forecast(h ="3 years") |># we forecasts in 5 years ahead since it a monthly interval datasetautoplot(NSW_Lambs, level=NULL) # I am removing the prediction interval by setting level to NULLfit_NSW_Lambs
Interpretation
The monthly lambs in New South Wales shows a clear visible seasonality. So the seasonal naive is the best benchmark for this monthly dataset.
d) Produce the forecast for the Household wealth (hh_budget)
head(hh_budget)
# A tsibble: 6 x 8 [1Y]
# Key: Country [1]
Country Year Debt DI Expenditure Savings Wealth Unemployment
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Australia 1995 95.7 3.72 3.40 5.24 315. 8.47
2 Australia 1996 99.5 3.98 2.97 6.47 315. 8.51
3 Australia 1997 108. 2.52 4.95 3.74 323. 8.36
4 Australia 1998 115. 4.02 5.73 1.29 339. 7.68
5 Australia 1999 121. 3.84 4.26 0.638 354. 6.87
6 Australia 2000 126. 3.77 3.18 1.99 350. 6.29
fit_hh_budget <- hh_budget |>model(Seasonal_naive =SNAIVE(Wealth),Naive =NAIVE(Wealth),Drift =RW(Wealth ~drift())) |>forecast(h =10) |># we forecasts 10 years ahead autoplot(hh_budget, level=NULL) # I am removing the prediction interval by setting level to NULL
Warning: 4 errors (1 unique) encountered for Seasonal_naive
[4] Non-seasonal model specification provided, use RW() or provide a different lag specification.
fit_hh_budget
Warning: Removed 40 rows containing missing values or values outside the scale range
(`geom_line()`).
Interpretation
The dataset plot does not show any seasonality therefore the seasonal naive is definitely not a good fit. The plot show an overall consistent upward trend which proves that the drift model with its extended upward line is the best model to fit this dataset.
e) Produce the forecast for the Australian takeaway food turnover (aus_retail)
head(aus_retail)
# A tsibble: 6 x 5 [1M]
# Key: State, Industry [1]
State Industry `Series ID` Month Turnover
<chr> <chr> <chr> <mth> <dbl>
1 Australian Capital Territory Cafes, restaurants… A3349849A 1982 Apr 4.4
2 Australian Capital Territory Cafes, restaurants… A3349849A 1982 May 3.4
3 Australian Capital Territory Cafes, restaurants… A3349849A 1982 Jun 3.6
4 Australian Capital Territory Cafes, restaurants… A3349849A 1982 Jul 4
5 Australian Capital Territory Cafes, restaurants… A3349849A 1982 Aug 3.6
6 Australian Capital Territory Cafes, restaurants… A3349849A 1982 Sep 4.2
tail(aus_retail)
# A tsibble: 6 x 5 [1M]
# Key: State, Industry [1]
State Industry `Series ID` Month Turnover
<chr> <chr> <chr> <mth> <dbl>
1 Western Australia Takeaway food services A3349435A 2018 Jul 179.
2 Western Australia Takeaway food services A3349435A 2018 Aug 178.
3 Western Australia Takeaway food services A3349435A 2018 Sep 180.
4 Western Australia Takeaway food services A3349435A 2018 Oct 183.
5 Western Australia Takeaway food services A3349435A 2018 Nov 184.
6 Western Australia Takeaway food services A3349435A 2018 Dec 195.
The Australian takeaway turnover foods shows a clear visible strong monthly seasonality. Therefore, the seasonal naive is the best benchmark for this series.
Exercise 5.2
Use the Facebook stock price (data set gafa_stock) to do the following:
a) Let’s visualize the gafa_stock dataset and produce a time plot of the series
head(gafa_stock|>filter(Symbol=="FB")) # first 6 rows of the Facebook stock price from the gafa_stock tsibble
# Let's produce the plot of the Facebook closing stock price from the gafa_stocks time seriesgafa_stock |>filter(Symbol=="FB")|>autoplot(Close)
b) Let’s produce forecasts using the drift method and plot them.
Since the stock only trade during the working day, we could anticipate the fact that there are some missing Facebook price in our dataset related the weekend and holidays.
In order to avoid any when computing our forecast, we need to re-index the time series by using just trading day as our new index which will help us avoinding the problem of any missing stock price days.
# Let's create our new datasetFB_stock_new <- gafa_stock |>filter(Symbol=="FB") |># pulling out just the Facebook datamutate(trading_day=row_number()) |># we create a new variable that represents the number of rows in the data set update_tsibble(index=trading_day,regular=TRUE) # we are re-indexing our tsibble with trading_day as our new index.head(FB_stock_new)
#Let's produce forecasts for facebook closing stock prices using the drift method and plot themFB_stock_new |>model(Drift =RW(Close ~drift())) |># we fit the drift modelforecast(h =60) |># we pick the number of days we want to forecasts aheadautoplot(FB_stock_new) +labs(title ="Facebook Closing Stock Price Forecasts Using the Drift Method",x ="Trading_Day",y ="Closing Price (USD)" )
Interpretation
We observe that the time plot of the Facebook closing stock prices historical data shows an overall upward trend throughout the vast majority of the observed period with a notable dip equivalent to an interesting decline towards the end of the series. The drift forecasts shows a slight upward line trajectory which appears to be consistent with extending the line drawn between the first and last observations.
c) Let’s use some of the other benchmark functions to forecast the same data set. Which do you think is best? Why?
For this time series data set, I am not going to fit the seasonal naive model because the facebook stock closing price does not exhibit seasonality.
# Let's fit the other benchmark forecasting methods and compare themFB_stock_new |>model(Mean =MEAN(Close),Naive =NAIVE(Close),Drift =RW(Close ~drift()) ) |>forecast(h =60) |># we are forecasting 60 trading days autoplot(FB_stock_new) +labs(title ="Benchmark Forecasts for Facebook Closing Stock Prices",x ="Trading_Day",y ="Closing Price (USD)" )
Interpretation
When comparing the three benchmark function to forecast the Facebook Closing stocks prices, we observe that the mean is not a good model for forecasting stocks prices because it forecasts an horizontal line which does not reflect the recent behavior of the stock price and is not close to the last observed historical movement price.
The naive and drift benchmarks are more reasonable because they both start off where the latest recent observed values and the historical movement of the series is. However, the best benchmark function of our data set will be the Drift because it forecasts an extended line which explicitly shows a clear overall upward trend over time connecting the first observation to the last observation and it is more realistic to the facebook stocks closing plot.
Exercise 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 interest
recent_production <- aus_production |> filter(year(Quarter) >= 1992) # Define and estimate a model fit <- recent_production |> model(SNAIVE(Beer)) # Look at the residuals fit |> gg_tsresiduals()
# A tsibble: 6 x 7 [1Q]
Quarter Beer Tobacco Bricks Cement Electricity Gas
<qtr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2009 Q1 415 NA NA 1963 58368 196
2 2009 Q2 398 NA NA 2160 57471 238
3 2009 Q3 419 NA NA 2325 58394 252
4 2009 Q4 488 NA NA 2273 57336 210
5 2010 Q1 414 NA NA 1904 58309 205
6 2010 Q2 374 NA NA 2401 58041 236
# extracting the australian production data from 1992 upwardNew_production <- aus_production |>filter(year(Quarter) >=1992)New_production
# Apply the seasonal naïve method to the quarterly Australian beer in the new production datasetfit_beer_1992 <- New_production |>model(Seaonal_naive=SNAIVE(Beer))# Let's look at the residualsfit_beer_1992 |>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()`).
Let’s plot the forecasts
# Look a some forecastsfit_beer_1992 |>forecast() |>autoplot(New_production,level=NULL)
Interpretation
The innovation residuals shows a big change in spread above or below zero and that suggest changing vairance. Looking at the autocorrelation function (acf) graph, we obverse for white noise that the majority of observations fall inside the blue dashed bounds expect from three observations at lag1, lag 3 and especially a significant spike at lag 4. That means the residuals are not pure white noise. The residual histogram is skewed to the left, which means residuals are not normally distributed. The forecast plot is repeating the seasonal pattern but it seems that the decline in beer production is not gradual. We can conclude that although the seasonal naive model capture the seasonality of the new beer production, it fails to do so downward, hence we believe that the forecasts are biased upward.
Exercise 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.
Case of the Australian exports
head(global_economy)
# A tsibble: 6 x 9 [1Y]
# Key: Country [1]
Country Code Year GDP Growth CPI Imports Exports Population
<fct> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Afghanistan AFG 1960 537777811. NA NA 7.02 4.13 8996351
2 Afghanistan AFG 1961 548888896. NA NA 8.10 4.45 9166764
3 Afghanistan AFG 1962 546666678. NA NA 9.35 4.88 9345868
4 Afghanistan AFG 1963 751111191. NA NA 16.9 9.17 9533954
5 Afghanistan AFG 1964 800000044. NA NA 18.1 8.89 9731361
6 Afghanistan AFG 1965 1006666638. NA NA 21.4 11.3 9938414
Aus_exports <- global_economy |>filter(Country =="Australia") # fit the naive modelfit_exports <- Aus_exports |>model(NAIVE(Exports))# Let's look at the residualsfit_exports |>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_exports |>forecast(h =10) |>autoplot(Aus_exports,level=NULL)
Interpretation
The historical plot shows a strong upward trend but without seasonability that’s why we used naive model.
The ACF shows a significant negative spike at lag 1 so the residuals are not white noise. The residual plot shows that values are hardly centered or distributed at zero. These conditions suggests that the naive do not full capture the trend.
The forecast plot shows a flat line which does not exhibit an upward trend.
we can conclude that the naive model is not the best fit for our data.
# Extracting data of interestBricks_prod <- aus_production |>filter(!is.na(Bricks)) # by selecting bricks , we also remove the missing data# plot the dataBricks_prod |>autoplot(Bricks)
# fit the seasonal naive modelfit_Bricks_prod <- Bricks_prod |>model(Seaonal_naive=SNAIVE(Bricks))# Let's look at the residualsfit_Bricks_prod |>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_Bricks_prod |>forecast(h ="3 years") |>autoplot(Bricks_prod,level=NULL)
Interpretation
The quarterly bricks production data plot shows a strong seasonality, therefore the seasonal naive should be appropriate.
The innovation residuals graph shows the bricks volatile which can affect the stability of the variance. Also, the ACF graph shows significant spikes out of the dashed area at seasonal lags w, so the residuals are not white noise. Moreover, the residual histogram is not normally distributed.
The forecast plot is repeating the historical seasonal pattern, but does not capture properly the overall trend downward in the bricks production. We can conclude that the seasonal naive model is biased.
Exercise 5.7
For your retail time series (from Exercise 7 in Section 2.10):
Let’s create a training dataset consisting of observations before 2011