R和Python中的ACF置信区间为什么不同?

10
当我在R中使用acf函数时,它会绘制水平线来表示不同滞后下的自相关置信区间(默认为95%): R ACF 然而,在Python中使用statsmodels.graphics.tsaplots.plot_acf时,我看到了一个基于更复杂计算的曲线置信区间: python ACF 请注意,在R版本中,直到25阶滞后被认为是显著的。对于相同的数据,在Python版本中,只有20阶滞后被认为是显著的。
这两种方法之间的区别是什么?哪一个应该更可信?有人能解释一下由statsmodels.tsa.stattools.acf计算的非常数置信区间的理论吗?
我知道可以通过简单地绘制y=[+/-]1.96 / np.sqrt(len(data))来重现R中的水平线。但是,我想了解这个花哨的曲线置信区间的原理。

只是提醒一下,这些都是“默认”行为。您可以使用Python的statsmodels.graphics.tsaplots.plot_acf函数来绘制常数(白噪声假设)置信区间,方法是包含可选参数bartlett_confint=False,而您可以使用R的acf()函数来绘制非常数(移动平均假设)置信区间,方法是使用参数ci.type='ma' - postylem
2个回答

15

研究表明,自相关系数r(k)服从方差为Var(r(k))的高斯分布。

正如您发现的,在R中,对于所有的k,方差可以简单地计算为Var(r(k)) = 1/N。而在Python中,使用Bartlett公式计算方差,其中Var(r(k)) = 1/N (1 + 2(r(1)^2+r(2)^2+...+r(k-1)^2))。这导致了上面显示的第一个增加,然后变平的置信水平。

Python中ACF方差的源代码:

varacf = np.ones(nlags + 1) / nobs
varacf[0] = 0
varacf[1] = 1. / nobs
varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2)

这两个不同的公式基于不同的假设。前者假设一个i.i.d过程,对于所有的k != 0, r(k) = 0,而后者假设一个MA过程,其阶数为k-1,其中ACF在滞后k之后"截尾"。


谢谢澄清!然而,使用R或Python实现是否有任何区别?还有其他人说:开头弯曲会有影响吗?除此之外,它们似乎提供相同的结果。 - Ben
一个有界随机变量r(k)如何成为正态分布... - Rémy Hosseinkhan Boucher
我想了解“具有k-1阶的MA过程,其中ACF在滞后k之后‘截尾’”这个假设。有人能推荐一下去哪里查找吗? - postylem
特别是,当数据具有内在的时间依赖性时,非常数置信区间版本(巴特利特公式)通常更加合理,这是否普遍成立? - postylem

2
这段文本的英译如下:

这并不是对理论部分的回答(可能更适合在CrossValidated上),但也许有用……?

如果你去statsmodels.tsa.stattools.acf的文档页面,它会给你一个浏览源代码的选项。那里的代码是:

varacf = np.ones(nlags + 1) / nobs
varacf[0] = 0
varacf[1] = 1. / nobs
varacf[2:] *= 1 + 2 * np.cumsum(acf[1:-1]**2)
interval = stats.norm.ppf(1 - alpha / 2.) * np.sqrt(varacf)
confint = np.array(lzip(acf - interval, acf + interval))

相比之下,plot.acf的R源代码显示
clim0 <- if (with.ci) qnorm((1 + ci)/2)/sqrt(x$n.used) else c(0, 0)

其中 ci 是置信水平(默认值为0.95)。

1
谢谢Ben——是的,我也发现了,但仍然想知道理论和哪种方法更好。 - eraoul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接