Title: | Convenient Functions for Ensemble Time Series Forecasts |
Version: | 5.1.20 |
Date: | 2025-07-03 |
Description: | Convenient functions for ensemble forecasts in R combining approaches from the 'forecast' package. Forecasts generated from auto.arima(), ets(), thetaf(), nnetar(), stlm(), tbats(), snaive() and arfima() can be combined with equal weights, weights based on in-sample errors (introduced by Bates & Granger (1969) <doi:10.1057/jors.1969.103>), or cross-validated weights. Cross validation for time series data with user-supplied models and forecasting functions is also supported to evaluate model accuracy. |
Depends: | R (≥ 4.0.4), forecast (≥ 8.16), thief |
Imports: | doParallel (≥ 1.0.16), foreach (≥ 1.5.1), ggplot2 (≥ 3.3.6), purrr (≥ 0.3.5), zoo (≥ 1.8) |
Suggests: | GMDH, knitr, rmarkdown, roxygen2, testthat |
VignetteBuilder: | knitr |
License: | GPL-3 |
URL: | https://gitlab.com/dashaub/forecastHybrid, https://github.com/ellisp/forecastHybrid |
BugReports: | https://github.com/ellisp/forecastHybrid/issues |
RoxygenNote: | 7.3.2 |
ByteCompile: | true |
NeedsCompilation: | no |
Encoding: | UTF-8 |
Packaged: | 2025-07-03 18:09:21 UTC; felix |
Author: | David Shaub [aut, cre], Peter Ellis [aut] |
Maintainer: | David Shaub <davidshaub@alumni.harvard.edu> |
Repository: | CRAN |
Date/Publication: | 2025-07-06 23:30:02 UTC |
Accuracy measures for cross-validated time series
Description
Returns range of summary measures of the cross-validated forecast accuracy
for cvts
objects.
Usage
## S3 method for class 'cvts'
accuracy(object, ..., f = NULL)
Arguments
object |
a |
... |
other arguments (ignored). |
f |
Deprecated. Please use 'object' instead. |
Details
Currently the method only implements ME
, RMSE
, and MAE
. The accuracy
measures MPE
, MAPE
, and MASE
are not calculated. The accuracy
is calculated for each forecast horizon up to maxHorizon
Author(s)
David Shaub
Accuracy measures for hybridModel objects
Description
Accuracy measures for hybridModel objects.
Usage
## S3 method for class 'hybridModel'
accuracy(object, individual = FALSE, ..., f = NULL)
Arguments
object |
the input hybridModel. |
individual |
if |
... |
other arguments (ignored). |
f |
Deprecated. Please use 'object' instead. |
Details
Return the in-sample accuracy measures for the component models of the hybridModel
Value
The accuracy of the ensemble or individual component models.
Author(s)
David Shaub
See Also
Validate that CV window parameters are valid
Description
Validate that CV window parameters are valid
Usage
checkCVArguments(x, windowSize, maxHorizon)
Arguments
x |
the input time series. |
windowSize |
length of the window to build each model. When |
maxHorizon |
maximum length of the forecast horizon to use for computing errors. |
Helper function to test all the model arguments (e.g. a.args, e.args, etc)
Description
Helper function to test all the model arguments (e.g. a.args, e.args, etc)
Usage
checkModelArgs(modelArguments, models)
Arguments
modelArguments |
A list of containing the model arguments |
models |
A character vector containing all the model codes |
Helper function to check the that the parallel arguments are valid
Description
Helper function to check the that the parallel arguments are valid
Usage
checkParallelArguments(parallel, num.cores)
Arguments
parallel |
A logic to indicate if parallel processing should be used |
num.cores |
An integer for the number of threads to use |
Cross validation for time series
Description
Perform cross validation on a time series.
Usage
cvts(
x,
FUN = NULL,
FCFUN = NULL,
rolling = FALSE,
windowSize = 84,
maxHorizon = 5,
horizonAverage = FALSE,
xreg = NULL,
saveModels = length(x) <= 500,
saveForecasts = length(x) <= 500,
verbose = TRUE,
num.cores = 2L,
extraPackages = NULL,
...
)
Arguments
x |
the input time series. |
FUN |
the model function used. Custom functions are allowed. See details and examples. |
FCFUN |
a function that process point forecasts for the model function. This defaults
to |
rolling |
should a rolling procedure be used? If TRUE, non-overlapping windows
of size |
windowSize |
length of the window to build each model. When |
maxHorizon |
maximum length of the forecast horizon to use for computing errors. |
horizonAverage |
should the final errors be an average over all forecast horizons
up to |
xreg |
External regressors to be used to fit the model. Only used if FUN accepts xreg as an argument. FCFUN is also expected to accept it (see details) |
saveModels |
should the individual models be saved? Set this to |
saveForecasts |
should the individual forecast from each model be saved? Set this
to |
verbose |
should the current progress be printed to the console? |
num.cores |
the number of cores to use for parallel fitting. If the underlying model that is being fit also utilizes parallelization, the number of cores it is using multiplied by 'num.cores' should not exceed the number of cores available on your machine. |
extraPackages |
on Windows if a custom 'FUN' or 'FCFUN' is being used that requires loaded, these can be passed here so that they can be passed to parallel socket workers |
... |
Other arguments to be passed to the model function FUN |
Details
Cross validation of time series data is more complicated than regular
k-folds or leave-one-out cross validation of datasets
without serial correlation since observations x_t
and x_{t+n}
are not independent. The cvts()
function overcomes
this obstacle using two methods: 1) rolling cross validation where an initial training window
is used along with a forecast horizon
and the initial window used for training grows by one observation each round until the training
window and the forecast horizon capture the
entire series or 2) a non-rolling approach where a fixed training length is used that
is shifted forward by the forecast horizon after each iteration.
For the rolling approach, training points are heavily recycled, both in terms of used for fitting
and in generating forecast errors at each of the forecast horizons from 1:maxHorizon
.
In contrast, the models fit with
the non-rolling approach share less overlap, and the predicted forecast values are also
only compared to the actual values once.
The former approach is similar to leave-one-out cross validation while the latter resembles
k-fold cross validation. As a result,
rolling cross validation requires far more iterations and computationally takes longer
to complete, but a disadvantage of the
non-rolling approach is the greater variance and general instability of cross-validated errors.
The FUN
and FCFUN
arguments specify which function to use
for generating a model and forecasting, respectively. While the functions
from the "forecast" package can be used, user-defined functions can also
be tested, but the object returned by FCFUN
must
accept the argument h
and contain the point forecasts out to
this horizon h
in slot $mean
of the returned object. An example is given with
a custom model and forecast.
For small time series (default length <= 500
), all of the individual fit models
are included in the final
cvts
object that is returned. This can grow quite large since functions
such as auto.arima
will
save fitted values, residual values, summary statistics, coefficient matrices, etc.
Setting saveModels = FALSE
can be safely done if there is no need to examine individual models fit at every stage
of cross validation since the
forecasts from each fold and the associated residuals are always saved.
External regressors are allowed via the xreg
argument. It is assumed that both
FUN
and FCFUN
accept the xreg
parameter if xreg
is not NULL
.
If FUN
does not accept the xreg
parameter a warning will be given.
No warning is provided if FCFUN
does not use the xreg
parameter.
Author(s)
David Shaub
See Also
Examples
series <- subset(AirPassengers, end = 50)
cvmod1 <- cvts(series, FUN = snaive,
windowSize = 25, maxHorizon = 12)
accuracy(cvmod1)
# We can also use custom model functions for modeling/forecasting
stlmClean <- function(x) stlm(tsclean(x))
series <- subset(austres, end = 38)
cvmodCustom <- cvts(series, FUN = stlmClean, windowSize = 26, maxHorizon = 6)
accuracy(cvmodCustom)
# Use the rwf() function from the "forecast" package.
# This function does not have a modeling function and
# instead calculates a forecast on the time series directly
series <- subset(AirPassengers, end = 26)
rwcv <- cvts(series, FCFUN = rwf, windowSize = 24, maxHorizon = 1)
# Don't return the model or forecast objects
cvmod2 <- cvts(USAccDeaths, FUN = stlm,
saveModels = FALSE, saveForecasts = FALSE,
windowSize = 36, maxHorizon = 12)
# If we don't need prediction intervals and are using the nnetar model, turning off PI
# will make the forecasting much faster
series <- subset(AirPassengers, end=40)
cvmod3 <- cvts(series, FUN = hybridModel,
FCFUN = function(mod, h) forecast(mod, h = h, PI = FALSE),
rolling = FALSE, windowSize = 36,
maxHorizon = 2)
Extract cross validated rolling forecasts
Description
Obtain cross validated forecasts when rolling cross validation is used. The object is not inspected to see if it was fit using a rolling origin
Usage
extractForecasts(cv, horizon = 1)
Arguments
cv |
An object of class cvts |
horizon |
The forecast horizon from each fold to extract |
Details
Combine the cross validated forecasts fit with a rolling origin. This may be useful to visualize and investigate the cross validated performance of the model
Value
Forecasts computed via a rolling origin
Author(s)
Ganesh Krishnan
Examples
cv <- cvts(AirPassengers, FUN = stlm, FCFUN = forecast,
rolling = TRUE, windowSize = 134, horizon = 2)
extractForecasts(cv)
Extract Model Fitted Values
Description
Extract the model fitted values from the hybridModel
object.
Usage
## S3 method for class 'hybridModel'
fitted(object, individual = FALSE, ...)
Arguments
object |
the input hybridModel. |
individual |
if |
... |
other arguments (ignored). |
Value
The fitted values of the ensemble or individual component models.
See Also
Hybrid forecast
Description
Forecast method for hybrid models.
Usage
## S3 method for class 'hybridModel'
forecast(
object,
h = ifelse(object$frequency > 1, 2 * object$frequency, 10),
xreg = NULL,
level = c(80, 95),
PI = TRUE,
fan = FALSE,
PI.combination = c("extreme", "mean"),
...
)
Arguments
object |
a hybrid time series model fit with hybridModel. |
h |
number of periods for forecasting. If |
xreg |
future values of regression variables (for use if one of the ensemble methods used
in creating the hybrid forecast was |
level |
confidence level for prediction intervals. This can be expressed as a decimal between 0.0 and 1.0 or numeric between 0 and 100. |
PI |
should prediction intervals be produced? If a |
fan |
if |
PI.combination |
Method for combining the prediction intervals from each of the
forecasts. Supplying |
... |
other arguments passed to the individual |
Details
if xreg
was used in constructing the hybridModel
,
it must also be passed into forecast.hybridModel
.
While prediction intervals are produced for the
final ensemble forecast model, these should be viewed conservatively as insights
to the forecast's uncertainty. Currently these are constructed using the most extreme interval
from each component model for each horizon, so the composite prediction intervals do not
have statistical guarantees of asymptotic efficiency. More sophisticated
and rigorous techniques are planned, however, particularly when cross validation
approaches are used.
Value
An object of class forecast.
Author(s)
David Shaub
See Also
Examples
## Not run:
mod <- hybridModel(AirPassengers)
fc <- forecast(mod)
# View the point forecasts
fc$mean
# View the upper prediction interval
fc$upper
# View the lower prediction interval
fc$lower
# Plot the forecast
plot(fc)
## End(Not run)
Forecast using a Theta model
Description
Returns forecasts and other information for univariate Theta "models"
Usage
## S3 method for class 'thetam'
forecast(
object,
h = ifelse(object$m > 1, 2 * object$m, 10),
level = c(80, 95),
fan = FALSE,
...
)
Arguments
object |
An object of class " |
h |
Number of periods for forecasting |
level |
Confidence level for prediction intervals |
fan |
If TRUE, level is set to |
... |
Ignored |
Value
An object of class forecast
Author(s)
Peter Ellis
See Also
Examples
mod1 <- thetam(Nile)
fc1 <- forecast(mod1)
plot(fc1)
Return a forecast model function for a given model character
Description
Convert the single-letter representation used in the "forecastHybrid" package to the corresponding model function from the "forecast" package
Usage
getModel(modelCharacter)
Arguments
modelCharacter |
a single character representing one of the models from the |
See Also
Examples
forecastHybrid:::getModel("a")
forecastHybrid:::getModel("s")
forecastHybrid:::getModel("z")
Translate character to model name
Description
Convert the single-letter representation used in the "forecastHybrid" package to the corresponding function name from the "forecast" package
Usage
getModelName(modelCharacter)
Arguments
modelCharacter |
a single character representing one of the models from the |
See Also
Examples
forecastHybrid:::getModelName("a")
forecastHybrid:::getModelName("s")
forecastHybrid:::getModelName("z")
Hybrid time series modeling
Description
Create a hybrid time series model with two to five component models.
Usage
hybridModel(
y,
models = "aefnst",
lambda = NULL,
a.args = NULL,
e.args = NULL,
n.args = NULL,
s.args = NULL,
t.args = NULL,
x.args = NULL,
z.args = NULL,
weights = c("equal", "insample.errors", "cv.errors"),
errorMethod = c("RMSE", "MAE", "MASE"),
rolling = FALSE,
cvHorizon = frequency(y),
windowSize = 84,
horizonAverage = FALSE,
parallel = FALSE,
num.cores = 2L,
verbose = TRUE
)
Arguments
y |
A numeric vector or time series. |
models |
A character string of up to seven characters indicating which contributing
models to use:
a ( |
lambda |
Box-Cox transformation parameter. Ignored if NULL. Otherwise, data transformed before model is estimated. |
a.args |
an optional |
e.args |
an optional |
n.args |
an optional |
s.args |
an optional |
t.args |
an optional |
x.args |
an optional |
z.args |
an optional |
weights |
method for weighting the forecasts of the various contributing
models. Defaults to |
errorMethod |
method of measuring accuracy to use if weights are not
to be equal.
Root mean square error ( |
rolling |
If |
cvHorizon |
If |
windowSize |
length of the window to build each model, only used when
|
horizonAverage |
If |
parallel |
a boolean indicating if parallel processing should be used between models.
Parallelization will still occur within individual models that support it and can be controlled
using |
num.cores |
If |
verbose |
Should the status of which model is being fit/cross validated be printed to the terminal? |
Details
The hybridModel
function fits multiple individual model specifications
to allow easy creation of ensemble forecasts. While default settings for the individual
component models work quite well in most cases, fine control can be exerted by passing detailed
arguments to the component models in the a.args
, e.args
, n.args
,
s.args
, x.args
, and t.args
lists.
Note that if xreg
is passed to the a.args
, n.args
, or
s.args
component models it must now be passed as a matrix. In "forecastHybrid"
versions earlier than 4.0.15 it would instead be passed in as a dataframe, but for consistency
with "forecast" v8.5 we now require a matrix with colnames
Characteristics of the input series can cause problems for certain types of models
and parameters. For example, stlm
models require that the input
series be seasonal; furthermore, the data must include at least two seasons
of data (i.e. length(y) >= 2 * frequency(y)
) for the decomposition to succeed.
If this is not the case, hybridModel()
will remove the stlm
model so an error does not occur.
Similarly, nnetar
models require that
length(y) >= 2 * frequency(y)
, so these models will be removed if the condition
is not satisfied. The ets
model does not handle
a series well with a seasonal period longer than 24 and will ignore the seasonality.
In this case, hybridModel()
will also drop the ets
model from the ensemble.
Value
An object of class hybridModel. The individual component models are stored inside of the object and can be accessed for all the regular manipulations available in the forecast package.
Author(s)
David Shaub
See Also
forecast.hybridModel
, auto.arima
,
ets
, thetam
, nnetar
,
stlm
, tbats
Examples
## Not run:
# Fit an auto.arima, ets, thetam, nnetar, stlm, arfima, and tbats model
# on the time series with equal weights
mod1 <- hybridModel(AirPassengers)
plot(forecast(mod1))
# Use an auto.arima, ets, and tbats model with weights
# set by the MASE in-sample errors
mod2 <- hybridModel(AirPassengers, models = "aet",
weights = "insample.errors", errorMethod = "MASE")
# Pass additional arguments to auto.arima() to control its fit
mod3 <- hybridModel(AirPassengers, models = "aens",
a.args = list(max.p = 7, max.q = 7, approximation = FALSE))
# View the component auto.arima() and stlm() models
mod3$auto.arima
mod3$stlm
## End(Not run)
Test if the object is a hybridModel object
Description
Test if the object is a hybridModel
object.
Usage
is.hybridModel(x)
Arguments
x |
the input object. |
Value
A boolean indicating if the object is a hybridModel
is returned.
Plot a hybridModel object
Description
Plot a representation of the hybridModel.
Usage
## S3 method for class 'hybridModel'
plot(x, type = c("fit", "models"), ggplot = FALSE, ...)
Arguments
x |
an object of class hybridModel to plot. |
type |
if |
ggplot |
should the |
... |
other arguments passed to plot. |
Details
For type = "fit"
, the original series is plotted in black.
Fitted values for the individual component models are plotted in other colors.
For type = "models"
, each individual component model is plotted. Since
there is not plot method for stlm
or nnetar
objects, these component
models are not plotted.
Value
None. Function produces a plot.
Author(s)
David Shaub
See Also
Examples
## Not run:
hm <- hybridModel(woolyrnq, models = "aenst")
plot(hm, type = "fit")
plot(hm, type = "models")
## End(Not run)
Plot components from Theta model
Description
Produces a plot of the level components from the ETS model underlying a Theta model
Usage
## S3 method for class 'thetam'
plot(x, ...)
Arguments
x |
Object of class "thetam". |
... |
Other plotting parameters passed through to |
Details
The "state" component of the plot comes from the model ets(..., model = "ANN")
that was fit as part of the theta method. The "seasonal" component is the multipliers
from multiplicative classical
decomposition seasonal adjustment that is performed before the ets
model is fit.
The "linear" component shows the direction and slope of drift that is used in the forecasting
to come.
Value
None. Function produces a plot.
Author(s)
Peter Ellis
See Also
Examples
model <- thetam(wineind)
plot(model)
Plot the fitted values of a hybridModel object
Description
Plot a fitted values of the hybridModel.
Usage
plotFitted(x, ggplot, ...)
Arguments
x |
an object of class hybridModel to plot. |
ggplot |
should the |
... |
other arguments passed to plot. |
Plot the component models of a hybridModel object
Description
Plot a representation of the hybridModel.
Usage
plotModelObjects(x, ggplot, ...)
Arguments
x |
an object of class hybridModel to plot. |
ggplot |
should the |
... |
other arguments passed to plot. |
Helper function to validate and clean the input time series
Description
Helper function to validate and clean the input time series
Usage
prepareTimeseries(y)
Arguments
y |
The input time series |
Print information about the hybridModel object
Description
Print information about the hybridModel
object.
Usage
## S3 method for class 'hybridModel'
print(x, ...)
Arguments
x |
the input |
... |
other arguments (ignored). |
Details
Print the names of the individual component models and their weights.
Helper function to remove models that require more data
Description
Helper function to remove models that require more data
Usage
removeModels(y, models)
Arguments
y |
The input time series |
models |
The model codes to test |
Extract Model Residuals
Description
Extract the model residuals from the hybridModel
object.
Usage
## S3 method for class 'hybridModel'
residuals(object, individual = FALSE, ...)
Arguments
object |
The input hybridModel. |
individual |
If |
... |
Other arguments (ignored). |
Value
The residuals of the ensemble or individual component models.
See Also
Print a summary of the hybridModel object
Description
Print a summary of the hybridModel object
Usage
## S3 method for class 'hybridModel'
summary(x)
Arguments
x |
the input |
Details
Print the names of the individual component models and their weights.
Theta method 'model'
Description
Create a model object as an interim step to a theta method forecast.
Usage
thetam(y)
Arguments
y |
A numeric vector or time series. |
Details
This fits an exponential smoothing state space model with
model = 'ANN'
to y
, having first performed classic multiplicative
seasonal adjustment. A drift value is also calculated by
lsfit(0:(length(y) - 1), y)$coef[2] / 2
. In combination with forecast.thetam()
,
this provides identical results to forecast::thetaf(...)
. The purpose of splitting
it into a 'model' and 'forecast' functions is to make the approach consistent with other
modeling / forecasting approaches used in hybridModel()
.
Value
An object of class thetam
Author(s)
Peter Ellis
See Also
Examples
mod1 <- thetam(Nile)
plot(mod1)
Forecast ensemble using THieF
Description
Create a forecast ensemble using the theif() model
Usage
thiefModel(
y,
models = "aefnt",
h = 2 * frequency(y),
comb = c("struc", "mse", "ols", "bu", "shr", "sam"),
verbose = FALSE
)
Arguments
y |
the input time series |
models |
the models to use. These are specified the same way as |
h |
the forecast horizon |
comb |
the combination method to use by |
verbose |
if |
Details
Use the "thief" package method for reconciling forecasts across the temporal hierarchy.
The base models to be included in the ensemble are the same as those in hybridModel
, but
the stlm
model cannot be included since it requires seasonal data.
Author(s)
David Shaub
See Also
Examples
series <- subset(woolyrnq, end = 8)
thiefModel(series, models = "fz")
Combine multiple sequential time series
Description
Combine multiple ts objects into a single ts object. It is assumed that the ts objects provided are sequential. In other words, it is assumed that a valid time series object can actually be constructed from the provided objects. The start time and frequency of the combined object will correspond to the start time and frequency of the first provided object
Usage
tsCombine(...)
Arguments
... |
ts objects to combine |
Details
Combine sequential time series objects into a single time series object. This might
be useful, for example, when you want to combine the training and validation time series objects
for plotting. The function assumes that the provided objects have no overlap.
For example, a valid argument set would have two time series with periods from Jan-Dec 2015
and Jan-Dec 2016. An invalid set would be two time series t1 and t2 with periods from
Jan-Dec 2015 and Aug 2015-Dec 2016 respectively. In that case, there is overlap between
t1 and t2. The return value will depend on the order in which the arguments are provided.
If the function call is tsCombine(t1, t2), the overlapping portion of t1 and t2
(Aug-Dec 2015 in this example), would have values from t1 as long as they are not NA
.
If the call is tsCombine(t2, t1), it will have values from t2 as long as they are not NA
.
Value
A combined ts object generated from the individual ts objects
Author(s)
Ganesh Krishnan
Examples
tsCombine(window(AirPassengers, end = c(1951, 12)), window(AirPassengers, start = c(1952, 1)))
Generate training and test indices for time series cross validation
Description
Training and test indices are generated for time series cross validation. Generated indices are based on the training windowSize, forecast horizons and whether a rolling or non-rolling cross validation procedure is desired.
Usage
tsPartition(x, rolling, windowSize, maxHorizon)
Arguments
x |
A time series |
rolling |
Should indices be generated for a rolling or non-rolling procedure? |
windowSize |
Size of window for training |
maxHorizon |
Maximum forecast horizon |
Value
List containing train and test indices for each fold
Author(s)
Ganesh Krishnan
Examples
tsPartition(AirPassengers, rolling = TRUE, windowSize = 10, maxHorizon = 2)
Subset time series with provided indices
Description
Use provided indices to subset a time series. The provided indices must be contiguous
Usage
tsSubsetWithIndices(x, indices)
Arguments
x |
A time series object |
indices |
A contiguous vector of indices to use for subsetting |
Value
A time series object appropriately subsetted using provided indices
Author(s)
Ganesh Krishnan
Examples
tsSubsetWithIndices(AirPassengers, c(3:10))
Helper function used to unpack the fitted model objects from a list
Description
Helper function used to unpack the fitted model objects from a list
Usage
unwrapParallelModels(fitModels, expandedModels)
Arguments
fitModels |
A list containing the models to include in the ensemble |
expandedModels |
A character vector from the |
Details
See usage inside the hybridModel
function.