How to let ETS() choose a model, and when to override it

Today let's understand how ETS() decides which model to fit on its own, and when that automatic pick is worth overriding.

Take Western Australia's domestic holiday trips, counted every quarter from 1998 to 2017, in thousands of overnight trips. That's 80 quarters of real tourism numbers, and the series climbs across the two decades, from around 750 thousand trips a quarter in the late 1990s to over 1,000 thousand two decades later. Here is all 80 quarters of it, plotted in order.

Look at how that line climbs unevenly over the two decades, dipping and recovering along the way. In the steps ahead, you will let ETS() search across every reasonable combination on exactly this series, and see which one it picks for you.

ETS() with no formula: fitting becomes a search

ETS stands for three parts a model can have: Error, Trend and Season. Error is either additive (A), where the noise around the series stays roughly the same size no matter how high the series runs, or multiplicative (M), where the noise grows and shrinks along with the level. Trend is none (N), additive (A) as a straight climb or fall, or additive damped (Ad), a climb that flattens out over time. Season is none (N), additive (A) as a repeating swing of fixed size, or multiplicative (M) as a repeating swing that grows with the level.

report() always writes a model's name as ETS(error, trend, season), in that fixed order. So ETS(A,A,A) means additive error, additive trend, additive season, and ETS(M,N,M) means multiplicative error, no trend, multiplicative season.

Until now, you have told ETS() exactly which of those three letters to use, by writing something like ETS(trips ~ error("A") + trend("A") + season("A")). But you do not have to name any of them. Leave the right-hand side off entirely, and ETS() fits every valid combination itself and hands you back the one it judged best.

Build the WA series first, then fit it both ways and compare the labels.

RInteractive R
# Build the WA quarterly holiday-trips tsibble, then let ETS() search for the best model on its own library(fable) library(tsibble) library(dplyr) trips <- c(773, 720, 755, 814, 943, 845, 823, 697, 905, 905, 672, 716, 709, 738, 762, 813, 871, 773, 789, 643, 846, 714, 722, 766, 942, 685, 772, 727, 817, 646, 650, 624, 863, 761, 679, 799, 852, 786, 702, 762, 900, 654, 736, 655, 748, 642, 570, 584, 636, 627, 603, 567, 733, 648, 613, 666, 779, 680, 629, 692, 918, 745, 680, 691, 1266, 1066, 855, 898, 1168, 990, 928, 960, 1166, 1054, 804, 983, 1134, 998, 880, 1026) wa <- tsibble( quarter = yearquarter(seq(as.Date("1998-01-01"), by = "quarter", length.out = 80)), trips = trips, index = quarter ) fit_auto <- wa |> model(auto = ETS(trips)) fit_auto #> # A mable: 1 x 1 #> auto #> <model> #> 1 <ETS(M,N,M)>

  

Now fit the same 80 quarters again, but name every letter yourself.

RInteractive R
# Fit the same data, but name every letter yourself instead of letting ETS() search fit_named <- wa |> model(named = ETS(trips ~ error("A") + trend("A") + season("A"))) fit_named #> # A mable: 1 x 1 #> named #> <model> #> 1 <ETS(A,A,A)>

  

Two different labels from the same 80 quarters. fit_named is exactly what you asked for: additive error, additive trend, additive season, because that is what you typed. fit_auto's label, ETS(M,N,M), is not something you picked. It is what fable's search judged as the best fit among every combination it tried, silently, in the background.