使用Statsmodels MLEmodel构建自定义状态空间模型

时间:2020-09-02 07:56:28

标签: python time-series

我正在研究如何使用python中的状态空间模型构建状态空间模型的自定义模型。 我想知道是否应该在下面的URL使用Statsomdels的MLEmodel类,但是我不确定如何构建它。 https://www.statsmodels.org/dev/generated/statsmodels.tsa.statespace.mlemodel.MLEModel.html https://www.statsmodels.org/dev/examples/notebooks/generated/statespace_custom_models.html#Model-1:-time-varying-coefficients

具体来说,我想使用以下模型进行长期预测。

1。状态方程

x_t = x_ {t-1} + exp(B / z_ {t-1})+ E_ {1t}

  • x_t:在时间t的状态
  • x_ {t-1}:在时间t-1的状态
  • A:常数(要估算的参数)
  • B:常量(要估算的参数)
  • z_ {t-1}:说明变量
  • E_ {1t}:系统噪音(〜N(0,u_1))
  1. 观测方程 y_t = x_t + E_ {2t}
  • y_t:观测数据(感应)
  • E_ {2t}:观察噪声(〜N(0,u_2))

请告诉我

2 个答案:

答案 0 :(得分:0)

模型的基本实现是(编辑以添加预测所需的方法):

import numpy as np
import statsmodels.api as sm

class RWD(sm.tsa.statespace.MLEModel):
    param_names = ['A', 'B', 'u_1', 'u_2']
    start_params = [1., 0., 1., 1]

    def __init__(self, endog, exog):
        exog = np.squeeze(exog)
        super().__init__(endog, exog=exog, k_states=1, initialization='diffuse')
        self.k_exog = 1
        
        # Z = I
        self['design', 0, 0] = 1.
        # T = I
        self['transition', 0, 0] = 1.
        # R = I
        self['selection', 0, 0] = 1.
        
        # Set c_t to be time-varying
        self['state_intercept'] = np.zeros((1, self.nobs))
        
    def clone(self, endog, exog, **kwargs):
        # This method must be set to allow forecasting in custom
        # state space models that include time-varying state
        # space matrices, like we have for state_intercept here
        return self._clone_from_init_kwds(endog, exog=exog, **kwargs)
        
    def transform_params(self, params):
        # Variances must be positive
        params[2:] = params[2:]**2
        return params
        
    def untransform_params(self, params):
        # Reverse of above transformation
        params[2:] = params[2:]**0.5
        return params
    
    def update(self, params, **kwargs):
        params = super().update(params, **kwargs)
        
        # c_t = A * exp(B / z_t)
        self['state_intercept', 0, :] = params[0] * np.exp(params[1] / self.exog)
        
        # H = u_1
        self['obs_cov', 0, 0] = params[2]
        # Q = u_2
        self['state_cov', 0, 0] = params[3]

答案 1 :(得分:0)

对不起。富尔顿先生

我想在方程式中加上一个常数T,如下所示。 我应该更改“转换”的指定方法吗?

状态方程: x_t = T x_ {t-1} + exp(B / z_ {t-1})+ E_ {1t}

import numpy as np
import statsmodels.api as sm

class RWD(sm.tsa.statespace.MLEModel):
    param_names = ['T', 'A', 'B', 'u_1', 'u_2']
    start_params = [1., 1., 0., 1., 1]

    def __init__(self, endog, exog):
        exog = np.squeeze(exog)
        super().__init__(endog, exog=exog, k_states=1, initialization='diffuse')
        self.k_exog = 1
        
        # Z = I
        self['design', 0, 0] = 1.
        # T = I
        #self['transition', 0, 0] = 1.
        # R = I
        self['selection', 0, 0] = 1.
        
        # Set c_t to be time-varying
        self['state_intercept'] = np.zeros((1, self.nobs))
        
    def clone(self, endog, exog, **kwargs):
        #This method must be set to allow forecasting in custom
        #state space models that include time-varying state
        #space matrices, like we have for state_intercept here
        return self._clone_from_init_kwds(endog, exog=exog, **kwargs)
        
    def transform_params(self, params):
        # Variances must be positive
        params[3:] = params[3:]**2
        return params
        
    def untransform_params(self, params):
        # Reverse of above transformation
        params[3:] = params[3:]**0.5
        return params
    
    def update(self, params, **kwargs):
        params = super().update(params, **kwargs)
        # T = T
        self['transition', 0, 0] = params[0] 
        # c_t = A * exp(B / z_t)
        self['state_intercept', 0, :] = params[1] * np.exp(params[2] / self.exog)
        
        # H = u_1
        self['obs_cov', 0, 0] = params[3]
        # Q = u_2
        self['state_cov', 0, 0] = params[4]