Python 模拟置信区间不等于conf_int结果

Python 模拟置信区间不等于conf_int结果,python,scipy,statsmodels,Python,Scipy,Statsmodels,鉴于此模拟数据: import numpy as np from statsmodels.tsa.arima_process import ArmaProcess from statsmodels.tsa.statespace.structural import UnobservedComponents np.random.seed(12345) ar = np.r_[1, 0.9] ma = np.array([1]) arma_process = ArmaProcess(ar, ma)

鉴于此模拟数据:

import numpy as np
from statsmodels.tsa.arima_process import ArmaProcess
from statsmodels.tsa.statespace.structural import UnobservedComponents


np.random.seed(12345)
ar = np.r_[1, 0.9]
ma = np.array([1])
arma_process = ArmaProcess(ar, ma)

X = 100 + arma_process.generate_sample(nsample=100)
y = 1.2 * X + np.random.normal(size=100)
我们构建了一个
未观察到的组件
模型,用前70个点对后30个点进行推断,如下所示:

model = UnobservedComponents(y[:70], level='llevel', exog=X[:70])
f_model = model.fit()

forecaster = f_model.get_forecast(
    steps=30,
    exog=X[70:].reshape(-1, 1)
)
conf_int = forecaster.conf_int()
如果我们观察95%置信区间的平均值,我们得到以下结果:

conf_int.mean(axis=0)
array([118.19789195, 122.14101161])
但是当试图通过模型模拟得到相同的值时,我们并没有得到完全相同的结果。下面是我们为模拟边界运行的脚本:

sim_model = UnobservedComponents(np.zeros(30), level='llevel', exog=X[70:])
res = []
predicted_state = f_model.predicted_state[..., -1]
predicted_state_cov = f_model.predicted_state_cov[..., -1]   
for i in range(1000):
     init_state = np.random.multivariate_normal(
         predicted_state,
         predicted_state_cov
     )
     sim = sim_model.simulate(
         f_model.params,
         30,
         initial_state=init_state)
     res.append(sim.mean())
打印下面的2.5%和上面的97.5%我们得到:

np.percentile(res, [2.5, 97.5])
array([119.06735028, 121.26810407])
当我们使用模型模拟来区分数据中的信号和噪声时,这种差异最终导致了相互矛盾的结论。例如,如果我们制作:

y[70:] += 1
然后根据第一种技术,我们得出结论,新的
y
不携带信号,因为其平均值低于
122.14
。但如果我们使用第二种技术,情况就不一样了:因为上边界是
121.2
,所以我们得出结论,存在信号


我们现在试图理解的是,这是否是预期的。这两种技术的95%置信区间的下限和上限不应该相等吗?

我的猜测是,这主要是小样本问题(但我没有试图理解计算的细节)。另外,statsmodels中的所有时间序列模型都忽略了预测置信区间中的参数不确定性。您可以尝试使用更大的样本量,70个观测值对于估计具有较大持续性的时间序列过程来说是非常小的。此外,预测是以最后一个观测值为条件的。但是,IIUC,那么你在模拟中使用的是一个随机初始状态,你在计算百分位数时没有对其进行校正。如果这是正确的,那么你可以通过随机初始化添加额外的方差。嗨@Josef,我试着用8000点跑步,但上限仍然是
122
。我还从内环中删除了
init_state
计算(起初我认为这个值应该存在,以便为卡尔曼滤波模拟建模所有可能的初始状态值),但结果也没有太大变化(它转到了
121.13
,在它成为
121.2
之前。忽略预测中的不确定性意味着间隔应该更大。我不太明白为什么模拟结果会有不同的间隔。与非线性函数相关的另一个区别是,对于你所预测的预测计算百分位数/分位数的平均值,但在模拟中取平均值的百分位数。最好在模拟中查看特定视界的百分位数,而不是所有时间段的平均值,因为预测和置信区间将随预测视界而变化。@Josef我明白你的意思了!总计y是有意义的!刚才我意识到,可能取百分位数的平均值毕竟不是一个合适的操作。这意味着,实际上,如果我想得到平均值的上下置信区间,那么模拟技术就是我应该使用的,对吗?