PyMCStateSpace#

class pymc_extras.statespace.core.PyMCStateSpace(k_endog: int, k_states: int, k_posdef: int, filter_type: str = 'standard', verbose: bool = True, measurement_error: bool = False)[source]#

PyMC 中线性高斯状态空间模型的基础类。

包含 PytensorRepresentationKalmanFilter,并提供 PyMC 模型和状态空间模型之间的映射。

参数:
  • k_endog (int) – 内生变量(观测时间序列)的数量。

  • k_states (int) – 状态变量的数量。

  • k_posdef (int) – 模型中冲击的数量

  • filter_type (str, 可选) – 要使用的卡尔曼滤波器类型。有效选项为“standard”、“univariate”、“single”、“cholesky”和“steady_state”。有关更多信息,请参阅每个滤波器的文档。默认为“standard”。

  • verbose (bool, 可选) – 如果为 True,则显示有关已初始化模型的信息。默认为 True。

  • measurement_error (bool, 可选) – 如果为 true,则模型包含测量误差。后验估计抽样方法需要它来决定如何计算观测误差。如果为 False,这些误差确定性地为零;如果为 True,则从多元正态分布中抽样。

注释

基于 statsmodels 状态空间实现 statsmodels/statsmodels,在 [1] 中描述。

所有状态空间模型都继承自这个基类,它负责提供 PyMC 模型和线性状态空间模型的 PytensorRepresentation 之间的接口。 这是通过 update 方法完成的,该方法将 PyMC 随机变量向量作为输入,并将它们分配到底层 PytensorRepresentation 中的正确位置。 参数向量(称为 theta)的构造是自动完成的,但取决于 param_names 属性中提供的名称。

要实现新的状态空间模型,需要:

  1. 重载 param_names 属性以返回参数名称列表。

  2. 重载 update 方法以将这些参数放入其各自的状态空间矩阵中

此外,还可以重载许多其他属性,以便在用户编写 PyMC 模型时为他们提供额外的资源。 有关详细信息,请参阅此类文档的属性部分。

最后,此类包含所有状态空间模型共有的后验估计方法,在编写自定义状态空间模型时无需重载这些方法。

示例

局部水平模型是一个简单的状态空间模型。 它是一个高斯随机游走,带有一个漂移项,该漂移项本身也遵循高斯随机游走,如下两个方程所述:

\[\begin{split}\begin{align} y_{t} &= y_{t-1} + x_t + \nu_t \tag{1} \\ x_{t} &= x_{t-1} + \eta_t \tag{2} \end{align}\end{split}\]

其中 \(y_t\) 是观测数据,\(x_t\) 是未观测到的趋势项。 该模型有两个未知参数,即两个创新项的方差 \(sigma_\nu\)\(sigma_\eta\)。 将隐藏状态向量取为 \(\begin{bmatrix} y_t & x_t \end{bmatrix}^T\),冲击向量取为 \(\varepsilon_t = \begin{bmatrix} \nu_t & \eta_t \end{bmatrix}^T\)。 然后,可以使用以下矩阵将此模型转换为状态空间形式:

\[\begin{split}\begin{align} T &= \begin{bmatrix}1 & 1 \\ 0 & 1 \end{bmatrix} & R &= \begin{bmatrix}1 & 0 \\ 0 & 1 \end{bmatrix} & Q &= \begin{bmatrix} \sigma_\nu & 0 \\ 0 & \sigma_\eta \end{bmatrix} & Z &= \begin{bmatrix} 1 & 0 \end{bmatrix} \end{align}\end{split}\]

其余状态空间矩阵为适当大小的零矩阵。 该模型具有两个状态、两个冲击和一个观测状态。 了解所有这些之后,可以按如下方式实现一个非常简单的局部水平模型:

from pymc_extras.statespace.core import PyMCStateSpace
import numpy as np

class LocalLevel(PyMCStateSpace):
    def __init__():
        # Initialize the superclass. This creates the PytensorRepresentation and the Kalman Filter
        super().__init__(k_endog=1, k_states=2, k_posdef=2)

        # Declare the non-zero, non-parameterized matrices
        self.ssm['transition', :, :] = np.array([[1.0, 1.0], [0.0, 1.0]])
        self.ssm['selection', :, :] = np.eye(2)
        self.ssm['design', :, :] = np.array([[1.0, 0.0]])

    @property
    def param_names(self):
        return ['x0', 'P0', 'sigma_nu', 'sigma_eta']

    def make_symbolic_graph(self):
        # Declare symbolic variables that represent parameters of the model
        # In this case, we have 4: x0 (initial state), P0 (initial state covariance), sigma_nu, and sigma_eta

        x0 = self.make_and_register_variable('x0', shape=(2,))
        P0 = self.make_and_register_variable('P0', shape=(2,2))
        sigma_mu = self.make_and_register_variable('sigma_nu')
        sigma_eta = self.make_and_register_variable('sigma_eta')

        # Next, use these symbolic variables to build the statespace matrices by assigning each parameter
        # to its correct location in the correct matrix

        self.ssm['initial_state', :] = x0
        self.ssm['initial_state_cov', :, :] = P0
        self.ssm['state_cov', 0, 0] = sigma_nu
        self.ssm['state_cov', 1, 1] = sigma_eta

在定义命名参数 P0x0sigma_etasigma_nu 的先验之后,我们可以从此模型中抽样:

import pymc as pm

ll = LocalLevel()

with pm.Model() as mod:
    x0 = pm.Normal('x0', shape=(2,))
    P0_diag = pm.Exponential('P0_diag', 1, shape=(2,))
    P0 = pm.Deterministic('P0', pt.diag(P0_diag))
    sigma_nu = pm.Exponential('sigma_nu', 1)
    sigma_eta = pm.Exponential('sigma_eta', 1)

    ll.build_statespace_graph(data = data)
    idata = pm.sample()

参考文献

__init__(k_endog: int, k_states: int, k_posdef: int, filter_type: str = 'standard', verbose: bool = True, measurement_error: bool = False)[source]#

方法

__init__(k_endog, k_states, k_posdef[, ...])

add_default_priors()

将默认先验添加到活动的 PyMC 模型上下文中

build_statespace_graph(data[, ...])

给定参数向量 theta,构造描述状态空间模型和数据关联的对数概率的完整计算图。

forecast(idata[, start, periods, end, ...])

生成未来状态空间模型轨迹的预测。

impulse_response_function(idata[, n_steps, ...])

从状态空间模型动态生成脉冲响应函数 (IRF)。

make_and_register_data(name, shape[, dtype])

帮助函数,用于创建 pytensor 符号变量并在 _name_to_data 字典中注册它

make_and_register_variable(name[, shape, dtype])

帮助函数,用于创建 pytensor 符号变量并在 _name_to_variable 字典中注册它

make_symbolic_graph()

make_symbolic_graph 函数的目的是向用户隐藏繁琐的参数分配。

sample_conditional_posterior(idata[, ...])

从条件后验中抽样;也就是说,给定来自后验分布的参数样本,计算卡尔曼滤波轨迹。

sample_conditional_prior(idata[, random_seed])

从条件先验中抽样;也就是说,给定来自先验分布的参数样本,计算卡尔曼滤波轨迹。

sample_statespace_matrices(idata, matrix_names)

从提供的 idata 中抽取请求的状态空间矩阵的样本

sample_unconditional_posterior(idata[, ...])

使用模型参数后验分布的随机样本,根据状态空间动力学绘制无条件样本轨迹。

sample_unconditional_prior(idata[, steps, ...])

使用模型参数先验分布的随机样本,根据状态空间动力学绘制无条件样本轨迹。

unpack_statespace()

帮助函数,用于快速获取标准顺序中的所有状态空间矩阵。

属性

coords

PyMC 模型坐标

data_info

有关需要在 PyMC 模型块中声明的数据变量的信息。

data_names

模型预期的数据变量的名称。

default_priors

模型参数名称和可调用函数的字典,用于构造模型的默认先验

observed_states

一个 k_endog 长度的字符串列表,与模型的观测状态相关联

param_dims

每个模型参数的命名维度的字典

param_info

声明先验所需的参数信息

param_names

模型参数的名称

shock_names

一个 k_posdef 长度的字符串列表,与模型的冲击过程相关联

state_names

一个 k_states 长度的字符串列表,与模型的隐藏状态相关联