Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions _quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,19 @@ website:
contents:
- lessons/R-time-series-modeling/material.qmd
- lessons/R-time-series-modeling/r_tutorial.qmd
- lessons/R-time-series-modeling/equation_review.qmd
- section: 'R: Time series modeling 2'
href: lessons/R-time-series-modeling-2/index.qmd
contents:
- lessons/R-time-series-modeling-2/material.qmd
- lessons/R-time-series-modeling-2/r_tutorial.qmd
- lessons/R-time-series-modeling-2/equation_review.qmd
- section: 'R: Time series modeling 3'
href: lessons/R-time-series-modeling-3/index.qmd
contents:
- lessons/R-time-series-modeling-3/material.qmd
- lessons/R-time-series-modeling-3/r_tutorial.qmd
- lessons/R-time-series-modeling-3/equation_review.qmd
- section: Intro to Ecological Forecasting
href: lessons/intro-to-forecasting/index.qmd
contents:
Expand Down Expand Up @@ -229,11 +232,13 @@ website:
contents:
- lessons/R-complex-time-series-models-1/material.qmd
- lessons/R-complex-time-series-models-1/r_tutorial.qmd
- lessons/R-complex-time-series-models-1/equation_review.qmd
- section: 'R: Complex Time-Series Models 2'
href: lessons/R-complex-time-series-models-2/index.qmd
contents:
- lessons/R-complex-time-series-models-2/material.qmd
- lessons/R-complex-time-series-models-2/r_tutorial.qmd
- lessons/R-complex-time-series-models-2/equation_review.qmd
- section: 'R: State Space Models 1'
href: lessons/R-state-space-models-1/index.qmd
contents:
Expand Down
71 changes: 71 additions & 0 deletions lessons/R-complex-time-series-models-1/equation_review.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: Annotated Equations
order: 4
---

A quick reference for the models introduced in the [R Tutorial](r_tutorial.qmd). Each equation is broken down term by term so you can check your understanding of what every symbol is doing.

## Baseline model: AR + covariate + Gaussian error

The starting point in `mvgam` looks like the ARIMAX models from previous lessons — a covariate, an autoregressive term, and Gaussian error — just written and fit a different way (via `mvgam()`'s Bayesian MCMC fitting, instead of `fable`'s `ARIMA()`).

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#319795}{\beta_1 x_{1,t}}}_{\textstyle\color{#319795}{\text{covariate}}}
\;+\; \underbrace{\color{#c05621}{\beta_2 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
\;+\; \underbrace{\color{#718096}{\mathcal{N}(0,\sigma^2)}}_{\textstyle\color{#718096}{\text{Gaussian noise}}}
$$

- $y_t$ — the observed value at time $t$ (e.g., desert pocket mouse abundance)
- $c$ — a constant
- $\beta_1 x_{1,t}$ — the covariate effect (e.g., minimum temperature)
- $\beta_2 y_{t-1}$ — the AR part: the effect of the previous value
- $\mathcal{N}(0,\sigma^2)$ — Gaussian noise with mean 0 and variance $\sigma^2$

**How it's fit:** `mvgam` uses Bayesian methods (MCMC via STAN) rather than the exact-likelihood approach `fable` uses, but for this baseline model the equation itself is the same idea — the AR term is specified separately, via `trend_model = AR(p = 1)`, rather than inside the model formula.

## The same model, decomposed

The additive form above can equivalently be written as an explicit observation distribution around a modeled mean — a small notational shift that matters once we start changing the error distribution.

$$
y_t = \mathcal{N}(
\underbrace{\color{#d53f8c}{\mu_t}}_{\textstyle\color{#d53f8c}{\text{process mean}}},\sigma^2
)
$$

$$
\color{#d53f8c}{\mu_t} = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#319795}{\beta_1 x_{1,t}}}_{\textstyle\color{#319795}{\text{covariate}}}
\;+\; \underbrace{\color{#c05621}{\beta_2 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
$$

- $y_t$ — the observed value at time $t$, drawn from a normal distribution
- $\mu_t$ — the process mean at time $t$: everything the model can explain
- $\sigma^2$ — the variance of the observation noise around that mean
- $c$, $\beta_1 x_{1,t}$, $\beta_2 y_{t-1}$ — exactly the same constant, covariate, and AR terms as the baseline model, just relocated into $\mu_t$

**Why bother rewriting it:** splitting "what generates $y_t$" ($\mathcal{N}(\mu_t, \sigma^2)$) from "what determines $\mu_t$" makes it straightforward to swap in a different observation distribution without changing how $\mu_t$ is modeled — which is exactly what happens next.

## Modeling count data: Poisson error

Abundance counts are non-negative integers, which a Gaussian error model doesn't respect. Swapping in a Poisson distribution fixes that.

$$
y_t = \mathrm{Pois}(
\underbrace{\color{#d53f8c}{\lambda_t}}_{\textstyle\color{#d53f8c}{\text{rate parameter}}}
)
$$

$$
\underbrace{\color{#d69e2e}{\log(\lambda_t)}}_{\textstyle\color{#d69e2e}{\text{log link}}} = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#319795}{\beta_1 x_{1,t}}}_{\textstyle\color{#319795}{\text{covariate}}}
\;+\; \underbrace{\color{#c05621}{\beta_2 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
$$

- $y_t$ — the observed value at time $t$, now constrained to non-negative integers
- $\lambda_t$ — the Poisson rate parameter: both the mean and the variance of the distribution, so it must be positive
- $\log(\lambda_t)$ — the log link: instead of modeling $\lambda_t$ directly, the model predicts $\log(\lambda_t)$, which can be any real number, then exponentiates it back — guaranteeing $\lambda_t$ stays positive
- $c$, $\beta_1 x_{1,t}$, $\beta_2 y_{t-1}$ — the same constant, covariate, and AR terms as before, now predicting $\log(\lambda_t)$ instead of $y_t$ directly

**A side effect of the log link:** because the model is linear on the log scale, the relationship between the covariate and the untransformed abundance becomes exponential — worth checking with `plot_predictions()` rather than assuming it looks like the linear relationship on the link scale.
1 change: 1 addition & 0 deletions lessons/R-complex-time-series-models-1/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ listing:
contents:
- material.qmd
- r_tutorial.qmd
- equation_review.qmd
type: table
fields:
- title
Expand Down
71 changes: 71 additions & 0 deletions lessons/R-complex-time-series-models-2/equation_review.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: Annotated Equations
order: 4
---

A quick reference for the models introduced in the [R Tutorial](r_tutorial.qmd). Each equation is broken down term by term so you can check your understanding of what every symbol is doing.

## Baseline model: AR + covariate + Gaussian error

The starting point in `mvgam` looks like the ARIMAX models from previous lessons — a covariate, an autoregressive term, and Gaussian error — just written and fit a different way (via `mvgam()`'s Bayesian MCMC fitting, instead of `fable`'s `ARIMA()`).

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#319795}{\beta_1 x_{1,t}}}_{\textstyle\color{#319795}{\text{covariate}}}
\;+\; \underbrace{\color{#c05621}{\beta_2 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
\;+\; \underbrace{\color{#718096}{\mathcal{N}(0,\sigma^2)}}_{\textstyle\color{#718096}{\text{Gaussian noise}}}
$$

- $y_t$ — the observed value at time $t$ (e.g., desert pocket mouse abundance)
- $c$ — a constant
- $\beta_1 x_{1,t}$ — the covariate effect (e.g., minimum temperature)
- $\beta_2 y_{t-1}$ — the AR part: the effect of the previous value
- $\mathcal{N}(0,\sigma^2)$ — Gaussian noise with mean 0 and variance $\sigma^2$

**How it's fit:** `mvgam` uses Bayesian methods (MCMC via STAN) rather than the exact-likelihood approach `fable` uses, but for this baseline model the equation itself is the same idea — the AR term is specified separately, via `trend_model = AR(p = 1)`, rather than inside the model formula.

## The same model, decomposed

The additive form above can equivalently be written as an explicit observation distribution around a modeled mean — a small notational shift that matters once we start changing the error distribution.

$$
y_t = \mathcal{N}(
\underbrace{\color{#d53f8c}{\mu_t}}_{\textstyle\color{#d53f8c}{\text{process mean}}},\sigma^2
)
$$

$$
\color{#d53f8c}{\mu_t} = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#319795}{\beta_1 x_{1,t}}}_{\textstyle\color{#319795}{\text{covariate}}}
\;+\; \underbrace{\color{#c05621}{\beta_2 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
$$

- $y_t$ — the observed value at time $t$, drawn from a normal distribution
- $\mu_t$ — the process mean at time $t$: everything the model can explain
- $\sigma^2$ — the variance of the observation noise around that mean
- $c$, $\beta_1 x_{1,t}$, $\beta_2 y_{t-1}$ — exactly the same constant, covariate, and AR terms as the baseline model, just relocated into $\mu_t$

**Why bother rewriting it:** splitting "what generates $y_t$" ($\mathcal{N}(\mu_t, \sigma^2)$) from "what determines $\mu_t$" makes it straightforward to swap in a different observation distribution without changing how $\mu_t$ is modeled — which is exactly what happens next.

## Modeling count data: Poisson error

Abundance counts are non-negative integers, which a Gaussian error model doesn't respect. Swapping in a Poisson distribution fixes that.

$$
y_t = \mathrm{Pois}(
\underbrace{\color{#d53f8c}{\lambda_t}}_{\textstyle\color{#d53f8c}{\text{rate parameter}}}
)
$$

$$
\underbrace{\color{#d69e2e}{\log(\lambda_t)}}_{\textstyle\color{#d69e2e}{\text{log link}}} = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#319795}{\beta_1 x_{1,t}}}_{\textstyle\color{#319795}{\text{covariate}}}
\;+\; \underbrace{\color{#c05621}{\beta_2 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
$$

- $y_t$ — the observed value at time $t$, now constrained to non-negative integers
- $\lambda_t$ — the Poisson rate parameter: both the mean and the variance of the distribution, so it must be positive
- $\log(\lambda_t)$ — the log link: instead of modeling $\lambda_t$ directly, the model predicts $\log(\lambda_t)$, which can be any real number, then exponentiates it back — guaranteeing $\lambda_t$ stays positive
- $c$, $\beta_1 x_{1,t}$, $\beta_2 y_{t-1}$ — the same constant, covariate, and AR terms as before, now predicting $\log(\lambda_t)$ instead of $y_t$ directly

**A side effect of the log link:** because the model is linear on the log scale, the relationship between the covariate and the untransformed abundance becomes exponential — worth checking with `plot_predictions()` rather than assuming it looks like the linear relationship on the link scale.
1 change: 1 addition & 0 deletions lessons/R-complex-time-series-models-2/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ listing:
contents:
- material.qmd
- r_tutorial.qmd
- equation_review.qmd
type: table
fields:
- title
Expand Down
118 changes: 118 additions & 0 deletions lessons/R-time-series-modeling-2/equation_review.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
title: Annotated Equations
order: 4
---

A quick reference for the models introduced in the [R Tutorial](r_tutorial.qmd).

## Moving average (MA) model

Instead of using past *values* like an AR model, an MA model uses past *errors* to predict the current observation.

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#7c3aed}{\theta_1 \epsilon_{t-1}}}_{\textstyle\color{#7c3aed}{\text{MA: lag-1}}}
\;+\; \underbrace{\color{#718096}{\epsilon_t}}_{\textstyle\color{#718096}{\text{random error}}}
$$

- $y_t$ — the observed value at time $t$
- $c$ — a constant, analogous to the intercept in a regression
- $\theta_1 \epsilon_{t-1}$ — the lag-1 MA effect: $\theta_1$ scales how much last time step's *error* (not value) carries over
- $\epsilon_t$ — random error at time $t$

**Reading the coefficient:** if $\theta_1 > 0$, an observation that came in above the mean last time step nudges this time step above the mean too. Positive MA components say an outlier tends to be followed by another outlier in the same direction — unlike an AR model, it's the *surprise*, not the *value*, that carries forward.

## ARMA model

AR and MA structure can both be present in the same time series — an ARMA model combines them.

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#c05621}{b_1 y_{t-1}}}_{\textstyle\color{#c05621}{\text{AR: lag-1}}}
\;+\; \underbrace{\color{#7c3aed}{\theta_1 \epsilon_{t-1}}}_{\textstyle\color{#7c3aed}{\text{MA: lag-1}}}
\;+\; \underbrace{\color{#718096}{\epsilon_t}}_{\textstyle\color{#718096}{\text{random error}}}
$$

- $y_t$ — the observed value at time $t$
- $c$ — a constant
- $b_1 y_{t-1}$ — the AR part: the effect of the previous *value*
- $\theta_1 \epsilon_{t-1}$ — the MA part: the effect of the previous *error*
- $\epsilon_t$ — random error at time $t$

## Differencing

ARIMA-family models assume the series is "stationary" — no overall trend. Differencing removes a trend by modeling the *change* from one time step to the next instead of the raw values.

$$
y_t' = \underbrace{\color{#38a169}{y_t}}_{\textstyle\color{#38a169}{\text{current value}}}
\;-\; \underbrace{\color{#92400e}{y_{t-1}}}_{\textstyle\color{#92400e}{\text{previous value}}}
$$

- $y_t'$ — the differenced series: how much the value changed since last time step
- $y_t$ — the current value
- $y_{t-1}$ — the previous value

**Why this matters:** once the data is differenced, the model is no longer fit to the raw values but to the *changes* between them, which removes a long-term trend before the AR/MA structure is estimated.

## A fitted example: MA(3)

Fitting `ARIMA()` with no structure specified can return a model like this one — a 3rd-order MA model with no differencing and no AR terms.

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{
\color{#7c3aed}{\theta_1 \epsilon_{t-1}}
\color{black}{\,+\,}
\color{#9333ea}{\theta_2 \epsilon_{t-2}}
\color{black}{\,+\,}
\color{#c026d3}{\theta_3 \epsilon_{t-3}}
}_{\textstyle\color{#9333ea}{\text{MA terms: lags 1-3}}}
\;+\; \underbrace{\color{#718096}{\epsilon_t}}_{\textstyle\color{#718096}{\text{random error}}}
$$

- $y_t$ — the observed value at time $t$
- $c$ — a constant
- $\theta_1 \epsilon_{t-1}$, $\theta_2 \epsilon_{t-2}$, $\theta_3 \epsilon_{t-3}$ — the MA(3) terms: this model uses the last three months' errors, shown in the `Coefficients` table as `ma1`, `ma2`, `ma3`
- $\epsilon_t$ — random error at time $t$

**Reading it:** if NDVI was above average over the last three months, this model expects it to be above average now too — consistent with the idea that a good year (an MA-style "outlier" in errors) tends to persist for a while.

## Seasonal AR term

ARIMA models can also capture a seasonal cycle directly, by using a lag equal to the length of one full cycle — here, 12 months.

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{\color{#dd6b20}{b_{12} y_{t-12}}}_{\textstyle\color{#dd6b20}{\text{seasonal effect (1 year back)}}}
$$

- $y_t$ — the observed value at time $t$
- $c$ — a constant
- $b_{12} y_{t-12}$ — the seasonal AR term: how strongly the value from exactly one year ago (`sar1` in the `Coefficients` table) predicts the current value

**Ecological connection:** it makes sense that greenness one year ago is informative — ecosystems are reliably greener in summer than winter, so "how green was it this time last year" is a good predictor of "how green is it now."

## Full seasonal ARIMA model

Like the MA(3) model above but with a seasonal AR term added.

$$
y_t = \underbrace{\color{#2b6cb0}{c}}_{\textstyle\color{#2b6cb0}{\text{constant}}}
\;+\; \underbrace{
\color{#7c3aed}{\theta_1 \epsilon_{t-1}}
\color{black}{\,+\,}
\color{#9333ea}{\theta_2 \epsilon_{t-2}}
\color{black}{\,+\,}
\color{#c026d3}{\theta_3 \epsilon_{t-3}}
}_{\textstyle\color{#9333ea}{\text{MA terms: lags 1-3}}}
\;+\; \underbrace{\color{#dd6b20}{b_{12} y_{t-12}}}_{\textstyle\color{#dd6b20}{\text{seasonal effect}}}
\;+\; \underbrace{\color{#718096}{\epsilon_t}}_{\textstyle\color{#718096}{\text{random error}}}
$$

- $y_t$ — the observed value at time $t$
- $c$ — a constant
- $\theta_1 \epsilon_{t-1}$, $\theta_2 \epsilon_{t-2}$, $\theta_3 \epsilon_{t-3}$ — the MA(3) terms from the last three months' errors
- $b_{12} y_{t-12}$ — the seasonal AR term from one year back
- $\epsilon_t$ — random error at time $t$

**Putting it together:** this model explains the current value using recent surprises (MA), last year's value (seasonal AR), and nothing else — no direct AR terms on the immediately preceding months were needed once the seasonal and MA structure were included.
1 change: 1 addition & 0 deletions lessons/R-time-series-modeling-2/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ listing:
contents:
- material.qmd
- r_tutorial.qmd
- equation_review.qmd
type: table
fields:
- title
Expand Down
Loading
Loading