knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "README-" )
This is a work-in-progress package to fit a variety of multivariate timeseries models. At present, vector exponential smoothing models, univariate ensemble models and multivariate random forest modes are supported. All models can be reconciled using temporal hierarchies. These methods are established in the forecasting field but are little used or known by ecologists.
You can install the development version from GitHub
using:
install.packages("devtools") devtools::install_github("nicholasjclark/mvforecast")
You can test the package's main functionality with the test_mvforecast
function, which fits a multivariate exponential smoothing model to the NEON Ixodes scapularis survey timeseries that are used in the Ecological Forecasting Initiative's 2021 Forecast Challenge. Using thief_vets
, the function then fits an equivalent model to the original series but also uses automatic univariate forecast models applied to all higher levels of temporal aggregation to gain information about long-term trends and seasonalities that would otherwise be missed when focusing only on the noisy original data. thief_vets
uses these aggregate forecasts to reconcile the original forecast by relying on functions available in the thief
package. Finally, the sum of the Continuous Rank Probability Score (CRPS) is calculated for both models against the out-of-sample test set, where a lower score is better.
library(mvforecast) test_mvforecast()
We can explore how the different models produce forecast distributions by fitting each and plotting the resulting forecasts for a single plot
mod1 <- suppressWarnings(thief_rfsrc(y = ixodes_vets_dat$y_train, frequency = 52, k = 1)) mod2 <- suppressWarnings(thief_ensemble(y = ixodes_vets_dat$y_train, frequency = 52, k = 1)) mod3 <- suppressWarnings(thief_vets(y = ixodes_vets_dat$y_train, multi_freq = 24, level = "grouped", slope = "none", damped = "none", seasonal = "common", lambda = 0.75, dependence = "equicorrelation", frequency = 52, cores = 6, group = ixodes_vets_dat$groups, save_plots = F))
site = 3 plot_mvforecast(simulation = mod1[[site]], main = 'thief_rfsrc') points(as.vector(ixodes_vets_dat$y_test[,site]), col = 'black', pch = 16)
plot_mvforecast(simulation = mod2[[site]], main = 'thief_ensemble') points(as.vector(ixodes_vets_dat$y_test[,site]), col = 'black', pch = 16)
plot_mvforecast(simulation = mod3[[site]], main = 'thief_vets') points(as.vector(ixodes_vets_dat$y_test[,site]), col = 'black', pch = 16)
Comparison of the CRPS is straightforward
calc_crps(mod1, y_test = ixodes_vets_dat$y_test) calc_crps(mod2, y_test = ixodes_vets_dat$y_test) calc_crps(mod3, y_test = ixodes_vets_dat$y_test)
Reconciliation is clearly a powerful technique that can drastically improve forecasts for many types of time series. In the interest of transparency and robust software engineering, a Docker
container has been built to ensure functions in this package can be used in future if dependencies make any drastic changes. You can install the container from Dockerhub
. For example, using singularity
this would read as:
singularity pull docker://nicholasjclark/brms singularity shell brms_latest.sif R
Interested users can create their own containers to add further functionality or add additional libraries. The entire Dockerfile
reads as:
FROM lcolling/r-verse-base:latest # Use clang to compile Stan # Using the default g++ causes memory issues RUN apt-get update \ && apt-get install -y --no-install-recommends \ clang RUN apt-get install -y --no-install-recommends libudunits2-dev RUN apt-get install -y --no-install-recommends libgdal-dev RUN apt-get update && apt-get install -y --no-install-recommends libv8-dev RUN apt-get clean \ && rm -rf /var/lib/apt/lists/* # Create a makevars file and then install rstan from source # following the instructions at https://github.com/stan-dev/rstan/wiki/Installing-RStan-on-Linux # Install remaining R packages using specific versions (latest as of February 2021, or by indexing specific commits on Github) RUN R -e "options(repos = \ list(CRAN = 'https://mran.revolutionanalytics.com/snapshot/2021-02-01/')); \ dotR <- file.path(Sys.getenv('HOME'), '.R'); \ if (!file.exists(dotR)) dir.create(dotR); \ M <- file.path(dotR, 'Makevars'); \ if (!file.exists(M)) file.create(M); \ cat('\nCXX14FLAGS=-O3 -march=native -mtune=native -fPIC', \ 'CXX14=clang++', \ file = M, sep = '\n', append = TRUE); \ install.packages('rstan', type = 'source'); \ install.packages('remotes'); \ install.packages('brms'); \ install.packages('here'); \ install.packages('tidybayes'); \ install.packages('xfun'); \ install.packages('mgcv'); \ install.packages('prophet'); \ install.packages('pbapply'); \ install.packages('ggplot2'); \ install.packages('viridis'); \ install.packages('reshape'); \ remotes::install_github('tsmodels/tsmethods@16601e3bd21d7293490d820137324e4f16462dbf', dependencies = TRUE); \ remotes::install_github('tsmodels/tsaux@da46a751c619ba10184f0749ccd7d9fb9a7be31f', dependencies = TRUE); \ remotes::install_github('tsmodels/tsets@51a26d80fdfafc41d564d08a38fe4c9776ba333f', dependencies = TRUE); \ remotes::install_github('tsmodels/tsvets@7bea965911ddee0c585199cb380b1299e341273b', dependencies = TRUE); \ remotes::install_github('nicholasjclark/mvforecast', dependencies = TRUE); \ remotes::install_github('asael697/varstan@5378f428cad9560dae7f6daf8f431113f19a2019', dependencies = TRUE)" CMD [ "R" ]
This project is licensed under the terms of the GNU General Public License (GNU GPLv3)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.