Getting started with spooky 2.0

Giancarlo Vercellino

2026-09-07

Overview

spooky forecasts one or more time features with a compact spectral model. It uses differencing, FFT extrapolation, rolling validation, and jackknife-style resampling to compare candidate sequence lengths and leave-out values.

Spooky 2.0 has no runtime dependencies beyond base R packages.

Numeric forecasting

The package includes time_features, a small example data set with two numeric series. The following fits one candidate model and keeps the example fast.

data(time_features)
fit <- spooky(time_features, seq_len = 10, lno = 1,
              n_samp = 1, n_windows = 2, seed = 42)
fit
#> Spooky 2.0 fit
#> Features: 2 
#> Candidates: 1
fit$best_model$testing_errors
#>                   me      mae       mse rmsse      mape      rmae
#> IBM.Close  -10.25244 14.42115  324.6378   NaN 0.1115564 0.9997535
#> MSFT.Close  61.89077 61.92975 6714.8292   NaN 0.3304639 0.9997016
head(fit$best_model$preds[[1]])
#>        min      10%      25%      50%      75%      90%      max     mean
#> 1 127.2167 130.4788 135.3719 143.5271 151.6823 156.5754 159.8375 143.5271
#> 2 126.6978 130.0118 134.9827 143.2676 151.5526 156.5235 159.8375 143.2676
#> 3 126.6839 129.9993 134.9723 143.2607 151.5491 156.5221 159.8375 143.2607
#> 4 127.2456 130.5048 135.3936 143.5415 151.6895 156.5783 159.8375 143.5415
#> 5 127.2225 130.4840 135.3762 143.5300 151.6837 156.5760 159.8375 143.5300
#> 6 126.5231 129.8545 134.8517 143.1803 151.5089 156.5060 159.8375 143.1803
#>         sd
#> 1 23.06637
#> 2 23.43329
#> 3 23.44309
#> 4 23.04595
#> 5 23.06229
#> 6 23.55685

The history component records the candidate settings and validation errors. The best_model component contains errors, prediction summaries, and plot objects for each input feature.

Categorical forecasting

Categorical columns are encoded internally, so no dummy-variable package is needed.

events <- data.frame(state = factor(rep(c("quiet", "active"), 30)))
categorical_fit <- spooky(events, seq_len = 2, lno = 1,
                          n_samp = 1, n_windows = 2, seed = 42)
categorical_fit$best_model$testing_errors
#>            dice       mae
#> state 0.3255814 0.5616345

Reproducibility

Set seed to make the random candidate search reproducible. For a larger search, provide ranges for seq_len and lno, and increase n_samp.

fit <- spooky(time_features,
              seq_len = c(5, 30), lno = c(1, 10),
              n_samp = 30, n_windows = 3, seed = 42)