# fasster An implementation of the FASSTER (Forecasting with Additive Switching of Seasonality, Trend and Exogenous Regressors) model in R. This model is designed to capture patterns of multiple seasonality in a state space framework by using state switching. The *fasster* package prioritizes flexibility, computational speed and accuracy to provide convenient tools for modelling, predicting and understanding high frequency time-series. ## Model information This model was developed in 2017 for an honours thesis, and the clearest description with examples of using fasster can be found in my useR! 2018 talk: [slides](https://slides.mitchelloharawild.com/user2018/), [video](https://www.youtube.com/watch?v=6YlboftSalY), [source](https://github.com/mitchelloharawild/talk-user2018-fasster). The model uses a forward filtering backward smoothing heuristic for estimating the initial states in the model. It is essentially an opinionated wrapper of the `{dlm}` package aimed at making it easier to specify a sophisticated model suitable for forecasting complex seasonal patterns. ## Installation The **stable** version can be installed from CRAN: ``` r install.packages("fasster") ``` The **development** version can be installed from GitHub using: ``` r # install.packages("devtools") devtools::install_github("tidyverts/fasster") ``` ## Usage ### Model specification *fasster* allows flexible model specification by allowing the user to specify the model structure with standard formula conventions. ``` r library(fasster) library(tidyverse) library(lubridate) library(tsibble) library(fable) lung_deaths <- as_tsibble(cbind(mdeaths, fdeaths), pivot_longer = FALSE) fit <- lung_deaths |> model(fasster = FASSTER(fdeaths ~ mdeaths)) fit |> report() #> Series: fdeaths #> Model: FASSTER #> #> Estimated variances: #> State noise variances (W): #> mdeaths #> 1.7119e-34 #> #> Observation noise variance (V): #> 1.6631e+03 #> #> Initial states (m0): #> mdeaths: 3.7711e-01 ``` Commonly used state space components can be added using the following convenience functions: - `trend(n)` to include an n-th order polynomial - `season(s)` to include a seasonal factor of frequency s - `fourier(s, q)` to include seasonal fourier terms of frequency s with q harmonics - `arma(ar, ma)` to include an ARMA term (where ar and ma are vectors of coefficients) - Exogenous regressors can be added by referring to their name For example, to create a model with trend and monthly seasonality, you can use: ``` r fit <- as_tsibble(USAccDeaths) |> model(fasster = FASSTER(value ~ trend(1) + fourier(12))) fit |> report() #> Series: value #> Model: FASSTER #> #> Estimated variances: #> State noise variances (W): #> fourier(12) #> 3.5590e-13 2.3103e-13 3.5905e-13 4.3745e-13 3.6531e-13 8.4136e-13 2.6433e-13 3.4998e-13 4.1144e-13 3.6736e-13 1.3359e-13 #> trend(1) #> 5.9382e+03 #> #> Observation noise variance (V): #> 2.0543e+04 #> #> Initial states (m0): #> fourier(12): -7.2510e+02 #> fourier(12): -7.4524e+02 #> fourier(12): 4.1713e+02 #> fourier(12): 8.1375e+01 #> fourier(12): 1.5506e+02 #> fourier(12): -1.9470e+02 #> fourier(12): -1.0038e+01 #> fourier(12): 1.5899e+02 #> fourier(12): 1.5997e+02 #> fourier(12): 2.0428e+02 #> fourier(12): -1.5165e+01 #> trend(1): 9.7398e+03 ``` The interface for creating a FASSTER model introduces a new formula construct, `%S%`, known as the switch operator. This allows modelling of more complex patterns such as multiple seasonality by modelling the components for each group separately and switching between them. ``` r elec_tr <- tsibbledata::vic_elec |> filter( Time < lubridate::ymd("2012-03-01") ) |> mutate(WorkDay = wday(Time) %in% 2:6 & !Holiday) elec_fit <- elec_tr |> model( fasster = fasster(log(Demand) ~ WorkDay %S% (fourier(48, 16) + trend(1)) + Temperature + I(Temperature^2) ) ) ``` ### Decomposing Fitted FASSTER models can be decomposed to provide a description of how the underlying states function. Decomposing a FASSTER model provides aggregates of its components such as trends and seasonalities. These components can accessed from a fitted model using the [`components()`](https://generics.r-lib.org/reference/components.html) function: ``` r fit |> components() #> # A dable: 72 x 5 [1M] #> # Key: .model [1] #> # : value = `fourier(12)` + `trend(1)` #> .model index value `fourier(12)` `trend(1)` #> #> 1 fasster 1973 Jan 9007 -795. 9740. #> 2 fasster 1973 Feb 8106 -1546. 9754. #> 3 fasster 1973 Mar 8928 -758. 9719. #> 4 fasster 1973 Apr 9137 -536. 9706. #> 5 fasster 1973 May 10017 322. 9693. #> 6 fasster 1973 Jun 10826 802. 9694. #> 7 fasster 1973 Jul 11317 1669. 9830. #> 8 fasster 1973 Aug 10744 974. 9755. #> 9 fasster 1973 Sep 9713 -65.7 9761. #> 10 fasster 1973 Oct 9938 233. 9768. #> # ℹ 62 more rows ``` ``` r elec_fit |> components() #> # A dable: 2,880 x 9 [30m] #> # Key: .model [1] #> # : log(Demand) = `WorkDay_FALSE/fourier(48, 16)` + #> # `WorkDay_FALSE/trend(1)` + `WorkDay_TRUE/fourier(48, 16)` + #> # `WorkDay_TRUE/trend(1)` + Temperature + `I(Temperature^2)` #> .model Time `log(Demand)` `WorkDay_FALSE/fourier(48, 16)` #> #> 1 fasster 2012-01-01 00:00:00 8.39 -0.00345 #> 2 fasster 2012-01-01 00:30:00 8.36 -0.0234 #> 3 fasster 2012-01-01 01:00:00 8.31 -0.0971 #> 4 fasster 2012-01-01 01:30:00 8.26 -0.105 #> 5 fasster 2012-01-01 02:00:00 8.30 -0.117 #> 6 fasster 2012-01-01 02:30:00 8.26 -0.0812 #> 7 fasster 2012-01-01 03:00:00 8.21 -0.251 #> 8 fasster 2012-01-01 03:30:00 8.18 -0.144 #> 9 fasster 2012-01-01 04:00:00 8.14 -0.374 #> 10 fasster 2012-01-01 04:30:00 8.12 -0.202 #> # ℹ 2,870 more rows #> # ℹ 5 more variables: `WorkDay_FALSE/trend(1)` , #> # `WorkDay_TRUE/fourier(48, 16)` , `WorkDay_TRUE/trend(1)` , #> # Temperature , `I(Temperature^2)` ``` The tools made available by *fasster* are designed to integrate seamlessly with the tidyverse of packages, enabling familiar data manipulation and visualisation capabilities. ### Forecasting *fasster* conforms to the object structure from the *fable* package, allowing common visualisation and analysis tools to be applied on FASSTER models. ``` r fit |> forecast(h=24) |> autoplot(as_tsibble(USAccDeaths)) ``` ![](man/figure/forecast-1.png) Future index values are automatically produced and used where necessary in the model specification. If additional information is required by the model (such as `WorkDay` and `Temperature`) they must be included in a `tsibble` of future values passed to `new_data`. ``` r elec_ts <- tsibbledata::vic_elec |> filter( yearmonth(Time) == yearmonth("2012 Mar") ) |> mutate(WorkDay = wday(Time) %in% 2:6 & !Holiday) |> select(-Demand) elec_fit |> forecast(new_data = elec_ts) |> autoplot(elec_tr) ``` ![](man/figure/complex_fc-1.png) # Package index ## Model specification Functions for specifying and estimating FASSTER models - [`FASSTER()`](https://fasster.tidyverts.org/reference/fasster-model.md) : Fast Additive Switching of Seasonality, Trend and Exogenous Regressors ## Model extraction Functions to extract information from fitted FASSTER models - [`tidy(`*``*`)`](https://fasster.tidyverts.org/reference/tidy.FASSTER.md) : Extract coefficients from a FASSTER model - [`glance(`*``*`)`](https://fasster.tidyverts.org/reference/glance.FASSTER.md) : Glance at a FASSTER model - [`fitted(`*``*`)`](https://fasster.tidyverts.org/reference/fitted.FASSTER.md) : Extract fitted values from a FASSTER model - [`residuals(`*``*`)`](https://fasster.tidyverts.org/reference/residuals.FASSTER.md) : Extract residuals from a FASSTER model - [`components(`*``*`)`](https://fasster.tidyverts.org/reference/components.FASSTER.md) : Extract Components from a FASSTER Model ## Forecasting and prediction Functions for generating forecasts and streaming new data - [`forecast(`*``*`)`](https://fasster.tidyverts.org/reference/forecast.FASSTER.md) : Forecast a FASSTER model - [`interpolate(`*``*`)`](https://fasster.tidyverts.org/reference/interpolate.FASSTER.md) : Interpolate missing values in a FASSTER model ## Model re-estimation Functions for refitting and updating models with new data - [`refit(`*``*`)`](https://fasster.tidyverts.org/reference/refit.FASSTER.md) : Refit a FASSTER model - [`stream(`*``*`)`](https://fasster.tidyverts.org/reference/stream.FASSTER.md) : Stream new data through a FASSTER model ## Reporting Functions for displaying model information - [`report(`*``*`)`](https://fasster.tidyverts.org/reference/report.FASSTER.md) : Report on a FASSTER model # Articles ### All vignettes - [Introduction to FASSTER](https://fasster.tidyverts.org/articles/fasster.md):