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

Python 使用Statsmodels MLEmodel构建自定义状态空间模型,python,time-series,Python,Time Series,我正在研究如何使用python中的状态空间模型构建状态空间模型的自定义模型。 我想知道是否应该在下面的URL中使用statsomdel的MLEmodel类,但我不确定如何构建它。 具体来说,我想使用以下模型进行长期预测 1.状态方程 x_t=x_{t-1}+A 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)) 观测方程

我正在研究如何使用python中的状态空间模型构建状态空间模型的自定义模型。 我想知道是否应该在下面的URL中使用statsomdel的MLEmodel类,但我不确定如何构建它。

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

1.状态方程

x_t=x_{t-1}+A 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))
  • 观测方程 y_t=x_t+E_{2t}
    • 是:观测数据(传感)
    • E_{2t}:观测噪声(~N(0,u_2))

    请告诉我

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

    对不起。富尔顿先生

    我想在方程中加一个常数项T,如下所示。 我是否应该更改“转换”的规格说明方法

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


    谢谢你,富尔顿先生!我很荣幸能直接收到开发者的来信。没问题,我希望它有用。对不起。富尔顿先生,我想在方程中加一个常数项T,如下所示。我是否应该改变“过渡”的规格说明方法?富尔顿先生。请告诉我。是否可以增加自定义状态空间模型中的滞后数?(t-2,t-3,t-4,t-5,,,,,)@cfulton
    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]
    
    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]