---
title: "Prediction intervals for multivariate time series (simulation-based)"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Prediction intervals for multivariate time series (simulation-based)}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

`ahead` is a package for **univariate** and **multivariate time series forecasting**, with uncertainty quantification (R and [Python](https://techtonique.github.io/ahead_python/)).

The model used in this demo is the one presented in [this paper](https://www.mdpi.com/2227-9091/6/1/22), and has actually been significantly improved since 2018, as you'll see here. 

Currently for this model (as of 2023-08-28), for **uncertainty quantification**, I have:

-   Gaussian distribution
-   Independent **bootstrap** simulation 
-   Multivariate circular **block bootstrap** simulation 
-   Multivariate moving block bootstrap simulation 
-   Copula simulation 
-   **More options to come** in the future.

Please remember that _in real life_, this model's hyperparameters will have to be tuned.

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

**Contents:**

-   0 - Install `ahead`
-   1 - Prediction intervals based on **Gaussian** distribution (meh, but quick)
-   2 - Prediction intervals based on **independent bootstrap**
-   3 - Prediction intervals based on **block bootstrap**
-   4 - Prediction intervals based on moving block bootstrap
-   5 - Prediction intervals based on R-Vine copula simulation

# 0 - Install `ahead`

Here's how to install the R version of the package:

-   **1st method**: from [R-universe](https://techtonique.r-universe.dev)

    In R console:

    ``` r
    options(repos = c(
        techtonique = 'https://techtonique.r-universe.dev',
        CRAN = 'https://cloud.r-project.org'))

    install.packages("ahead")
    ```

-   **2nd method**: from [Github](https://github.com/Techtonique/ahead)

    In R console:

    ``` r
    devtools::install_github("Techtonique/ahead")
    ```

    Or

    ``` r
    remotes::install_github("Techtonique/ahead")
    ```

And here are the packages that will be used in this vignette:

```{r include=FALSE}
library(ahead)
library(fpp)
```

``` r
library(ahead)
library(fpp)
```

# 1 - Prediction intervals based on Gaussian distribution (meh, but quick)

## 1 - 1 With default parameters

```{r "gaussian-default", fig.width=7.2}
h <- 10L # forecasting horizon

(res1 <- ahead::ridge2f(fpp::insurance, h = h))

print(summary(res1$residuals))

print(apply(res1$residuals, 2, function (x) Box.test(x)$p.value)) # stationarity is overrated?:)

print(apply(res1$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res1, "Quotes")
plot(res1, "TV.advert")
```

## 1 - 2 With external regressors

```{r "gaussian-xreg", fig.width=7.2}
xreg <- as.numeric(time(fpp::insurance))
(res2 <- ahead::ridge2f(fpp::insurance, xreg = xreg, h = h))

print(summary(res2$residuals))

print(apply(res2$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res2$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res2, "Quotes")
plot(res2, "TV.advert")
```

## 1 - 3 With external regressors and K-Means clustering

```{r, "gaussian-xreg-kmeans", fig.width=7.2}
centers <- 2L
(res3 <- ahead::ridge2f(fpp::insurance, xreg = xreg, centers = centers, h = h))

print(summary(res3$residuals))

print(apply(res3$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res3$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res3, "Quotes")
plot(res3, "TV.advert")
```

## 1 - 4 With K-Means clustering

```{r, "gaussian-kmeans", fig.width=7.2}
centers <- 2L
(res10 <- ahead::ridge2f(fpp::insurance, centers = centers, h = h))

print(summary(res10$residuals))

print(apply(res10$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res10$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res10, "Quotes")
plot(res10, "TV.advert")
```

# 2 - Prediction intervals based on independent bootstrap

## 2 - 1 With default parameters

```{r "bootstrap-default", fig.width=7.2}
B <- 10L # number of bootstrap replications -- increase this
(res4 <- ahead::ridge2f(fpp::insurance, 
                        type_pi = "bootstrap", B = B, h = h))

print(summary(res4$residuals))

print(apply(res4$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res4$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res4, "Quotes")
plot(res4, "TV.advert")
```

## 2 - 2 With external regressors

```{r "bootstrap-xreg", fig.width=7.2}
(res5 <- ahead::ridge2f(fpp::insurance, xreg = xreg, 
                        type_pi = "bootstrap", B = B, h = h))

print(summary(res5$residuals))

print(apply(res5$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res5$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res5, "Quotes")
plot(res5, "TV.advert")
```

## 2 - 3 With external regressors and K-Means clustering

```{r "bootstrap-xreg-clustering", fig.width=7.2}
(res6 <- ahead::ridge2f(fpp::insurance, xreg = xreg, 
                        centers = centers, 
                        type_pi = "bootstrap", B = B, h = h))

print(summary(res6$residuals))

print(apply(res6$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res6$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res6, "Quotes")
plot(res6, "TV.advert")
```

## 2 - 4 With K-Means clustering

```{r, "bootstrap-kmeans", fig.width=7.2}
centers <- 2L
(res11 <- ahead::ridge2f(fpp::insurance, 
                         centers = centers, 
                         type_pi = "bootstrap", B = B, h = h))

print(summary(res11$residuals))

print(apply(res11$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res11$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res11, "Quotes")
plot(res11, "TV.advert")
```

# 3 - Prediction intervals based on block bootstrap

## 3 - 1 With default parameters

```{r "blockbootstrap-default", fig.width=7.2}
block_length <- 5L
(res7 <- ahead::ridge2f(fpp::insurance, 
                        type_pi = "blockbootstrap", 
                        block_length = block_length,
                        B = B, h = h))

print(summary(res7$residuals))

print(apply(res7$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res7$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res7, "Quotes")
plot(res7, "TV.advert")
```

## 3 - 2 With external regressors

```{r "blockbootstrap-xreg", fig.width=7.2}
(res8 <- ahead::ridge2f(fpp::insurance, xreg = xreg, 
                        type_pi = "blockbootstrap", 
                        block_length = block_length,
                        B = B, h = h))

print(summary(res8$residuals))

print(apply(res8$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res8$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res8, "Quotes")
plot(res8, "TV.advert")
```

## 3 - 3 With external regressors and K-Means clustering

```{r blockbootstrap-xreg-clustering, fig.width=7.2}
(res9 <- ahead::ridge2f(fpp::insurance, 
                        xreg = xreg, centers = centers, 
                        type_pi = "blockbootstrap", 
                        block_length = block_length,
                        B = B, h = h))

print(summary(res9$residuals))

print(apply(res9$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res9$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res9, "Quotes")
plot(res9, "TV.advert")
```

## 3 - 4 With K-Means clustering

```{r, "blockbootstrap-kmeans", fig.width=7.2}
(res12 <- ahead::ridge2f(fpp::insurance, 
                         centers = centers, 
                         type_pi = "blockbootstrap", 
                         block_length = block_length,
                         B = B, h = h))

print(summary(res12$residuals))

print(apply(res12$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res12$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res12, "Quotes")
plot(res12, "TV.advert")
```

## 3 - 5 Using the median instead of the mean in bootstrap aggregation

```{r, "blockbootstrap-median-kmeans", fig.width=7.2}
(res13 <- ahead::ridge2f(fpp::insurance, 
                         centers = centers, 
                         type_pi = "blockbootstrap", 
                         type_aggregation = "median",
                         block_length = block_length,
                         B = B, h = h))

print(apply(res13$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

print(summary(res13$residuals))

print(apply(res13$residuals, 2, function (x) Box.test(x)$p.value))

plot(res13, "Quotes")
plot(res13, "TV.advert")
```


# 4 - Prediction intervals based on moving block bootstrap

## 4 - 1 With default parameters

```{r "movingblockbootstrap-default", fig.width=7.2}
block_length <- 5L
(res16 <- ahead::ridge2f(fpp::insurance, 
                        type_pi = "movingblockbootstrap", 
                        block_length = block_length,
                        B = B, h = h))

print(summary(res16$residuals))

print(apply(res16$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res16$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res16, "Quotes", type = "sims")
plot(res16, "TV.advert")
```

## 4 - 2 With external regressors

```{r "movingblockbootstrap-xreg", fig.width=7.2}
(res8 <- ahead::ridge2f(fpp::insurance, xreg = xreg, 
                        type_pi = "movingblockbootstrap", 
                        block_length = block_length,
                        B = B, h = h))

print(summary(res8$residuals))

print(apply(res8$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res8$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res8, "Quotes")
plot(res8, "TV.advert", type = "dist")
```

## 4 - 3 With external regressors and K-Means clustering

```{r "movingblockbootstrap-xreg-clustering", fig.width=7.2}
(res15 <- ahead::ridge2f(fpp::insurance, 
                        xreg = xreg, centers = centers, 
                        type_pi = "movingblockbootstrap", 
                        block_length = block_length,
                        B = B, h = h))

print(summary(res15$residuals))

print(apply(res15$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res15$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res15, "Quotes", type = "dist")
plot(res15, "TV.advert")
```

## 4 - 4 With K-Means clustering

```{r, "movingblockbootstrap-kmeans", fig.width=7.2}
(res12 <- ahead::ridge2f(fpp::insurance, 
                         centers = centers, 
                         type_pi = "movingblockbootstrap", 
                         block_length = block_length,
                         B = B, h = h))

print(summary(res12$residuals))

print(apply(res12$residuals, 2, function (x) Box.test(x)$p.value))

print(apply(res12$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

plot(res12, "Quotes")
plot(res12, "TV.advert", type = "sims")
```

## 4 - 5 Using the median instead of the mean in bootstrap aggregation

```{r, "movingblockbootstrap-median-kmeans", fig.width=7.2}
(res14 <- ahead::ridge2f(fpp::insurance, 
                         centers = centers, 
                         type_pi = "movingblockbootstrap", 
                         type_aggregation = "median",
                         block_length = block_length,
                         B = B, h = h))

print(apply(res14$residuals, 2, function (x) shapiro.test(x)$p.value)) # Gaussian?

print(summary(res14$residuals))

print(apply(res14$residuals, 2, function (x) Box.test(x)$p.value))

plot(res14, "Quotes", type = "dist")
plot(res14, "TV.advert")
```


# 5 - Prediction intervals based on R-Vine copula simulation

```{r, "RVineCopula", fig.width=7.2}
(obj <- ahead::ridge2f(fpp::insurance, 
                         type_pi = "rvinecopula", 
                         B = B, h = h))


plot(obj, "Quotes", type = "dist")
plot(obj, "TV.advert", type = "sims")
```

