This module contains the update algorithm for a DGLM. After observing a new value $y_t$, updating incorporates the new information into the DGLM coefficients. It also applies the discount factors to reduce the impact of older information. For any model `mod`, the correct method usage is `mod.update(y, X)`.

Updating occurs after observing a new value, $y_t$. The update function accepts $y_t$ and the predictors $X_t$. It will update the state vector from $\theta_t$ into $\theta_{t+1}$, producing the new mean $a_{t+1}$ and variance matrix $R_{t+1}$. In a normal DLM, the updating also impacts the mean of the observation variance, $s_{t+1}$. The coefficients can be accessed with mod.get_coef, or more directly as mod.a, mod.R, and for a normal DLM, mod.s.

To give the more formal Bayesian interpretation of these steps:

  • At time $t$, we know the prior moments of the state vector $\theta_t | \mathcal{D_t} \sim [a_t, R_t]$, where $\mathcal{D_t}$ is all of the observations up to time $t$.
  • We then observe $y_t$, and incorporate the new information to give the posterior: $\theta_t | \mathcal{D_t}, y_t \sim [m_t, C_t]$.
  • Finally, we discount the old information, to give us our new priors for the next time step: $\theta_{t+1} | \mathcal{D_{t+1}} \sim [a_{t+1}, R_{t+1}]$.

If you are interested in the posterior moments of $\theta_t | \mathcal{D_t}, y_t$ before the discounting is applied, then you can access mod.m and mod.C, although these are rarely used.

Again, these functions do not need to be accessed independently from a model. Every model in PyBATS has a mod.update(y, X) method, which will call the appropriate update function.

Update Functions


update(mod, y=None, X=None)

This update method works for Poisson and Bernoulli DGLMs. Below are very simple tests which:

  • Manually define a DGLM with an intercept and 2 regression predictors
  • Define a new $y_t, X_t$
  • Update the model, given $y_t, X_t$
  • Check that the posterior mean $a_t$ and variance $R_t$ of the state vector is correct
import numpy as np
from pybats.dglm import dlm, pois_dglm, bern_dglm, bin_dglm
from pybats.analysis import analysis

a0 = np.array([1, 1, 1])
R0 = np.eye(3)
mod_p = pois_dglm(a0, R0, ntrend=1, nregn=2, deltrend=1, delregn=.9)
mod_bern = bern_dglm(a0, R0, ntrend=1, nregn=2, deltrend=1, delregn=.9)

# New data:
y = 5
X = np.array([1,2])

# Test the Poisson DGLM
mod_p.update(y=y, X=X)
ans = np.array([[0.59974735],
   [0.1994947 ]])
assert (np.equal(np.round(ans, 5), np.round(mod_p.a, 5)).all())

ans = np.array([-0.16107008, 0.93214436])
assert (np.equal(np.round(ans, 5), np.round(mod_p.R[0:2, 1], 5)).all())

# Test the Bernoulli DGLM
mod_bern.update(y=1, X=X)
ans = np.array([[1.02626224],
assert (np.equal(np.round(ans, 5), np.round(mod_bern.a, 5)).all())

ans = np.array([-1.00331466e-04,  1.11099963])
assert (np.equal(np.round(ans, 5), np.round(mod_bern.R[0:2, 1], 5)).all())


update_dlm(mod, y=None, X=None)

This update method works for normal DLMs. Here is a similar updating test, calling the method as mod_n.update:

mod_n = dlm(a0, R0, ntrend=1, nregn=2, deltrend=1, delregn=.9)

# Test the normal DLM
mod_n.update(y = y, X=X)
ans = np.array([[1.14285714],
assert(np.equal(np.round(ans, 5), np.round(mod_n.a, 5)).all())

ans = np.array([-0.08163265, 0.54421769])
assert(np.equal(np.round(ans, 5), np.round(mod_n.R[0:2,1], 5)).all())


update_bindglm(mod, n=None, y=None, X=None)

This update method works for binomial DGLMs. Here is a similar updating test, calling the method as mod_b.update. Note that for a binomial DGLM, we must specify the number of trials, $n_t$.

mod_b = bin_dglm(a0, R0, ntrend=1, nregn=2, deltrend=1, delregn=.9)

# New data - the number of trials
n = 10

# Test the Binomial DGLM
mod_b.update(y=y, X=X, n=n)
ans = np.array([[ 0.46543905],
   [ 0.46543905],
   [-0.0691219 ]])
assert (np.equal(np.round(ans, 5), np.round(mod_b.a, 5)).all())

ans = np.array([-0.15854342, 0.93495175])
assert (np.equal(np.round(ans, 5), np.round(mod_b.R[0:2, 1], 5)).all())