TimeSeasonality#

class pymc_extras.statespace.models.structural.TimeSeasonality(season_length: int, innovations: bool = True, name: str | None = None, state_names: list | None = None, pop_state: bool = True)[source]#

季节性组件,在时域中建模

参数:
  • season_length (int) – 单个季节性周期中的周期数,例如,对于具有年度季节性模式的月度数据为 12,对于具有每周季节性模式的每日数据为 7,等等。

  • innovations (bool, default True) – 是否在季节性效应的强度中包含随机创新

  • name (str, default None) – 此季节性组件的名称。用于标记维度和坐标。当同一模型中包含多个季节性组件时很有用。默认为 f"Seasonal[s={season_length}]"

  • state_names (str列表, default None) –

    季节性效应标签的字符串列表。如果提供,则长度必须为 season_length。一个例子是 state_names = ['Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun'] 当数据是每日的,并且具有每周季节性模式时 (season_length = 7)。

    如果为 None,状态将编号为 [State_0, ..., State_s]

注释

季节性效应是每隔固定间隔重复的任何模式。尽管有很多可能的方法来建模季节性效应,但此处使用的实现是 [1] 描述为“规范”时域表示的方法。季节性组件可以表示为

\[\gamma_t = -\sum_{i=1}^{s-1} \gamma_{t-i} + \omega_t, \quad \omega_t \sim N(0, \sigma_\gamma)\]

其中 \(s\)seasonal_length 参数,\(\omega_t\) 是(可选的)随机创新。为了解释 \(\gamma\) 项,通过一个简单的例子来理解代数运算会很有帮助。令 \(s=4\),并省略冲击项。定义初始条件 \(\gamma_0, \gamma_{-1}, \gamma_{-2}\)。前 5 个时间步的季节性组件的值将是

\[\begin{split}\begin{align} \gamma_1 &= -\gamma_0 - \gamma_{-1} - \gamma_{-2} \\ \gamma_2 &= -\gamma_1 - \gamma_0 - \gamma_{-1} \\ &= -(-\gamma_0 - \gamma_{-1} - \gamma_{-2}) - \gamma_0 - \gamma_{-1} \\ &= (\gamma_0 - \gamma_0 )+ (\gamma_{-1} - \gamma_{-1}) + \gamma_{-2} \\ &= \gamma_{-2} \\ \gamma_3 &= -\gamma_2 - \gamma_1 - \gamma_0 \\ &= -\gamma_{-2} - (-\gamma_0 - \gamma_{-1} - \gamma_{-2}) - \gamma_0 \\ &= (\gamma_{-2} - \gamma_{-2}) + \gamma_{-1} + (\gamma_0 - \gamma_0) \\ &= \gamma_{-1} \\ \gamma_4 &= -\gamma_3 - \gamma_2 - \gamma_1 \\ &= -\gamma_{-1} - \gamma_{-2} -(-\gamma_0 - \gamma_{-1} - \gamma_{-2}) \\ &= (\gamma_{-2} - \gamma_{-2}) + (\gamma_{-1} - \gamma_{-1}) + \gamma_0 \\ &= \gamma_0 \\ \gamma_5 &= -\gamma_4 - \gamma_3 - \gamma_2 \\ &= -\gamma_0 - \gamma_{-1} - \gamma_{-2} \\ &= \gamma_1 \end{align}\end{split}\]

此练习表明,给定长度为 s-1initial_conditions 列表,此模型的效果将是

  • 周期 1: -sum(initial_conditions)

  • 周期 2: initial_conditions[-1]

  • 周期 3: initial_conditions[-2]

  • 周期 s: initial_conditions[0]

  • 周期 s+1: -sum(initial_condition)

等等。因此,为了解释,season_length - 1 初始状态是,当反转时,与 state_names[1:] 关联的系数。

警告

尽管 state_names 参数期望一个长度为 season_length 的列表,但只有 state_names[1:] 将作为模型维度保存,因为第一个系数未被识别(它被定义为 \(-\sum_{i=1}^{s} \gamma_{t-i}\))。

示例

使用具有高斯随机游走趋势和月度季节性的模型估计月度数据

from pymc_extras.statespace import structural as st
import pymc as pm
import pytensor.tensor as pt
import pandas as pd

# Get month names
state_names = pd.date_range('1900-01-01', '1900-12-31', freq='MS').month_name().tolist()

# Build the structural model
grw = st.LevelTrendComponent(order=1, innovations_order=1)
annual_season = st.TimeSeasonality(season_length=12, name='annual', state_names=state_names, innovations=False)
ss_mod = (grw + annual_season).build()

# Estimate with PyMC
with pm.Model(coords=ss_mod.coords) as model:
    P0 = pm.Deterministic('P0', pt.eye(ss_mod.k_states) * 10, dims=ss_mod.param_dims['P0'])
    intitial_trend = pm.Deterministic('initial_trend', pt.zeros(1), dims=ss_mod.param_dims['initial_trend'])
    annual_coefs = pm.Normal('annual_coefs', sigma=1e-2, dims=ss_mod.param_dims['annual_coefs'])
    trend_sigmas = pm.HalfNormal('trend_sigmas', sigma=1e-6, dims=ss_mod.param_dims['trend_sigmas'])
    ss_mod.build_statespace_graph(data, mode='JAX')
    idata = pm.sample(nuts_sampler='numpyro')

参考文献

__init__(season_length: int, innovations: bool = True, name: str | None = None, state_names: list | None = None, pop_state: bool = True)[source]#

方法

__init__(season_length[, innovations, name, ...])

build([name, filter_type, verbose])

从当前组件构建 StructuralTimeSeries 状态空间模型

make_and_register_data(name, shape[, dtype])

Helper function to create a pytensor symbolic variable and register it in the _name_to_data dictionary

make_and_register_variable(name, shape[, dtype])

Helper function to create a pytensor symbolic variable and register it in the _name_to_variable dictionary

make_symbolic_graph()

populate_component_properties()