--- title: "3. Priors" output: bookdown::html_document2: base_format: rmarkdown::html_vignette toc: true toc_depth: 2 number_sections: true pkgdown: as_is: true vignette: > %\VignetteIndexEntry{3. Priors} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, echo = TRUE, comment = "#>", fig.width = 7, fig.height = 1.5 ) ``` # Set-up ```{r setup} suppressPackageStartupMessages({ library(bage) library(poputils) library(ggplot2) library(dplyr) }) ``` ```{r} plot_exch <- function(draws) { ggplot(draws, aes(x = element, y = value)) + facet_wrap(vars(draw), nrow = 1) + geom_hline(yintercept = 0, col = "grey") + geom_point(col = "darkblue", size = 0.7) + scale_x_continuous(n.breaks = max(draws$element)) + xlab("Unit") + ylab("") + theme(text = element_text(size = 8)) } ``` ```{r} plot_cor_one <- function(draws) { ggplot(draws, aes(x = along, y = value)) + facet_wrap(vars(draw), nrow = 1) + geom_hline(yintercept = 0, col = "grey") + geom_line(col = "darkblue") + xlab("Unit") + ylab("") + theme(text = element_text(size = 8)) } ``` ```{r} plot_cor_many <- function(draws) { ggplot(draws, aes(x = along, y = value)) + facet_grid(vars(by), vars(draw)) + geom_hline(yintercept = 0, col = "grey") + geom_line(col = "darkblue") + xlab("Unit") + ylab("") + theme(text = element_text(size = 8)) } ``` ```{r} plot_svd_one <- function(draws) { ggplot(draws, aes(x = age_mid(age), y = value, color = sexgender)) + facet_wrap(vars(draw), nrow = 1) + geom_line() + scale_color_manual(values = c("darkgreen", "darkorange")) + xlab("Age") + ylab("") + theme(text = element_text(size = 8), legend.position = "top", legend.title = element_blank()) } ``` ```{r} plot_svd_many <- function(draws) { draws |> mutate(element = paste("Unit", element)) |> ggplot(aes(x = age_mid(age), y = value, color = sexgender)) + facet_grid(vars(element), vars(draw)) + geom_line() + scale_color_manual(values = c("darkgreen", "darkorange")) + xlab("Age") + ylab("") + theme(text = element_text(size = 8), legend.position = "top", legend.title = element_blank()) } ``` # Exchangeable Units ## Fixed Normal `NFix()` ### Model \begin{equation} \beta_j \sim \text{N}(0, \mathtt{sd}^2) \end{equation} ### All defaults `sd = 1` ```{r} set.seed(0) NFix() |> generate(n_element = 10, n_draw = 8) |> plot_exch() ``` ### Reduce `sd` `sd = 0.01` ```{r, fig.height = 1.5} set.seed(0) NFix(sd = 0.01) |> generate(n_element = 10, n_draw = 8) |> plot_exch() ``` ## Normal `N()` ### Model \begin{align} \beta_j & \sim \text{N}(0, \tau^2) \\ \tau & \sim \text{N}^+(0, \mathtt{s}) \end{align} ### All defaults `s = 1` ```{r} set.seed(0) N() |> generate(n_element = 10, n_draw = 8) |> plot_exch() ``` ### Reduce `s` `s = 0.01` ```{r, fig.height = 1.5} set.seed(0) N(s = 0.01) |> generate(n_element = 10, n_draw = 8) |> plot_exch() ``` # Units Correlated With Neighbours ## Random Walk `RW()` ### Model \begin{align} \beta_1 & \sim \text{N}(0, \mathtt{sd}^2) \\ \beta_j & \sim \text{N}(\beta_{j-1}, \tau^2), \quad j = 2, \cdots, J \\ \tau & \sim \text{N}^+(0, \mathtt{s}^2) \end{align} ### All defaults `s = 1`, `sd = 1` ```{r} set.seed(0) RW() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` `s = 0.01`, `sd = 1` ```{r} set.seed(0) RW(s = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` and `sd` `s = 0.01`, `sd = 0` ```{r} set.seed(0) RW(s = 0.01, sd = 0) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Second-Order Random Walk `RW2()` ### Model \begin{align} \beta_1 & \sim \text{N}(0, \mathtt{sd}^2) \\ \beta_2 & \sim \text{N}(\beta_1, \mathtt{sd\_slope}^2) \\ \beta_j & \sim \text{N}(2\beta_{j-1} - \beta_{j-2}, \tau^2), \quad j = 3, \cdots, J \\ \tau & \sim \text{N}^+(0, \mathtt{s}^2) \end{align} ### All defaults `s = 1`, `sd = 1`, `sd_slope = 1` ```{r} set.seed(0) RW2() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` `s = 0.01`, `sd = 1`, `sd_slope = 1` ```{r} set.seed(0) RW2(s = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` and `sd_slope` `s = 0.01`, `sd = 1`, `sd_slope = 0.01` ```{r} set.seed(0) RW2(s = 0.01, sd_slope = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s`, `sd`, and `sd_slope` `s = 0.01`, `sd = 0`, `sd_slope = 0.01` ```{r} set.seed(0) RW2(s = 0.01, sd = 0, sd_slope = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Autoregressive `AR()` ### Model \begin{equation} \beta_j \sim \text{N}\left(\phi_1 \beta_{j-1} + \cdots + \phi_{\mathtt{n\_coef}} \beta_{j-\mathtt{n\_coef}}, \omega^2\right) \end{equation} TMB derives a value of $\omega$ that gives each $\beta_j$ variance $\tau^2$. The prior for $\tau$ is \begin{equation} \tau \sim \text{N}^+(0, \mathtt{s}^2). \end{equation} The prior for each $\phi_k$ is \begin{equation} \frac{\phi_k + 1}{2} \sim \text{Beta}(\mathtt{shape1}, \mathtt{shape2}). \end{equation} ### All defaults `n_coef = 2`, `s = 1` ```{r} set.seed(0) AR() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Increase `n_coef` ```{r} set.seed(0) AR(n_coef = 3) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` ```{r} set.seed(0) AR(s = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Specify 'along' and 'by' dimensions ```{r, fig.height = 4.5} set.seed(0) AR() |> generate(n_along = 20, n_by = 3, n_draw = 8) |> plot_cor_many() ``` ### Specify 'along' and 'by' dimensions, set `con = "by"` ```{r, fig.height = 4.5} set.seed(0) AR(con = "by") |> generate(n_along = 20, n_by = 3, n_draw = 8) |> plot_cor_many() ``` ## First-Order Autoregressive `AR1()` ### Model \begin{equation} \beta_j \sim \text{N}\left(\phi \beta_{j-1}, \omega^2\right) \end{equation} TMB derives a value of $\omega$ that gives each $\beta_j$ variance $\tau^2$. The prior for $\tau$ is \begin{equation} \tau \sim \text{N}^+(0, \mathtt{s}^2). \end{equation} The prior for $\phi$ is \begin{equation} \frac{\phi - \mathtt{min}}{\mathtt{max} - \mathtt{min}} \sim \text{Beta}(\mathtt{shape1}, \mathtt{shape2}). \end{equation} ### All defaults `s = 1`, `min = 0.8`, `max = 0.98` ```{r} set.seed(0) AR1() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` ```{r} set.seed(0) AR1(s = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` and modify `min`, `max` ```{r} set.seed(0) AR1(s = 0.01, min = -1, max = 1) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Random Walk with Seasonal Effects `RW_Seas()` ### Model \begin{align} \beta_j & = \alpha_j + \lambda_j \\ \alpha_1 & \sim \text{N}(0, \mathtt{sd}^2) \\ \alpha_j & \sim \text{N}(\alpha_{j-1}, \tau^2), \quad j = 2, \cdots, J \\ \tau & \sim \text{N}^+\left(0, \mathtt{s}^2\right) \\ \lambda_j & \sim \text{N}(0, \mathtt{sd\_seas}^2), \quad j = 1, \cdots, \mathtt{n\_seas} - 1 \\ \lambda_j & = -\sum_{s=1}^{j-1} \lambda_{j-s}, \quad j = \mathtt{n\_seas},\; 2 \mathtt{n\_seas}, \cdots \\ \lambda_j & \sim \text{N}(\lambda_{j-\mathtt{n\_seas}}, \omega^2), \quad \text{otherwise} \\ \omega & \sim \text{N}^+\left(0, \mathtt{s\_seas}^2\right) \end{align} ### All defaults `s = 1`, `sd = 1`, `s_seas = 0`, `sd_seas = 1` ```{r} set.seed(0) RW_Seas(n_seas = 4) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s`, `sd` `s = 0.01`, `sd = 0`, `s_seas = 0`, `sd_seas = 1` ```{r} set.seed(0) RW_Seas(n_seas = 4, s = 0.01, sd = 0) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Increase `s_seas` `s = 0.01`, `sd = 0`, `s_seas = 1`, `sd_seas = 1` ```{r} set.seed(0) RW_Seas(n_seas = 4, s = 0.01, sd = 0, s_seas = 1) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `sd_seas` `s = 0.01`, `sd = 0`, `s_seas = 1`, `s_seas = 0`, `sd_seas = 0.01` ```{r} set.seed(0) RW_Seas(n_seas = 4, s = 0.01, sd = 0, sd_seas = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Second-Order Random Walk with Seasonal Effects `RW2_Seas()` ### Model \begin{align} \beta_j & = \alpha_j + \lambda_j \\ \alpha_1 & \sim \text{N}(0, \mathtt{sd}^2) \\ \alpha_2 & \sim \text{N}(\alpha_1, \mathtt{sd\_slope}^2) \\ \alpha_j & \sim \text{N}(2\alpha_{j-1} - \alpha_{j-2}, \tau^2), \quad j = 3, \cdots, J \\ \tau & \sim \text{N}^+\left(0, \mathtt{s}^2\right) \\ \lambda_j & \sim \text{N}(0, \mathtt{sd\_seas}^2), \quad j = 1, \cdots, \mathtt{n\_seas} - 1 \\ \lambda_j & = -\sum_{s=1}^{j-1} \lambda_{j-s}, \quad j = \mathtt{n\_seas},\; 2 \mathtt{n\_seas}, \cdots \\ \lambda_j & \sim \text{N}(\lambda_{j-\mathtt{n\_seas}}, \omega^2), \quad \text{otherwise} \\ \omega & \sim \text{N}^+\left(0, \mathtt{s\_seas}^2\right) \end{align} ### All defaults `s = 1`, `sd = 1`, `sd_slope = 1`, `s_seas = 0`, `sd_seas = 1` ```{r} set.seed(0) RW2_Seas(n_seas = 4) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s`, `sd`, `sd_slope`, `sd_seas` `s = 0.01`, `sd = 0`, `sd_slope = 0.01`, `s_seas = 0`, `sd_seas = 0.01` ```{r} set.seed(0) RW2_Seas(n_seas = 4, s = 0.01, sd = 0, sd_slope = 0.01, sd_seas = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Linear `Lin()` ### Model \begin{align} \beta_j & = \alpha_j + \epsilon_j \\ \alpha_j & = \left(j - \frac{J + 1}{2}\right) \eta \\ \eta & \sim \text{N}\left(\mathtt{mean\_slope}, \mathtt{sd\_slope}^2 \right) \\ \epsilon & \sim \text{N}(0, \tau^2) \\ \tau & \sim \text{N}^+\left(0, \mathtt{s}^2\right) \end{align} ### All defaults `s = 1`, `mean_slope = 0`, `sd_slope = 1` ```{r} set.seed(0) Lin() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s` `s = 0`, `mean_slope = 0`, `sd_slope = 1` ```{r} set.seed(0) Lin(s = 0) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Modify `mean_slope`, `sd_slope` `s = 1`, `mean_slope = 0.2`, `sd_slope = 0.1` ```{r} set.seed(0) Lin(mean_slope = 0.2, sd_slope = 0.1) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Specify 'along' and 'by' dimensions ```{r, fig.height = 4.5} set.seed(0) Lin() |> generate(n_along = 20, n_by = 3, n_draw = 8) |> plot_cor_many() ``` ### Specify 'along' and 'by' dimensions, set `con = "by"` ```{r, fig.height = 4.5} set.seed(0) Lin(con = "by") |> generate(n_along = 20, n_by = 3, n_draw = 8) |> plot_cor_many() ``` ## Linear with AR Errors `Lin_AR()` ### Model \begin{align} \beta_j & = \alpha_j + \epsilon_j \\ \alpha_j & = \left(j - \frac{J + 1}{2}\right) \eta \\ \eta & \sim \text{N}\left(\mathtt{mean\_slope}, \mathtt{sd\_slope}^2 \right) \\ \epsilon_j & \sim \text{N}\left(\phi_1 \epsilon_{j-1} + \cdots + \phi_{\mathtt{n\_coef}} \epsilon_{j-\mathtt{n\_coef}}, \omega^2\right) \tau & \sim \text{N}^+\left(0, \mathtt{s}^2\right) \\ \frac{\phi_k + 1}{2} & \sim \text{Beta}(\mathtt{shape1}, \mathtt{shape2}) \end{align} ### All defaults `n_coef = 2`, `s = 1`, `mean_slope = 0`, `sd_slope = 1` ```{r} set.seed(0) Lin_AR() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s`, `sd_slope` `s = 0.1`, `mean_slope = 0`, `sd_slope = 0.01` ```{r} set.seed(0) Lin_AR(s = 0.1, sd_slope = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Linear with AR1 Errors `Lin_AR1()` ### Model \begin{align} \beta_j & = \alpha_j + \epsilon_j \\ \alpha_j & = \left(j - \frac{J + 1}{2}\right) \eta \\ \eta & \sim \text{N}\left(\mathtt{mean\_slope}, \mathtt{sd\_slope}^2 \right) \\ \epsilon_j & \sim \text{N}\left(\phi \epsilon_{j-1}, \omega^2\right) \tau & \sim \text{N}^+\left(0, \mathtt{s}^2\right) \\ \frac{\phi - \mathtt{min}}{\mathtt{max} - \mathtt{min}} \sim \text{Beta}(\mathtt{shape1}, \mathtt{shape2}) \end{align} ### All defaults `s = 1`, `min = 0.8`, `max = 0.98`, `mean_slope = 0`, `sd_slope = 1` ```{r} set.seed(0) Lin_AR1() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Modify `min`, `max` `s = 1`, `min = -1`, `max = 1`, `mean_slope = 0`, `sd_slope = 1` ```{r} set.seed(0) Lin_AR1(min = -1, max = 1) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s`, `sd_slope` `s = 0.1`, `min = 0.8`, `max = 0.98`, `mean_slope = 0`, `sd_slope = 0.02` ```{r} set.seed(0) Lin_AR1(s = 0.1, sd_slope = 0.02) |> generate(n_draw = 8) |> plot_cor_one() ``` ## Penalised Spline `Sp()` ### Model \begin{align} \pmb{\beta} & = \bm{X} \pmb{\alpha} \\ \alpha_1 & \sim \text{N}(0, \mathtt{sd}^2) \\ \alpha_2 & \sim \text{N}(\alpha_1, \mathtt{sd\_slope}^2) \\ \alpha_j & \sim \text{N}(2\alpha_{j-1} - \alpha_{j-2}, \tau^2), \quad j = 3, \cdots, J \\ \tau & \sim \text{N}^+\left(0, \mathtt{s}^2\right) \\ \end{align} ### All defaults `n_comp = NULL`, `s = 1`, `sd = 1`, `sd_slope = 1` ```{r} set.seed(0) Sp() |> generate(n_draw = 8) |> plot_cor_one() ``` ### Specify `n_comp` `n_comp = 15`, `s = 1`, `sd = 1`, `sd_slope = 1` ```{r} set.seed(0) Sp(n_comp = 5) |> generate(n_draw = 8) |> plot_cor_one() ``` ### Reduce `s`, `sd`, `sd_slope` `n_comp = NULL`, `s = 0.01`, `sd = 0.01`, `sd_slope = 0.01` ```{r} set.seed(0) Sp(s = 0.01, sd = 0.01, sd_slope = 0.01) |> generate(n_draw = 8) |> plot_cor_one() ``` # SVD-Based Priors ## Exchangeable `SVD()` ### Model \begin{equation} \pmb{\beta} = \pmb{F} \pmb{\alpha} + \pmb{g} \end{equation} ### All defaults `n_comp = NULL`, `indep = TRUE` ```{r, fig.height = 3} set.seed(0) SVD(HMD) |> generate(n_draw = 8) |> plot_svd_one() ``` ### Increase `n_comp` `n_comp = 5`, `indep = TRUE` ```{r, fig.height = 2} SVD(HMD, n_comp = 5) |> generate(n_draw = 8) |> plot_svd_one() ``` ### Set `indep` to `FALSE` ```{r, fig.height = 2} SVD(HMD, indep = FALSE) |> generate(n_draw = 8) |> plot_svd_one() ``` ### Multiple units ```{r, fig.height = 4.5} SVD(HMD, indep = FALSE) |> generate(n_draw = 8, n_element = 3) |> plot_svd_many() ``` ## Dynamic SVD Prior: `SVD_AR()` ```{r, fig.height = 8} SVD_AR(HMD, indep = FALSE, s = 0.1) |> generate(n_draw = 6, n_along = 5) |> ggplot(aes(x = age_mid(age), y = value, color = sexgender)) + facet_grid(vars(draw), vars(along)) + geom_line() + scale_color_manual(values = c("darkgreen", "darkorange")) + xlab("Age") + ylab("") + theme(text = element_text(size = 8), legend.position = "top", legend.title = element_blank()) ```