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 中线性高斯状态空间模型的基础类。
包含
PytensorRepresentation
和KalmanFilter
,并提供 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
属性中提供的名称。要实现新的状态空间模型,需要:
重载
param_names
属性以返回参数名称列表。重载
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
在定义命名参数
P0
、x0
、sigma_eta
和sigma_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 长度的字符串列表,与模型的隐藏状态相关联