时间序列的平稳性检验方法汇总

时间序列平稳性检验方法,可分为三类:

  1. 图形分析方法

  2. 简单统计方法

  3. 假设检验方法

一、图形分析方法

可视化数据

可视化数据即绘制时间序列的折线图,看曲线是否围绕某一数值上下波动(判断均值是否稳定),看曲线上下波动幅度变化大不大(判断方差是否稳定),看曲线不同时间段波动的频率[~紧凑程度]变化大不大(判断协方差是否稳定),以此来判断时间序列是否是平稳的。

以下绘制几张图,大家来直观判断一下哪些是平稳的,哪些是非平稳的。

import numpy as np
import pandas as pd
import akshare as ak
from matplotlib import pyplot as pltnp.random.seed(123)# -------------- 准备数据 --------------
# 白噪声
white_noise = np.random.standard_normal(size=1000)# 随机游走
x = np.random.standard_normal(size=1000)
random_walk = np.cumsum(x)# GDP
df = ak.macro_china_gdp()
df = df.set_index('季度')
df.index = pd.to_datetime(df.index)
gdp = df['国内生产总值-绝对值'][::-1].astype('float')# GDP DIFF
gdp_diff = gdp.diff(4).dropna()# -------------- 绘制图形 --------------
fig, ax = plt.subplots(2, 2)ax[0][0].plot(white_noise)
ax[0][0].set_title('white_noise')
ax[0][1].plot(random_walk)
ax[0][1].set_title('random_walk')ax[1][0].plot(gdp)
ax[1][0].set_title('gdp')
ax[1][1].plot(gdp_diff)
ax[1][1].set_title('gdp_diff')plt.show()
 

 a. 白噪声,曲线围绕0值上下波动,波动幅度前后、上下一致,为平稳序列。
b. 随机游走,曲线无确定趋势,均值、方差波动较大,非平稳序列。
c. GDP数据趋势上升,均值随时间增加,非平稳序列。
d. GDP季节差分后数据,曲线大致在一条水平线上上下波动,波动幅度前后变化较小,可认为是平稳的。

可视化统计特征

可视化统计特征,是指绘制时间序列的自相关图和偏自相关图,根据自相关图的表现来判断序列是否平稳。

自相关,也叫序列相关,是一个信号与自身不同时间点的相关度,或者说与自身的延迟拷贝--或滞后--的相关性,是延迟的函数。不同滞后期得到的自相关系数,叫自相关图。

(这里有一个默认假设,即序列是平稳的,平稳序列的自相关性只和时间间隔k有关,不随时间t的变化而变化,因而可以称自相关函数是延迟(k)的函数)

平稳序列通常具有短期相关性,对于平稳的时间序列,自相关系数往往会迅速退化到零(滞后期越短相关性越高,滞后期为0时,相关性为1);而对于非平稳的数据,退化会发生得更慢,或存在先减后增或者周期性的波动等变动。

import statsmodels.api as sm
X = [2,3,4,3,8,7]
print(sm.tsa.stattools.acf(X, nlags=1, adjusted=True))

> [1, 0.3559322]
其中第一个元素为滞后期为0时的自相关性,第二个元素为滞后期为1时的自相关性

根据ACF求出滞后k自相关系数时,实际上得到并不是X(t)与X(t-k)之间单纯的相关关系。

因为X(t)同时还会受到中间k-1个随机变量X(t-1)、X(t-2)、……、X(t-k+1)的影响,而这k-1个随机变量又都和X(t-k)具有相关关系,所以自相关系数里面实际掺杂了其他变量对X(t)与X(t-k)的影响。

在剔除了中间k-1个随机变量X(t-1)、X(t-2)、……、X(t-k+1)的干扰之后,X(t-k)对X(t)影响的相关程度,叫偏自相关系数。不同滞后期得到的偏自相关系数,叫偏自相关图。(偏自相关系数计算较复杂,后期再来具体介绍)

 下面我们就来看看几个实战案例(上图中的数据再来看一下它们的自相关图和偏自相关图):

# 数据生成过程在第一个代码块中
from statsmodels.graphics.tsaplots import plot_acf, plot_pacffig, ax = plt.subplots(4, 2)
fig.subplots_adjust(hspace=0.5)plot_acf(white_noise, ax=ax[0][0])
ax[0][0].set_title('ACF(white_noise)')
plot_pacf(white_noise, ax=ax[0][1])
ax[0][1].set_title('PACF(white_noise)')plot_acf(random_walk, ax=ax[1][0])
ax[1][0].set_title('ACF(random_walk)')
plot_pacf(random_walk, ax=ax[1][1])
ax[1][1].set_title('PACF(random_walk)')plot_acf(gdp, ax=ax[2][0])
ax[2][0].set_title('ACF(gdp)')
plot_pacf(gdp, ax=ax[2][1])
ax[2][1].set_title('PACF(gdp)')plot_acf(gdp_diff, ax=ax[3][0])
ax[3][0].set_title('ACF(gdp_diff)')
plot_pacf(gdp_diff, ax=ax[3][1])
ax[3][1].set_title('PACF(gdp_diff)')plt.show()

 

 (1) 白噪声的自相关系数很快就衰减到0附近,是明显的平稳序列。滞后期为0时自相关系数和偏自相关系数其实就是序列自己和自己的相关性,故为1;滞后期为1时,自相关系数为0,表示白噪声无自相关性。
(2) 随机游走,自相关系数下降非常缓慢,故为非平稳序列;另从偏自相关系数中可以看到随机游走只和前一项有关。
(3) GDP数据的自相关图中也可以看到存在一定的周期性,滞后4、8、12等自相关系数较大下降较慢,差分后下降多一些起到一定效果,认为差分后序列是平稳的。同可视化数据一样,直观判断带有较强主观性,但能让我们对数据有更直观的认识。

二、简单统计方法

计算统计量的方法只是作为一个补充,了解即可。宽平稳中有两个条件是均值不变和方差不变,可视化数据中我们可以直观看出来,其实还可以具体计算一下看看。

很有意思的逻辑,直接将序列前后拆分成2个序列,分别计算这2个序列的均值、方差,对比看是否差异明显。(其实很多时序异常检验也是基于这种思想,前后分布一致则无异常,否则存在异常或突变)

我们来算白噪声和随机游走序列不同时间段的均值、方差:

import numpy as npnp.random.seed(123)white_noise = np.random.standard_normal(size=1000)x = np.random.standard_normal(size=1000)
random_walk = np.cumsum(x)def describe(X):split = int(len(X) / 2)X1, X2 = X[0:split], X[split:]mean1, mean2 = X1.mean(), X2.mean()var1, var2 = X1.var(), X2.var()print('mean1=%f, mean2=%f' % (mean1, mean2))print('variance1=%f, variance2=%f' % (var1, var2))print('white noise sample')
describe(white_noise)print('random walk sample')
describe(random_walk)

white noise sample:
mean1=-0.038644, mean2=-0.040484
variance1=1.006416, variance2=0.996734

random walk sample:
mean1=5.506570, mean2=8.490356
variance1=53.911003, variance2=126.866920

白噪声序列均值和方差略有不同,但大致在同一水平线上;
随机游走序列的均值和方差差异就比较大,因此为非平稳序列。

三、假设检验方法

平稳性的假设检验方法当前主流为单位根检验,检验序列中是否存在单位根,若存在,则为非平稳序列,不存在则为平稳序列。

在介绍检验方法之前,有必要了解一些相关补充知识,这样对后面的检验方法理解上就会更清晰一些。

什么是单位根

import numpy as np
from matplotlib import pyplot as pltnp.random.seed(123)def simulate(beta):y = np.random.standard_normal(size=1000)for i in range(1, len(y)):y[i] = beta * y[i - 1] + y[i]return yplt.figure(figsize=(20, 4))
for i, beta in enumerate([0.9, 1.0, 1.1]):plt.subplot(1, 3, i+1)plt.plot(simulate(beta))plt.title('beta: {}'.format(beta))
plt.show()

                                                                         检验方法

DF检验

ADF检验(Augmented Dickey-Fuller Testing)是最常用的单位根检验方法之一,通过检验序列是否存在单位根来判断序列是否是平稳的。ADF检验是DF检验的增强版,在介绍ADF之前,我们先来看一下DF检验。

迪基(Dickey)和弗勒(Fuller)1979年基于非平稳序列的基本特征将其大致归为三类并提出DF检验:

(1) 当序列基本走势呈现无规则上升或下降并反复时,将其归为无漂移项自回归过程;
(2) 当序列基本走势呈现明显的随时间递增或递减且趋势并不太陡峭时,将其归为带漂移项自回归过程;
(3) 当序列基本走势随时间快速递增时,则将其归为带趋势项回归过程。

若检验统计量大于临界值(p值大于显著性水平 ),不能拒绝原假设,序列是非平稳的;
若检验统计量小于临界值(p值小于显著性水平 ),拒绝原假设,认为序列是平稳的。

ADF检验

DF的检验公式为一阶自回归过程,为了能适用于高阶自回归过程的平稳性检验,迪基等1984年对DF检验进行了一定的修正,引入了更高阶的滞后项,ADF的检验回归式修正为:

 

import numpy as np
from matplotlib import pyplot as pltnp.random.seed(123)y = np.random.standard_normal(size=100)
for i in range(1, len(y)):y[i] = 1 + 0.1*i + y[i]plt.figure(figsize=(12, 6))
plt.plot(y)
plt.show()

 检验是否平稳:

from arch.unitroot import ADF
adf = ADF(y)
# print(adf.pvalue)
print(adf.summary().as_text())adf = ADF(y)
adf.trend = 'ct'
print(adf.summary().as_text())

 说明:
arch包中ADF检验可指定trend为
'n'(不含截距项和时间趋势项)
'c'(含截距项)
'ct'(含截距项和时间趋势项)
'ctt'(含截距项和时间趋势项和二次型时间趋势项)
分别对应不同平稳类型的检验。(滞后期lags默认为AIC最小)

以上第一个文本输出中,不指定trend默认为检验是否含截距项平稳,显著性水平p=0.836>0.05,不拒绝原假设,非平稳;
以上第二个文本输出中,指定trend为检验是否含截距项和时间趋势项平稳,显著性水平p=0.000<0.05,拒绝原假设,故为趋势项平稳。

我们再来看看GDP季节差分前后数据是否为平稳的:

# 数据在第一个代码块中
from arch.unitroot import ADF
adf = ADF(gdp)
print(adf.summary().as_text())adf = ADF(gdp_diff)
print(adf.summary().as_text())

 可以看到差分前p值为0.998>0.05,不能拒绝原假设,数据非平稳;差分后p值为0.003<0.05,故在5%的显著性水平下可拒绝原假设,差分后的数据是平稳的。

# 数据在第一个代码块中
from arch.unitroot import ADF
adf = ADF(gdp)
adf.trend = 'ct'
print(adf.summary().as_text())

 指定检验平稳类型为含截距项和时间趋势项平稳,p值为0.693>0.05,同样不能拒绝原假设,故差分前亦非趋势平稳。

PP检验

Phillips和Perron(1988) 提出一种非参数检验方法,主要是为了解决残差项中潜在的序列相关和异方差问题,其检验统计量的渐进分布和临界值与 ADF检验相同。同样出现较早,假设条件一样,用法相似,可作为ADF检验的补充。

同样构造一个趋势平稳序列,看下PP检验结果:

import numpy as np
from arch.unitroot import PhillipsPerronnp.random.seed(123)y = np.random.standard_normal(size=100)
for i in range(1, len(y)):y[i] = 1 + 0.1*i + y[i]pp = PhillipsPerron(y)
print(pp.summary().as_text())pp = PhillipsPerron(y)
pp.trend = 'ct'
print(pp.summary().as_text())

 不指定trend为默认检验是否为带截距项的平稳过程,检验结果p值为0.055>0.05,对应检验统计量为-2.825大于5%显著性水平下的临界值-2.89,所以5%显著性水平下不拒绝原假设,为非平稳序列;但是检验统计量小于10%显著性水平下的临界值-2.58,故在10%的显著性水平下可拒绝原假设,认为是平稳序列。

指定trend=‘ct’为检验是否为带截距项和时间趋势项的平稳过程,检验结果p值为0.000<0.05,故为趋势平稳;其实检验统计量为-10.009小于1%显著性水平下的临界值-4.05,所以即便在1%显著性水平下也是平稳的。

基于以上检验结果,可以判定序列是趋势平稳的。

DF-GLS检验

DF-GLS检验,是Elliott, Rothenberg, and  Stock 1996年提出的一种单位根检验方法,全称Dickey-Fuller Test with GLS Detredding,即“使用广义最小二乘法去除趋势的检验”,是目前最有功效的单位根检验。

DF-GLS检验利用广义最小二乘法,首先对要检验的数据进行一次“准差分”,然后利用准差分的数据对原序列进行去除趋势处理,再利用ADF检验的模型形式对去除趋势后的数据进行单位根检验,但此时ADF检验模型中不再包含常数项或者时间趋势变量。

同样构造一个趋势平稳序列看下检验效果:

import numpy as np
from arch.unitroot import DFGLSnp.random.seed(123)y = np.random.standard_normal(size=100)
for i in range(1, len(y)):y[i] = 1 + 0.1*i + y[i]dfgls = DFGLS(y)
print(dfgls.summary().as_text())dfgls = DFGLS(y)
dfgls.trend = 'ct'
print(dfgls.summary().as_text())

 

 不指定trend情况下不能拒绝原假设,非平稳;指定trend='ct'时p值小于0.05,拒绝原假设,带截距项和时间趋势平稳。

再来构造一个含单位根的非平稳序列看一下检验结果:

import numpy as np
from arch.unitroot import DFGLSnp.random.seed(123)y = np.random.standard_normal(size=100)
for i in range(1, len(y)):y[i] = 0.1 + y[i-1] + y[i]dfgls = DFGLS(y)
print(dfgls.summary().as_text())dfgls = DFGLS(y)
dfgls.trend = 'ct'
print(dfgls.summary().as_text())

 p值一个为0.645,一个为0.347,均大于0.05/0.1。指不指定检验类型,均未能通过检验,故该序列为非平稳序列。(DF-GLS检验trend只能指定为'c'或者'ct')

KPSS检验

另一个著名的单位根存在的检验是Kwiatkowski, Phillips, and Shin 1992年提出的KPSS检验。与以上三种检验方法相比,最大的不同点就是它的原假设是平稳序列或趋势平稳序列,而备择假设是存在单位根。

  • 原假设:序列不存在单位根(时间序列是平稳的或趋势平稳的)

  • 备择假设:序列存在单位根(时间序列是非平稳的)

  • import numpy as np
    from arch.unitroot import KPSSnp.random.seed(123)y = np.random.standard_normal(size=100)
    for i in range(1, len(y)):y[i] = 0.1 + y[i-1] + y[i]kpss = KPSS(y)
    print(kpss.summary().as_text())kpss = KPSS(y)
    kpss.trend = 'ct'
    print(kpss.summary().as_text())

     注意KPSS检验中原假设为不存在单位根。默认检验趋势类型下p值为0.000,拒绝原假设,存在单位根,序列非平稳。指定trend='ct'后,p值0.115>0.05,不拒绝原假设,认为序列趋势平稳,检验错误。以上几种检验中均不能100%保证检验正确,PP检验可认为是ADF检验的补充,KPSS检验同样也可和其他检验一同使用,当均认为是平稳或趋势平稳时方判定为平稳。

除以上检验方法外,还有Zivot-Andrews检验、Variance Ratio检验等检验方法。

以上代码实现中使用的是Python中的arch包,另外还有一个常用的包statsmodels中也实现了单位根检验方法,结果是一样的。

郑重感谢Python数据科学

本人接下来进行金融统计,需要转向python,需要教程,此公众号对我用处极大。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tcp的发送端一个小包就能打破对端的delay_ack么?

3.10内核&#xff0c;反向合入4.9的bbr。 最近分析bbr的时候&#xff0c;收集了线上的一些报文&#xff0c;其中有一个疑问一直在我脑海里面&#xff0c;如下&#xff1a; 本身处于delay_ack状态的客户端&#xff0c;大概40ms回复一个delay_ack&#xff0c;当收到一个490字节的…

Git 诞生记

你可能有过这样的经历&#xff1a;在 debug 的时候这里加一句&#xff0c;那里减一句&#xff0c;顺便改改参数&#xff0c;不一会你的程序就从一个 bug 增加到了无数个 bug 。最重要的是&#xff0c;你完全想不起来自己到底改了几个地方&#xff0c;原来的程序到底长什么样子了…

使用pandas进行量化回测(akshare)

本人看法&#xff0c;也就比excel高级一点&#xff0c;距离backtrader这些框架又差一点。做最基础的测试可以&#xff0c;如果后期加入加仓功能&#xff0c;或者是止盈止损等功能&#xff0c;很不合适。只能做最简单的技术指标测试。所以别太当回事。 导包&#xff0c;常用包导…

使用vue+webpack从零搭建项目

vue到现在已经成为一个热门的框架&#xff0c;在项目实践当中&#xff0c;如果想要创建一个新项目&#xff0c;通常都会使用vue-cli的脚手架工具&#xff0c;毋容置疑能够方便很多&#xff0c;很多东西也不需要自己亲自去配置。都知道&#xff0c;脚手架其实是vue结合webpack去…

怎样从Linux终端管理进程:10个你必须知道的命令

本文由 极客范 - Ben Zhang 翻译自 Chris Hoffman。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。Linux终端有一系列有用的命令。它们可以显示正在运行的进程、杀死进程和改变进程的优先级。本文列举了一些经典传统的命令和一些有用新…

搞了个30天学习量化的数据资料,可以bt做全球。数据链接白送

待会上传代码,资料,打包好了,拿来就能用。累死我了,搞了两天,必须收费,绝不允许白嫖。不然对不起我熬夜,那么辛苦。 确定后,扫描百度网盘 链接:https://pan.baidu.com/s/1C0k6zkjHchFVQaHe4nRMsg?pwd=kkgb 提取码:kkgb 如何回测k线图 如何根据形态选股

自学Linux命令的四种方法

本文由 极客范 - 小道空空 翻译自 Danny Stieben。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。如果你想成为Linux高手&#xff0c;那么掌握一些Linux命令是必不可少的。下面是自学Linux命令的四种方法。 每日提示 学习Linux命令的…

第五周学习总结

第六章&#xff1a; 主要内容: 1.接口 2.实现接口 3.理解接口 4.接口回调 5.接口与多态 6.接口变量做参数 7.面向接口编程 Example6_1: Example6_2: Example6_3: Example6_4: Example6_5: Example6_6: 总结&#xff1a;这章节没有较大问题&#xff0c;例题也都做了一遍。蛮顺利…

Android 设备的CPU类型(通常称为”ABIs”)

armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它.arm64-v8a: 第8代、64位ARM处理器&#xff0c;很少设备&#xff0c;三星 Galaxy S6是其中之一。armeabi: 第5代、第6代的ARM处理器&#xff0c;早期的手机用的比较多。x86: 平板、模…

通过8个技巧让你成为一个超强的Linux终端用户

本文由 极客范 - minejo 翻译自 Chris Hoffman。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。使用Linux终端不仅仅是只输入命令。学习这些基本的技巧&#xff0c;你就会逐渐掌握Bash shell&#xff0c;这个在大多数Linux发行版上默认…

时序数据库连载系列: 时序数据库一哥InfluxDB之存储机制解析

2019独角兽企业重金招聘Python工程师标准>>> InfluxDB 的存储机制解析 本文介绍了InfluxDB对于时序数据的存储/索引的设计。由于InfluxDB的集群版已在0.12版就不再开源&#xff0c;因此如无特殊说明&#xff0c;本文的介绍对象都是指 InfluxDB 单机版 1. InfluxDB 的…

如何在Linux上提高文本的搜索效率

本文由 极客范 - minejo 翻译自 Xmodulo。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。对于系统管理员或程序员来说&#xff0c;当需要在复杂配置的目录中或者在大型源码树中搜寻特定的文本或模式时&#xff0c;grep类型的工具大概是…

JSch - Java Secure Channel : java 代码实现服务器远程操作

一、前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 JSch是SSH2的纯Java实现 。 JSch允许您连接到sshd服务器并使用端口转发&#xff0c;X11转发&#xff0c;文件传输等&#xff0…

前嗅ForeSpider教程:数据建表

今天&#xff0c;小编为大家带来的教程是&#xff1a;如何在前嗅ForeSpider中&#xff0c;进行数据建表操作及各注意事项。主要内容包括&#xff1a;快速建表&#xff0c;自由建表&#xff0c;字段参数&#xff0c;数据表的创建&#xff0c;关联与删除&#xff0c;以及表单变更…

世纪大争论:Linux还是GNU/Linux?

本文由 极客范 - 爱开源的贡献开源社区 翻译自 Chris Hoffman。欢迎加入极客翻译小组&#xff0c;同我们一道翻译与分享。转载请参见文章末尾处的要求。我们在网上已经习惯用“Linux”来称呼Linux操作系统了&#xff0c;然而&#xff0c;偶尔也用“GNU/Linux”来称呼和指代同…

PyTorch Softmax

PyTorch provides 2 kinds of Softmax class. The one is applying softmax along a certain dimension. The other is do softmax on a spatial matrix sized in B, C, H, W. But it seems like some problems existing in Softmax2d. : ( 转载于:https://www.cnblogs.com/hiz…

同时寻找最大数和最小数的最优算法 第二大数

我们知道&#xff0c;在一个容量为n的数据集合中寻找一个最大数&#xff0c;不管用什么样的比较算法&#xff0c;至少要比较n-1次&#xff0c;就算是用竞标赛排序也得比较n-1次&#xff0c;否则你找到的就不能保证是最大的数。那么&#xff0c;在一个容量为n的数据集合中同时寻…

浅谈mpvue项目目录和文件结构

2019独角兽企业重金招聘Python工程师标准>>> 在Visual Studio Code里面打开项目文件夹&#xff0c;我们可以看到类似如下的文件结构&#xff1a; 1、package.json文件 package.json是项目的主配置文件&#xff0c;里面包含了mpvue项目的基本描述信息、项目所依赖的各…

进程间通信---信号

什么是信号&#xff1f; 】 信号处理流程 信号类型 发送信号的函数 参数sig&#xff1a;代表 信号 接收信号的函数 参数 handle 的处理方式有几种&#xff1f; 实例代码 实例逻辑 图中的等待操作使用&#xff1a;pause&#xff08;&#xff09;函数 代码 在这里插入代码片…

大白话解说,半分钟就懂 --- 分布式与集群是什么 ? 区别是什么?

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 PS&#xff1a;这篇文章算是笔记&#xff0c;仅部分文字是原创&#xff0c;相当内容只是收集、整理、提炼、总结别人写的。 没有标为原创…