predict.tulip | R Documentation |
Generate a forecast in the form of n
sample paths for the forecast horizon
h
based on the fitted model object
.
## S3 method for class 'tulip'
predict(
object,
h = 12,
n = 10000,
remove_anomalies = TRUE,
postprocess_sample = identity,
...
)
object |
The fitted model object returned by |
h |
The forecast horizon as integer number of periods. |
n |
The integer number of sample paths to draw from the forecast distribution. |
remove_anomalies |
Logical (default |
postprocess_sample |
A function that is applied on a numeric vector of
drawn samples for a single step-ahead before the samples are used to
update the state of the model, and before outliers are removed
(if applicable). By default equal to |
... |
arguments passed to or from other methods. |
The forecasts of a tulip
model are natively represented by sample paths.
Instead of providing a single point forecast, or marginal quantiles, possible
future outcomes are summarized through samples from the joint distribution
across future horizons. These samples can be summarized down to marginal
quantiles, but they also contain the dependency between future horizons
that is commonly lost by forecast frameworks that solely store marginal
quantile forecasts.
Depending on the chosen family
, the samples are either based on a
distribution that is fitted against the model's residuals during the fitting
procedure; or they can be based directly on bootstrapped residuals if
the family
of the tulip
object is overwritten to be bootstrap
. In the
latter case, the forecast distribution can represent asymmetries that were
observed in the input data. You might not want to use bootstrap
when the
input time series is very short. In such cases, a parametric assumption can
help with more reasonable behavior of the error component.
As for all exponential smoothing models, the one-step-ahead sample is fed back into the model to update the state components, before the two-step-ahead forecast sample is drawn given the updated state components. Through this mechanism, the temporal dependencies between samples of the same sample path are maintained. For example, if the initial sample is higher than average, the level and trend components of the model might update to be larger, thus consequently increasing chances that the next sample is again high (compared to the most recently observed training observation and level).
If the model is able to represent the input data well, then sample paths look like reasonable future continuations of the input series. Averaging across sample paths one can derive quantiles of the forecast distribution.
Importantly, because the sample paths maintain the temporal dependencies, one can also aggregate the forecasts across forecast horizons which is not possible when only quantiles are returned by a model. The ability to summarize arbitrary aggregates can be helpful for optimization problems that use the forecast as input.
The returned value is a matrix of dimensions h
times n
. Each of the n
columns represents one sample path and is a random draw from the
h
-dimensional forecast distribution. See also examples below.
Use the postprocess_sample
argument to hook into the sampling process of
the predict()
method. Provide a function that is applied on the current
j-step-ahead vector of samples before it is fed back into the model, before
the states are updated given those samples. This allows you to adjust the
data generating process–for example, to enforce non-negative count samples–
while doing so before the state components (level, trend, seasonality) of the
model are updated given the most recent sample. This can prevent the model's
level from drifting to zero, for example, because samples never became
less than zero, thus affecting subsequent samples to drift even further below
zero, and so on. Generated samples stay similar to the input data, allowing
the forecast to stay similar to the input data.
An object of class tulip_paths
that is a list of:
A matrix of dimensions (h
, n
), in which each of the n
columns represents one sample path over the h
-steps-ahead
The provided model object
https://papers.nips.cc/paper/2018/hash/5cf68969fb67aa6082363a6d4e6468e2-Abstract.html
https://proceedings.neurips.cc/paper/2016/file/03255088ed63354a54e0e5ed957e9008-Paper.pdf
tulip()
, autoplot.tulip_paths()
, stats::predict()
fitted_model <- tulip(y = tulip::flowers$flowers, m = 12)
forecast <- predict(object = fitted_model, h = 12, n = 10000)
# library(ggplot2)
# visualize the marginal quantile forecast
# autoplot(forecast)
# visualize a handful of sample paths directly
# autoplot(forecast, method = "paths")
# let's take a closer look at the sample paths themselves
m_fc <- forecast$paths
# summarize over draws (columns) to get point forecasts
rowMeans(m_fc)
# marginal quantiles can be derived in much the same way
apply(m_fc, 1, quantile, 0.05)
apply(m_fc, 1, quantile, 0.95)
# we can also summarize the distribution of the sum over horizons 4 to 6
quantile(colSums(m_fc[4:6, ]), c(0.05, 0.5, 0.95))
# sample paths carry autocorrelation, the horizons are not independent of
# another; this is revealed when we drop the autocorrelation by shuffling
# at each margin randomly and try to recompute the same quantiles as above:
m_fc_shuffled <- rbind(
m_fc[4, sample(x = 1:10000, size = 10000, replace = TRUE), drop = FALSE],
m_fc[5, sample(x = 1:10000, size = 10000, replace = TRUE), drop = FALSE],
m_fc[6, sample(x = 1:10000, size = 10000, replace = TRUE), drop = FALSE]
)
quantile(colSums(m_fc_shuffled), c(0.05, 0.5, 0.95))
# one can also look directly at the correlation
cor(m_fc[4, ], m_fc[6, ])
cor(m_fc_shuffled[1, ], m_fc_shuffled[3, ])
# -------------------
# An example of how the `postprocess_sample` argument can be used to
# enforce non-negative forecasts
set.seed(7759)
y <- rpois(n = 60, lambda = 1)
ls_fit <- tulip(y = y, m = 12, family = "norm", method = "additive")
ls_fit$family <- "bootstrap"
m_fc <- predict(
object = ls_fit,
h = 12,
n = 10000,
postprocess_sample = function(x) pmax(0, x)
)
# library(ggplot2)
# autoplot(m_fc)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.