library(fpp3)
library(RColorBrewer)
library(knitr)
library(pracma)
palette <- brewer.pal(n = 11, name = "BrBG")
#function taken from here: https://bookdown.org/yihui/rmarkdown-cookbook/font-color.html
colorize <- function(x, color){
if (knitr::is_latex_output()) {
sprintf("\\textcolor{%s}{%s}", color, x)
}
else if (knitr::is_html_output()){
sprintf("<span style='color: %s;'>%s</span>", color, x)
}
else x
}
Consider the the number of pigs slaughtered in Victoria, available in the aus_livestock dataset.
data(aus_livestock)
pigs <- aus_livestock |>
filter(Animal == "Pigs" & State == "Victoria") |>
mutate(Count_Thousands = Count / 1000)
fit <- pigs |>
model(SimExpSm = ETS(Count_Thousands ~ error("A") + trend("N") + season("N")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| Animal | State | .model | term | estimate |
|---|---|---|---|---|
| Pigs | Victoria | SimExpSm | alpha | 0.32 |
| Pigs | Victoria | SimExpSm | l[0] | 100.49 |
pigs_since_2010 <- pigs |>
filter(year(Month) >= 2010)
fit_augment <- augment(fit)
fit_augment_since_2010 <- fit_augment |>
filter(year(Month) >= 2010)
fit |>
forecast(h = 4) |>
autoplot(pigs_since_2010, level = 95, color = "#80CDC1") +
geom_line(aes(y = .fitted), color = "#DFC27D",
data = fit_augment_since_2010) +
labs(title = "Pigs Slaughtered", y = "Number in Thousands")
In the above chart, only data from 2010 onward are displayed so that the Fitted Values and the Forecasts from Simple Exponential Smoothing can be seen more clearly.
acc <- accuracy(fit)
RMSE <- round(as.numeric(acc$RMSE), 2)
kable(acc, format = "simple")
| Animal | State | .model | .type | ME | RMSE | MAE | MPE | MAPE | MASE | RMSSE | ACF1 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Pigs | Victoria | SimExpSm | Training | -0.0295501 | 9.336336 | 7.190129 | -1.056173 | 8.346368 | 0.7761893 | 0.7508488 | 0.0105559 |
\(s = 9.34\)
fc <- fit |>
forecast(h = 1)
y_hat <- round(as.numeric(fc$.mean), 2)
\(\hat{y} = 95.19\)
l <- y_hat - (1.96 * RMSE)
u <- y_hat + (1.96 * RMSE)
pi <- as.data.frame(t(c(l, u)))
colnames(pi) <- c("Lower", "Upper")
rownames(pi) <- "**Calculated Prediction Interval**"
kable(pi, format = "simple")
| Lower | Upper | |
|---|---|---|
| Calculated Prediction Interval | 76.8836 | 113.4964 |
The \(95\%\) calculated prediction interval aligns well with the interval produced by setting the level argument of the autoplot function to \(95\).
Data set global_economy contains the annual Exports from many countries. Select one country to analyse.
data(global_economy)
keep <- c("Country", "Year", "Exports")
canada <- global_economy |>
select(all_of(keep)) |>
filter(Country == "Canada")
canada |>
autoplot(Exports) +
labs(title = "Canadian Exports")
In Canada, there was a general upward trend for Exports (as percentage of GDP) from 1960 to 1990, after which the rate of the upward trend increased until 2000. Then there was a steep decline in Exports (as percentage of GDP) until 2009, after which the decline has leveled off. We could be seeing the previous general upward trend recommence or just a pause before further decline.
fit <- canada |>
filter(Year <= 2012) |>
model(SimExpSm = ETS(Exports ~ error("A") + trend("N") + season("N")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| Country | .model | term | estimate |
|---|---|---|---|
| Canada | SimExpSm | alpha | 1.00 |
| Canada | SimExpSm | l[0] | 16.97 |
fit_augment <- augment(fit)
fit |>
forecast(h = 10) |>
autoplot(canada, level = 95, color = "#80CDC1") +
geom_line(aes(y = .fitted), color = "#DFC27D",
data = fit_augment) +
labs(title = "Canadian Exports",
subtitle = "Simple Exponential Smoothing Forecasts",
y = "Percentage of GDP")
fc <- fit |>
forecast(h = 1)
y_hat1 <- round(as.numeric(fc$.mean), 2)
acc <- accuracy(fit)
RMSE1 <- round(as.numeric(acc$RMSE), 2)
kable(acc, format = "simple")
| Country | .model | .type | ME | RMSE | MAE | MPE | MAPE | MASE | RMSSE | ACF1 |
|---|---|---|---|---|---|---|---|---|---|---|
| Canada | SimExpSm | Training | 0.2499818 | 1.679944 | 1.266428 | 0.9283237 | 4.417591 | 0.9811533 | 0.9905539 | 0.3144439 |
\(RMSE = 1.68\)
fit <- canada |>
filter(Year <= 2012) |>
model(HoltLinTrend = ETS(Exports ~ error("A") + trend("A") + season("N")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| Country | .model | term | estimate |
|---|---|---|---|
| Canada | HoltLinTrend | alpha | 1.00 |
| Canada | HoltLinTrend | beta | 0.23 |
| Canada | HoltLinTrend | l[0] | 16.46 |
| Canada | HoltLinTrend | b[0] | 0.08 |
fit_augment <- augment(fit)
fit |>
forecast(h = 10) |>
autoplot(canada, level = 95, color = "#80CDC1") +
geom_line(aes(y = .fitted), color = "#DFC27D",
data = fit_augment) +
labs(title = "Canadian Exports",
subtitle = "Holt's Linear Trend Method Forecasts",
y = "Percentage of GDP")
fc <- fit |>
forecast(h = 1)
y_hat2 <- round(as.numeric(fc$.mean), 2)
acc <- accuracy(fit)
RMSE2 <- round(as.numeric(acc$RMSE), 2)
kable(acc, format = "simple")
| Country | .model | .type | ME | RMSE | MAE | MPE | MAPE | MASE | RMSSE | ACF1 |
|---|---|---|---|---|---|---|---|---|---|---|
| Canada | HoltLinTrend | Training | -0.0517386 | 1.678591 | 1.245532 | -0.0624154 | 4.43095 | 0.9649638 | 0.9897558 | 0.1679992 |
\(RMSE = 1.68\)
Both models use an alpha coefficient close to 1, so more weight is given to more recent observations. The RMSE is the same for both models, but they have different numbers of parameters, so neither is more accurate by that standard. The fitted values from the ETS(A,A,N) model, Holt’s Linear Trend Method, demonstrate higher peaks and lower valleys than the ETS(A,N,N) model, Simple Exponential Smoothing. Holt’s Linear Trend Method has a beta coefficient of 0.23, indicating somewhat frequent changes in trend.
The merits of using a model that puts more weight on more recent observations and allows for a linear trend in the forecasts vs. one that doesn’t is: the analyst can see how things might go assuming the recent conditions continue. If there were reason to believe recent conditions would not continue, Simple Exponential Smoothing might be preferable.
The ETS(A,A,N) model is probably overestimating a downward trend for the point forecasts, and the prediction interval it provides gets very wide. The ETS(A,N,N) model forecasts are closer to the test data, and its prediction interval still allows for (less extreme) uncertainty. The ETS(A,N,N) model seems best here.
l <- y_hat1 - (1.96 * RMSE1)
u <- y_hat1 + (1.96 * RMSE1)
pi <- as.data.frame(t(c(l, u)))
colnames(pi) <- c("Lower", "Upper")
rownames(pi) <- "**Calculated Prediction Interval: Simple Exponential Smoothing**"
kable(pi, format = "simple")
| Lower | Upper | |
|---|---|---|
| Calculated Prediction Interval: Simple Exponential Smoothing | 26.9172 | 33.5028 |
l <- y_hat2 - (1.96 * RMSE2)
u <- y_hat2 + (1.96 * RMSE2)
pi <- as.data.frame(t(c(l, u)))
colnames(pi) <- c("Lower", "Upper")
rownames(pi) <- "**Calculated Prediction Interval: Holt's Linear Trend Method**"
kable(pi, format = "simple")
| Lower | Upper | |
|---|---|---|
| Calculated Prediction Interval: Holt’s Linear Trend Method | 26.3872 | 32.9728 |
Again, the \(95\%\) calculated prediction intervals align well with the intervals produced by setting the level argument of the autoplot functions to \(95\).
Forecast the Chinese GDP from the global_economy data set using an ETS model. Experiment with the various options in the ETS() function to see how much the forecasts change with damped trend, or with a Box-Cox transformation. Try to develop an intuition of what each is doing to the forecasts.
[Hint: use a relatively large value of \(h\) when forecasting, so you can clearly see the differences between the various options when plotting the forecasts.]
china <- global_economy |>
select(all_of(keep)) |>
filter(Country == "China")
china |>
autoplot(Exports)
lam <- china |>
features(Exports, features = guerrero) |>
pull(lambda_guerrero)
fit <- china |>
filter(Year <= 2012) |>
model(HoltLinTrend = ETS(Exports ~ error("A") + trend("A") + season("N")),
DampedHolt = ETS(Exports ~ error("A") + trend("Ad") + season("N")),
HoltLinTrend_Log = ETS(log(Exports) ~
error("A") + trend("A") + season("N")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| Country | .model | term | estimate |
|---|---|---|---|
| China | HoltLinTrend | alpha | 1.00 |
| China | HoltLinTrend | beta | 0.00 |
| China | HoltLinTrend | l[0] | 4.07 |
| China | HoltLinTrend | b[0] | 0.40 |
| China | DampedHolt | alpha | 1.00 |
| China | DampedHolt | beta | 0.22 |
| China | DampedHolt | phi | 0.80 |
| China | DampedHolt | l[0] | 4.15 |
| China | DampedHolt | b[0] | -0.11 |
| China | HoltLinTrend_Log | alpha | 1.00 |
| China | HoltLinTrend_Log | beta | 0.00 |
| China | HoltLinTrend_Log | l[0] | 1.52 |
| China | HoltLinTrend_Log | b[0] | 0.03 |
fit |>
forecast(h = 25) |>
autoplot(china, level = NULL) +
labs(title = "Chinese Exports",
subtitle = "Forecasts",
y = "Percentage of GDP")
The Damped Holt’s Linear Trend Method is influenced more by the recent downward trend than Holt’s Linear Trend Method, and it continues it, but with the smallest leveling off phi coefficient allowed of 0.8. Forecasts from Holt’s Linear Trend Method are more influenced by the general upward trend from the data prior to the recent decline. So they continue an upward trend. But they are not as optimistic as the forecasts from log transforming the Exports variable, then using the same method. These forecasts assume the rate of the trend will increase exponentially.
Here, the forecasts from the Damped Holt’s Linear Trend Method appear most appropriate, as they fit the test data best.
Find an ETS model for the Gas data from aus_production and forecast the next few years. Why is multiplicative seasonality necessary here? Experiment with making the trend damped. Does it improve the forecasts?
data(aus_production)
keep <- c("Quarter", "Gas")
gas <- aus_production |>
select(all_of(keep))
fit <- gas |>
filter(year(Quarter) <= 2007) |>
model(HoltWintAdd = ETS(Gas ~ error("A") + trend("A") + season("A")),
HoltWintMult = ETS(Gas ~ error("M") + trend("A") + season("M")),
DampHoltWintMult = ETS(Gas ~ error("M") + trend("Ad") + season("M")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| .model | term | estimate |
|---|---|---|
| HoltWintAdd | alpha | 0.50 |
| HoltWintAdd | beta | 0.00 |
| HoltWintAdd | gamma | 0.39 |
| HoltWintAdd | l[0] | 12.17 |
| HoltWintAdd | b[0] | 1.16 |
| HoltWintAdd | s[0] | -9.02 |
| HoltWintAdd | s[-1] | 5.29 |
| HoltWintAdd | s[-2] | 8.28 |
| HoltWintAdd | s[-3] | -4.56 |
| HoltWintMult | alpha | 0.66 |
| HoltWintMult | beta | 0.15 |
| HoltWintMult | gamma | 0.09 |
| HoltWintMult | l[0] | 5.88 |
| HoltWintMult | b[0] | 0.03 |
| HoltWintMult | s[0] | 0.93 |
| HoltWintMult | s[-1] | 1.18 |
| HoltWintMult | s[-2] | 1.07 |
| HoltWintMult | s[-3] | 0.82 |
| DampHoltWintMult | alpha | 0.65 |
| DampHoltWintMult | beta | 0.15 |
| DampHoltWintMult | gamma | 0.08 |
| DampHoltWintMult | phi | 0.98 |
| DampHoltWintMult | l[0] | 5.88 |
| DampHoltWintMult | b[0] | 0.07 |
| DampHoltWintMult | s[0] | 0.93 |
| DampHoltWintMult | s[-1] | 1.18 |
| DampHoltWintMult | s[-2] | 1.07 |
| DampHoltWintMult | s[-3] | 0.82 |
fit |>
forecast(h = 24) |>
autoplot(gas, level = NULL) +
labs(title = "Gas Production",
subtitle = "Forecasts",
y = "Petajoules")
We plot the full data here to answer the first question. Multiplicative seasonality is required because the seasonal variations are not constant throughout the series. They change proportional to the level of the series, as can clearly be seen when looking at the difference in seasonal variation between the beginning, middle, and end of the time series. Seasonal variation goes from pretty small to pretty large.
Next we zoom in on the most recent data to compare forecasts.
gas_since_2005 <- gas |>
filter(year(Quarter) >= 2005)
fit |>
forecast(h = 24) |>
autoplot(gas_since_2005, level = NULL) +
labs(title = "Gas Production",
subtitle = "Forecasts",
y = "Petajoules")
Even though multiplicative seasonality is necessary here, using additive seasonality actually comes closer to fitting the test data. Damping the trend does improve the multiplicative seasonality forecasts slightly, but the damped multiplicative forecasts are still not as close to the test data as the additive forecasts. We aren’t suggesting we should use additive seasonality when we know it’s not appropriate, however.
Recall your retail time series data (from Exercise 7 in Section 2.10).
data(aus_retail)
set.seed(1221)
my_series <- aus_retail |>
filter(`Series ID` == sample(aus_retail$`Series ID`, 1))
my_series |>
autoplot(Turnover)
Multiplicative seasonality is again necessary here because the seasonal variation is not constant throughout the time series. The seasonal variation at the beginning levels of the time series is smaller than at the middle/end levels of the time series.
fit <- my_series |>
filter(year(Month) < 2011) |>
model(HoltWintMult = ETS(Turnover ~ error("M") + trend("A") + season("M")),
DampHoltWintMult = ETS(Turnover ~
error("M") + trend("Ad") + season("M")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| State | Industry | .model | term | estimate |
|---|---|---|---|---|
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | alpha | 0.60 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | beta | 0.00 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | gamma | 0.13 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | l[0] | 2.30 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | b[0] | 0.04 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[0] | 1.13 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-1] | 0.95 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-2] | 0.87 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-3] | 1.43 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-4] | 0.99 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-5] | 0.92 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-6] | 0.94 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-7] | 1.00 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-8] | 0.95 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-9] | 0.90 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-10] | 0.98 |
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | s[-11] | 0.93 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | alpha | 0.58 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | beta | 0.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | gamma | 0.13 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | phi | 0.98 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | l[0] | 2.45 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | b[0] | 0.05 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[0] | 1.16 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-1] | 0.94 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-2] | 0.87 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-3] | 1.42 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-4] | 0.98 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-5] | 0.93 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-6] | 0.93 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-7] | 1.01 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-8] | 0.96 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-9] | 0.90 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-10] | 0.96 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-11] | 0.93 |
fit |>
forecast(h = 168) |>
autoplot(my_series, level = NULL) +
labs(title = "Australian Turnover (My Series)",
subtitle = "Forecasts",
y = "Turnover")
acc <- accuracy(fit)
kable(acc, format = "simple")
| State | Industry | .model | .type | ME | RMSE | MAE | MPE | MAPE | MASE | RMSSE | ACF1 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Australian Capital Territory | Newspaper and book retailing | HoltWintMult | Training | -0.0373398 | 0.6889633 | 0.5020404 | -0.9923539 | 7.025620 | 0.4540452 | 0.4442017 | 0.0351070 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | Training | 0.0115891 | 0.6893085 | 0.4991133 | -0.3248674 | 6.957762 | 0.4513980 | 0.4444243 | 0.0476988 |
The RMSE is practically the same for the two methods. The Damped method provides forecasts that are closer to the test data, and it would be preferable here.
fit_dhwm_only <- my_series |>
filter(year(Month) < 2011) |>
model(DampHoltWintMult = ETS(Turnover ~
error("M") + trend("Ad") + season("M")))
fit_dhwm_only |>
gg_tsresiduals()
There are a few spikes outside the blue bounds of the ACF plot. None of them are very large, but the presence of multiple spikes indicates the data are not white noise.
aug <- fit_dhwm_only |>
augment() |>
features(.innov, ljung_box, lag = 24)
kable(aug, format="simple")
| State | Industry | .model | lb_stat | lb_pvalue |
|---|---|---|---|---|
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | 48.86096 | 0.0019718 |
The Ljung-Box test also confirms that the residuals are distinguishable from white noise.
fit <- my_series |>
filter(year(Month) < 2011) |>
model(DampHoltWintMult = ETS(Turnover ~
error("M") + trend("Ad") + season("M")),
SeasonalNaive = SNAIVE(Turnover))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| State | Industry | .model | term | estimate | std.error | statistic | p.value |
|---|---|---|---|---|---|---|---|
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | alpha | 0.58 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | beta | 0.00 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | gamma | 0.13 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | phi | 0.98 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | l[0] | 2.45 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | b[0] | 0.05 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[0] | 1.16 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-1] | 0.94 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-2] | 0.87 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-3] | 1.42 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-4] | 0.98 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-5] | 0.93 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-6] | 0.93 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-7] | 1.01 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-8] | 0.96 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-9] | 0.90 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-10] | 0.96 | NA | NA | NA |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-11] | 0.93 | NA | NA | NA |
fit |>
forecast(h = 168) |>
autoplot(my_series, level = NULL) +
labs(title = "Australian Turnover (My Series)",
subtitle = "Forecasts",
y = "Turnover")
acc <- accuracy(fit)
kable(acc, format = "simple")
| State | Industry | .model | .type | ME | RMSE | MAE | MPE | MAPE | MASE | RMSSE | ACF1 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | Training | 0.0115891 | 0.6893085 | 0.4991133 | -0.3248674 | 6.957762 | 0.451398 | 0.4444243 | 0.0476988 |
| Australian Capital Territory | Newspaper and book retailing | SeasonalNaive | Training | 0.2258258 | 1.5510144 | 1.1057057 | 2.1931710 | 14.952835 | 1.000000 | 1.0000000 | 0.8094843 |
my_series_since_2011 <- my_series |>
filter(year(Month) >= 2011)
fit |>
forecast(h = 168) |>
autoplot(my_series_since_2011, level = NULL) +
labs(title = "Australian Turnover (My Series)",
subtitle = "Forecasts",
y = "Turnover")
Yes, the Damped Holt’s Linear Trend Method beats the Seasonal Naive method.
For the same retail data, try an STL decomposition applied to the Box-Cox transformed series, followed by ETS on the seasonally adjusted data. How does that compare with your best previous forecasts on the test set?
lam <- my_series |>
features(Turnover, features = guerrero) |>
pull(lambda_guerrero)
my_series_transformed <- my_series |>
mutate(Turnover_Transformed = nthroot(Turnover, n = 4)) |>
model(STL = STL(Turnover_Transformed)) |>
components() |>
select(-.model)
fit <- my_series_transformed |>
filter(year(Month) < 2011) |>
model(DampHoltWintMult = ETS(season_adjust^4 ~
error("M") + trend("Ad") + season("M")))
fit_print <- tidy(fit)
fit_print$estimate <- format(round(fit_print$estimate, 2), scientific = FALSE)
kable(fit_print, format = "simple")
| State | Industry | .model | term | estimate |
|---|---|---|---|---|
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | alpha | 0.67 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | beta | 0.04 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | gamma | 0.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | phi | 0.91 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | l[0] | 2.37 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | b[0] | 0.09 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[0] | 1.01 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-1] | 1.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-2] | 1.01 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-3] | 1.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-4] | 0.98 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-5] | 0.99 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-6] | 0.99 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-7] | 0.99 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-8] | 1.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-9] | 1.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-10] | 1.00 |
| Australian Capital Territory | Newspaper and book retailing | DampHoltWintMult | s[-11] | 1.01 |
my_series_transformed_since_2011 <- my_series_transformed |>
filter(year(Month) >= 2011)
fit |>
forecast(h = 168) |>
autoplot(my_series_transformed_since_2011, level = NULL) +
labs(title = "Australian Turnover (My Series)",
subtitle = "Forecasts",
y = "Turnover")
These forecasts are better than any previous forecasts on the test set.