Introduction

In this report, we explore various forecasting techniques applied to Australian economic and financial datasets. By implementing different time series models, we analyze trends, seasonality, and forecast future values. Our objective is to evaluate the effectiveness of models such as NAIVE, SNAIVE, and RW with drift to provide insights into population growth, industry production, and retail behavior.

Exercise 1: Forecasting with NAIVE(), SNAIVE(), and RW()

Australian Population (NAIVE)

#We begin by analyzing the Australian population trend using the NAIVE model. Since population growth tends to follow a stable trend, this method serves as a simple yet effective benchmark.

aus_pop <- global_economy %>% filter(Country == "Australia")
aus_pop %>% autoplot(Population)

fc_pop <- aus_pop %>% model(NAIVE(Population)) %>% forecast()
fc_pop %>% autoplot(aus_pop)

Bricks Production (SNAIVE)

The brick production industry exhibits strong seasonal trends, making SNAIVE a suitable forecasting method. This model considers seasonality patterns when making predictions.

aus_production %>% autoplot(Bricks)
## Warning: Removed 20 rows containing missing values or values outside the scale range
## (`geom_line()`).

fc_bricks <- aus_production %>% model(SNAIVE(Bricks)) %>% forecast()
fc_bricks %>% autoplot(aus_production)
## Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
## -Inf
## Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
## -Inf
## Warning: Removed 8 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()`).

NSW Lambs (SNAIVE)

Lamb production in NSW follows annual seasonal cycles. By applying a seasonal naïve model, we assume that future production follows past seasonal patterns.

aus_livestock %>% filter(State == "Victoria", Animal == "Lambs") %>% autoplot(Count)

fc_lambs <- aus_livestock %>% filter(State == "Victoria", Animal == "Lambs") %>% model(SNAIVE(Count)) %>% forecast()
fc_lambs %>% autoplot(aus_livestock)

Household Wealth (NAIVE)

Household wealth tends to show a long-term upward trend with some fluctuations. A naïve model provides a simple benchmark by assuming future values remain constant based on recent observations.

hh_budget %>% autoplot(Wealth)

fc_wealth <- hh_budget %>% model(NAIVE(Wealth)) %>% forecast()
fc_wealth %>% autoplot(hh_budget)

Australian Takeaway Food Turnover (SNAIVE)

Takeaway food services exhibit seasonal demand, influenced by holidays and economic conditions. We apply the seasonal naïve method to capture repetitive patterns in the data.

takeaway_data <- aus_retail %>% filter(Industry == "Takeaway food services")

if (nrow(takeaway_data) > 0) {
  fc_takeaway <- takeaway_data %>% model(SNAIVE(Turnover)) %>% forecast()
  fc_takeaway %>% autoplot()
} else {
  print("No data available for Takeaway Food industry.")
}

Exercise 2: Facebook Stock Price Analysis

Facebook Stock Price (RW with drift)

Stock prices are highly volatile, and the random walk with drift model assumes a steady increase over time. This method allows us to predict future stock prices based on past trends.

# Convert daily data to monthly by taking the last closing price of each month
fb_stock <- gafa_stock %>%
  filter(Symbol == "FB") %>%  # Select Facebook stock
  mutate(YearMonth = yearmonth(Date)) %>%  # Convert Date to yearmonth format
  index_by(YearMonth) %>%  # Group by month
  summarize(Close = last(Close)) %>%  # Take last closing price of each month
  as_tsibble(index = YearMonth)  # Convert to tsibble

fc_fb <- fb_stock %>%
  model(RW(Close ~ drift())) %>%
  forecast()

fc_fb %>% autoplot(fb_stock)

# Plot the original series and add a straight line from first to last point
fb_stock %>%
  autoplot(Close) +
  geom_line(data = fb_stock %>% filter(row_number() %in% c(1, n())),
            aes(x = YearMonth, y = Close), color = "red", linetype = "dashed") +
  labs(title = "Facebook Stock Price with Straight Line (First to Last Point)")

Exercise 3: Australian Beer Production (SNAIVE Model)

Australian beer production follows a distinct seasonal pattern, making SNAIVE the ideal choice for forecasting.

recent_production <- aus_production %>% filter(year(Quarter) >= 1992)
fit_beer <- recent_production %>% model(SNAIVE(Beer))
fit_beer %>% 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()`).

fc_beer <- fit_beer %>% forecast()
fc_beer %>% autoplot(recent_production)

Exercise 4: Forecasting Australian Exports and Bricks

Australian Exports (NAIVE)

Exports fluctuate based on global demand and economic conditions. We apply the naïve model to track short-term changes.

aus_exports <- global_economy %>% filter(Country == "Australia")
fc_exports <- aus_exports %>% model(NAIVE(Exports)) %>% forecast()
fc_exports %>% autoplot(aus_exports)

# Bricks Production (NAIVE)
fc_bricks_naive <- aus_production %>%
  model(NAIVE(Bricks)) %>%
  forecast()

fc_bricks_naive %>%
  autoplot(aus_production) +
  labs(title = "Forecast: Australian Bricks Production (NAIVE)")
## Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
## -Inf
## Warning in max(ids, na.rm = TRUE): no non-missing arguments to max; returning
## -Inf
## Warning: Removed 8 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()`).

Exercise 7: Retail Time Series Forecasting

# Selecting a random retail time series to analyze seasonal trends
set.seed(05201986)
myseries <- aus_retail %>% filter(`Series ID` == sample(aus_retail$`Series ID`, 1))

# Explore the chosen series
autoplot(myseries, Turnover)

gg_season(myseries, Turnover)

gg_subseries(myseries, Turnover)

gg_lag(myseries, Turnover)

ACF(myseries, Turnover) %>% autoplot()

# Train the model on data before 2011
myseries_train <- myseries %>% filter(year(Month) < 2011)

# Remove zero, missing, and infinite values to ensure accurate forecasting
myseries_train <- myseries_train %>% filter(Turnover > 0, !is.na(Turnover), is.finite(Turnover))

# Fit seasonal naïve model
fit_retail <- myseries_train %>% model(SNAIVE(Turnover))

# Check residuals
fit_retail %>% 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()`).

# Forecast for test data
fc_retail <- fit_retail %>% forecast()

# Remove any NA or infinite values before plotting
fc_retail_clean <- fc_retail %>% drop_na() %>% filter(if_all(where(is.numeric), ~ !is.na(.) & is.finite(.)))

# Ensure forecast data is valid before plotting
if (nrow(fc_retail_clean) > 0) {
  fc_retail_clean %>% autoplot(.mean) +
    labs(title = "Retail Turnover Forecast", y = "Turnover", x = "Month")
} else {
  print("Warning: Forecast data contains only missing or non-finite values. No valid data to plot.")
}

## Conclusion

Through this analysis, we applied different forecasting methods to real-world economic and industry data, identifying seasonal trends and evaluating residual errors. We observed that seasonal naïve models perform well for time series with strong periodic patterns, while naïve and random walk models are better suited for general trend forecasting. The insights gained from this exercise illustrate the importance of selecting the right forecasting method based on data behavior and industry characteristics.