Periodic effects and broadcasting

Periodic effects and broadcasting#

A common practice in time series forecasting is featuring periodic effects such as day of the week or weekend effects. pyrenew has built-in functions and classes to incorporate such effects into renewal models. Notably, the arrayutils.PeriodicBroadcaster class.

This document demonstrates how to use these functions and classes to model periodic effects and broadcasting in renewal models: Repeating elements of a sequence and repeating a sequence as a whole (tiling).

Repeated units#

The RtPeriodicDiff and RtWeeklyDiff classes use PeriodicBroadcaster to repeat each vector element to represent Rt values held constant within a period. Let’s show it’s usage with a basic renewal model. We will use the same model structure shown in the getting_started tutorial:

import jax.numpy as jnp
import numpy as np
import numpyro as npro
from pyrenew import process, deterministic
# The random process for Rt
rt_proc = process.RtWeeklyDiffProcess(
    offset=0,
    log_rt_prior=deterministic.DeterministicVariable(
        jnp.array([0.1, 0.2]), name="log_rt_prior"
    ),
    autoreg=deterministic.DeterministicVariable(
        jnp.array([0.7]), name="autoreg"
    ),
    periodic_diff_sd=deterministic.DeterministicVariable(
        jnp.array([0.1]), name="periodic_diff_sd"
    ),
)
with npro.handlers.seed(rng_seed=20):
    sim_data = rt_proc.sample(duration=30)

# Plotting the Rt values
import matplotlib.pyplot as plt

plt.step(np.arange(len(sim_data.rt)), sim_data.rt, where="post")
plt.xlabel("Time")
plt.ylabel("Rt")
plt.title("Simulated Rt values")

# Adding bands to mark weeks
for i in range(0, 30, 7):
    plt.axvline(i, color="black", linestyle="--", alpha=0.5)
plt.show()

image1

The implementation of the RtWeeklyDiffProcess (which is an instance of RtPeriodicDiffProcess), uses PeriodicBroadcaster to repeating values: PeriodicBroadcaster(..., period_size=7, broadcast_type="repeat"). Setting the broadcast_type to "repeat" repeats each vector element for the specified period size. The RtWeeklyDiff class is a particular case of RtPeriodicDiff with a period size of seven.

Repeated sequences (tiling)#

The PeriodicBroadcaster class can also be used to repeat a sequence as a whole. For example, we can use this to model a periodic effect such as day-of-the-week effect. Let’s use the DayOfWeekEffect random variable. We will sample from a scaled Dirchlet distribution such that the sum of the samples is 7:

import numpyro.distributions as dist
from pyrenew import transformation, metaclass

# Building the transformed prior: Dirichlet * 7
mysimplex = dist.TransformedDistribution(
    dist.Dirichlet(concentration=jnp.ones(7)),
    transformation.AffineTransform(loc=0, scale=7.0),
)

# Constructing the day of week effect
dayofweek = process.DayOfWeekEffect(
    offset=0,
    quantity_to_broadcast=metaclass.DistributionalRV(mysimplex, "simp"),
)

Like before, we can use the sample method to generate samples from the day of week effect:

with npro.handlers.seed(rng_seed=20):
    sim_data = dayofweek.sample(duration=30)

# Plotting the effect values
import matplotlib.pyplot as plt

plt.step(np.arange(len(sim_data.value)), sim_data.value, where="post")
plt.xlabel("Time")
plt.ylabel("Effect size")
plt.title("Simulated Day of Week Effect values")

# Adding bands to mark weeks
for i in range(0, 30, 7):
    plt.axvline(i, color="black", linestyle="--", alpha=0.5)
plt.show()

image2

Like the example from the previous section, the DayOfWeekEffect class uses PeriodicBroadcaster to broadcast the data, this time using broadcast_type = "tile", repeating the sequence as a whole. The DayOfWeekEffect class is a particular case of PeriodicEffect with a period size of seven.