精华内容
下载资源
问答
  • 当我们有一个新的时间序列数据时,怎么判断它是否是平稳的呢?时间序列平稳性检验方法,可分为三类:图形分析方法简单统计方法假设检验方法一、图形分析方法图形分析方法是一种最基本、最简单直接的方法...

    当我们有一个新的时间序列数据时,怎么判断它是否是平稳的呢?

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

    1. 图形分析方法

    2. 简单统计方法

    3. 假设检验方法

    一、图形分析方法

    图形分析方法是一种最基本、最简单直接的方法,即绘制图形,肉眼判断。

    可直接可视化时间序列数据,也可以可视化时间序列的统计特征。

    可视化数据

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

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

    import numpy as np
    import pandas as pd
    import akshare as ak
    from matplotlib import pyplot as plt
    
    np.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()

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

    可视化统计特征

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

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

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

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

    ab70810e4e6365bfe02b88459c6f252e.png

    自相关的计算公式为根据滞后期k将序列拆成等长的两个序列,计算这两个序列的相关性得到滞后期为k时的自相关性。举例:

    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_pacf
    
    fig, 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()

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

    二、简单统计方法

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

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

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

    import numpy as np
    
    np.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

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

    三、假设检验方法

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

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



    预备知识

    确定趋势

    如果时间序列有“确定趋势”,比如

    其中, 即为确定趋势。

    期望中有时间变量,随时间变化,所以不是平稳时间序列。

    含有确定趋势的序列的差分过程是过度差分:

    过度差分不但会使序列样本容量减少,还会使序列的方差变大。差分后的序列会存在自相关性,但这种自相关性是毫无意义的。

    所以应该使用“退势”的方法获得平稳序列,如下:
    但是  如何确定,趋势拟合。消除序列中的时间趋势后,即为平稳序列,所以称这样的序列为“趋势平稳”序列或“退势平稳”序列。

    随机趋势

    另一种导致时间序列非平稳的因素为“随机趋势”。比如随机游走模型:
    ,其中  为白噪声

    来自  的任何波动对  都具有永久性的冲击,最主要的是其影响力不随时间而衰减,称  为这个模型的“随机趋势”。


    带漂移项的随机游走模型:
    , 其中  为常数
        

    除持续受到来自随机趋势  的影响外,还受一个常数项  的影响。


    以上对随机游走或带漂移项的随机游走进行一阶差分,均可消除随机趋势的影响,得到一个平稳序列,故称“差分平稳”序列。

    d阶单整

    称平稳的时间序列为“零阶单整”(Integrated of order zero),记为 。
    如果时间序列的一阶差分是平稳的,则称为“一阶单整”(Integrated of order one),记为 ,也称为“单位根过程”(unit root process)。

    更一般地,如果时间序列的 阶差分为平稳过程,则称为“d阶单整”(Integrated of order d),记为 。

    什么是单位根

    考虑如下基础模型:
    ,其中  为白噪声
    和随机游走模型很像,只不过多了个系数 。

    我们知道随机游走是非平稳的,但是当  时,这个序列就变成平稳的了。

    当  时,随着  的增大, 最终会收敛,长期来看  是平稳的。
    当  时, 为无规律非平稳的随机游走过程;
    当  时, 为爆炸式增长的非平稳过程。

     等于1时  就是我们所说的单位根。

    画图对比以下可能会更清晰一些

    import numpy as np
    from matplotlib import pyplot as plt
    
    np.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 y
    
    plt.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()
    472f08e213462a8380da7931330f11b9.png

    一阶差分方程
            
                    
                             
     为一阶随机差分方程(因为含有随机项)
     无随机项为确定性差分方程(但非齐次,因为含常数项 )
     为对应的齐次差分方程

    根据差分方程理论, 的稳定性和  的稳定性是一样的,而  是否稳定取决于  是否稳定,所以判断一个差分方程是否稳定,只要看它对应的齐次差分方程是否有稳定的通解即可。

    以上齐次差分方程对应的特征方程为:, 称为差分方程的特征根。

    只有 ,即特征方程的根落在复平面的单位圆以内的时候,过程才会平稳。若果根正好落在圆上,称为单位根,为非平稳过程,比如随机游走的情形。如果落在圆外,则为爆炸式增长的非平稳过程。

    差分方程写成滞后算子的形式是这样的
    , 为滞后算子

    对应特征方程(逆特征方程)为:
    , 称为自回归滞后算子多项式的特征根。

    显然,差分方程的特征值λ与自回归滞后算子多项式的特征根z是互为倒数。
     均小于1(特征方程的根都在单位圆内)时是平稳的,对应的  均大于1(逆特征方程的根都在圆外)时是平稳的。

    更一般的n阶差分方程

    对应的齐次差分方程为:


    该齐次差分方程的特征方程为:

    根均在单位圆内是平稳的。

    滞后算子形式(逆特征方程)为:

    根均在单位圆外是平稳的。

    一般直接计算高阶差分方程的根比较复杂,有些简单规则可以用来检验高阶差分方程的稳定性。

    n阶差分方程中,所有特征根均位于单位圆内的充分条件为:

    n阶差分方程中,所有特征根均位于单位圆内的必要条件为:

    如果 ,至少有一个特征根等于1。

    一个或多个特征根等于1的时间序列,称为单位根过程

    单位根(unit root)检验就是检验该差分方程的特征方程(characteristic equation)的各个特征根(characteristic root)是均小于1,还是存在等于1的情况。没有检验均大于1的情况,是因为当根均大于1时为爆炸型发散序列,日常数据中基本不存在。



    检验方法

    DF检验

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

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

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

    对应检验回归式为:
    (i) 无漂移项自回归过程:
    (ii) 带漂移项自回归过程:
    (iii) 带漂移项和趋势项自回归过程:
    其中  是常数项, 是时间趋势项, 为白噪声无自相关性。

    • 原假设 (存在单位根,时间序列是非平稳的)

    • 备择假设 (不存在单位根,时间序列是平稳的--不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

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

    下图是网络中看到的单位根检验流程图以供参考(根据该流程可以确定序列是何种类型下的平稳,即便非平稳也可知道是何种类型下的非平稳序列):

    b1e73740a92e2dd185c48c51b48751bb.png
    单位根检验流程

    ADF检验

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

    e74c20e79873cef32b4079a1ebfa25c3.png

    假设条件不变:

    • 原假设 (存在单位根,时间序列是非平稳的)

    • 备择假设 (不存在单位根,时间序列是平稳的--不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

    检验流程同DF检验一致。若要严格判断序列是否是宽平稳的,可以直接检验是否不含截距项和趋势项平稳;若不能拒绝原假设(如p>0.05),序列非平稳,其实仍有必要检验序列是否是趋势平稳的。非平稳且非趋势平稳,可以使用一阶差分等平稳化方法处理后再做检验,若是趋势平稳,困于过度差分则不宜使用差分方式平稳化。

    生成一个趋势平稳序列:

    import numpy as np
    from matplotlib import pyplot as plt
    
    np.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()
    5587b4020d78e42d27b5930c6c3da0f4.png

    检验是否平稳:

    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())
    31b87d2c42ff63395bf6dd3c99025676.png

    说明:
    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())
    f9885c698f2f70b4beea3c06028dca41.png

    可以看到差分前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())
    0803596efd3e549688a03fe076c0573e.png

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

    PP检验

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

    • 原假设 (存在单位根,时间序列是非平稳的)

    • 备择假设 (不存在单位根,时间序列是平稳的--不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

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

    import numpy as np
    from arch.unitroot import PhillipsPerron
    
    np.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())
    6281e7a6fc072d36b1c4a8833738ee41.png

    不指定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 DFGLS
    
    np.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())
    d3bd9a939a489bb6d97ca7ceb0869b8a.png

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

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

    import numpy as np
    from arch.unitroot import DFGLS
    
    np.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())
    ccde421122197e2d60354e6c538cf605.png

    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 KPSS
    
    np.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())
    53726e06cda9bfb7db732b78537bae9c.png

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

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

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

    Method/ModelPackage/Module (function/class)
    Augmented Dickey-Fuller teststatsmodels.tsa.stattools (adfuller)
    arch.unitroot (ADF)
    Phillip-Perron testarch.unitroot (PhillipsPerron)
    Dickey-Fuller GLS Testarch.unitroot (DFGLS)
    KPSS teststatsmodels.tsa.stattools (kpss)
    arch.unitroot (KPSS)
    Zivot-Andrew teststatsmodels.tsa.stattools (zivot_andrews)
    arch.unitroot (ZivotAndrews)
    Variance Ratio testarch.unitroot (VarianceRatio)
    参考链接


    [1]  http://course.sdu.edu.cn/G2S/eWebEditor/uploadfile/20140525165255371.pdf
    [2]  https://max.book118.com/html/2016/0518/43276093.shtm
    [3]  https://doc.mbalib.com/view/ef1783f2fa1892f6ad016281ed743d78.html
    [4]  https://www.stata.com/manuals13/tsdfgls.pdf
    [5]  https://zhuanlan.zhihu.com/p/50553021
    [6]  https://arch.readthedocs.io/en/latest/index.html

    b99546ff26cd9b9f43ba5c547fcddcea.png

    E N D

    878bfd4f6f43ef264d13139bd77538e3.png

    a8cb22702c7e4348e656ab23883eef63.png

    展开全文
  • 来源:TimeSeries当我们有一个新的时间序列数据时,怎么判断它是否是平稳的呢?时间序列平稳性检验方法,可分为三类:图形分析方法简单统计方法假设检验方法一、图形分析方法图形分析方法是一...

    来源:TimeSeries

    44c209cba1920c0e02f0cea8fcfefc07.gif

    当我们有一个新的时间序列数据时,怎么判断它是否是平稳的呢?

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

    1. 图形分析方法

    2. 简单统计方法

    3. 假设检验方法

    一、图形分析方法

    图形分析方法是一种最基本、最简单直接的方法,即绘制图形,肉眼判断。

    可直接可视化时间序列数据,也可以可视化时间序列的统计特征。

    可视化数据

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

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

    import numpy as np
    import pandas as pd
    import akshare as ak
    from matplotlib import pyplot as plt
    
    np.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()

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

    可视化统计特征

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

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

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

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

    5be555a2f5f23718fba1242a2acfa1bf.png

    自相关的计算公式为根据滞后期k将序列拆成等长的两个序列,计算这两个序列的相关性得到滞后期为k时的自相关性。举例:

    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_pacf
    
    fig, 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()

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

    二、简单统计方法

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

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

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

    import numpy as np
    
    np.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

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

    三、假设检验方法

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

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

    预备知识

    确定趋势

    如果时间序列有“确定趋势”,比如

    其中, 即为确定趋势。

    期望中有时间变量,随时间变化,所以不是平稳时间序列。

    含有确定趋势的序列的差分过程是过度差分:

    过度差分不但会使序列样本容量减少,还会使序列的方差变大。差分后的序列会存在自相关性,但这种自相关性是毫无意义的。

    所以应该使用“退势”的方法获得平稳序列,如下:
    但是 如何确定,趋势拟合。消除序列中的时间趋势后,即为平稳序列,所以称这样的序列为“趋势平稳”序列或“退势平稳”序列。

    随机趋势

    另一种导致时间序列非平稳的因素为“随机趋势”。比如随机游走模型:
    ,其中 为白噪声

    来自 的任何波动对 都具有永久性的冲击,最主要的是其影响力不随时间而衰减,称 为这个模型的“随机趋势”。


    带漂移项的随机游走模型:
    , 其中 为常数
       

    除持续受到来自随机趋势 的影响外,还受一个常数项 的影响。


    以上对随机游走或带漂移项的随机游走进行一阶差分,均可消除随机趋势的影响,得到一个平稳序列,故称“差分平稳”序列。

    d阶单整

    称平稳的时间序列为“零阶单整”(Integrated of order zero),记为 。
    如果时间序列的一阶差分是平稳的,则称为“一阶单整”(Integrated of order one),记为 ,也称为“单位根过程”(unit root process)。

    更一般地,如果时间序列的 阶差分为平稳过程,则称为“d阶单整”(Integrated of order d),记为 。

    什么是单位根

    考虑如下基础模型:
    ,其中 为白噪声
    和随机游走模型很像,只不过多了个系数 。

    我们知道随机游走是非平稳的,但是当 时,这个序列就变成平稳的了。

    当 时,随着 的增大, 最终会收敛,长期来看 是平稳的。
    当 时, 为无规律非平稳的随机游走过程;
    当 时, 为爆炸式增长的非平稳过程。

    等于1时 就是我们所说的单位根。

    画图对比以下可能会更清晰一些

    import numpy as np
    from matplotlib import pyplot as plt
    
    np.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 y
    
    plt.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()
    eb6a4027e979762b6cc2fb08ce0612d0.png

    一阶差分方程
           
                   
                           
    为一阶随机差分方程(因为含有随机项)
    无随机项为确定性差分方程(但非齐次,因为含常数项 )
    为对应的齐次差分方程

    根据差分方程理论, 的稳定性和 的稳定性是一样的,而 是否稳定取决于 是否稳定,所以判断一个差分方程是否稳定,只要看它对应的齐次差分方程是否有稳定的通解即可。

    以上齐次差分方程对应的特征方程为:, 称为差分方程的特征根。

    只有 ,即特征方程的根落在复平面的单位圆以内的时候,过程才会平稳。若果根正好落在圆上,称为单位根,为非平稳过程,比如随机游走的情形。如果落在圆外,则为爆炸式增长的非平稳过程。

    差分方程写成滞后算子的形式是这样的
    , 为滞后算子

    对应特征方程(逆特征方程)为:
    , 称为自回归滞后算子多项式的特征根。

    显然,差分方程的特征值λ与自回归滞后算子多项式的特征根z是互为倒数。
    均小于1(特征方程的根都在单位圆内)时是平稳的,对应的 均大于1(逆特征方程的根都在圆外)时是平稳的。

    更一般的n阶差分方程

    对应的齐次差分方程为:


    该齐次差分方程的特征方程为:

    根均在单位圆内是平稳的。

    滞后算子形式(逆特征方程)为:

    根均在单位圆外是平稳的。

    一般直接计算高阶差分方程的根比较复杂,有些简单规则可以用来检验高阶差分方程的稳定性。

    n阶差分方程中,所有特征根均位于单位圆内的充分条件为:

    n阶差分方程中,所有特征根均位于单位圆内的必要条件为:

    如果 ,至少有一个特征根等于1。

    一个或多个特征根等于1的时间序列,称为单位根过程

    单位根(unit root)检验就是检验该差分方程的特征方程(characteristic equation)的各个特征根(characteristic root)是均小于1,还是存在等于1的情况。没有检验均大于1的情况,是因为当根均大于1时为爆炸型发散序列,日常数据中基本不存在。


    检验方法

    DF检验

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

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

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

    对应检验回归式为:
    (i) 无漂移项自回归过程:
    (ii) 带漂移项自回归过程:
    (iii) 带漂移项和趋势项自回归过程:
    其中 是常数项, 是时间趋势项, 为白噪声无自相关性。

    • 原假设 (存在单位根,时间序列是非平稳的)

    • 备择假设 (不存在单位根,时间序列是平稳的--不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

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

    下图是网络中看到的单位根检验流程图以供参考(根据该流程可以确定序列是何种类型下的平稳,即便非平稳也可知道是何种类型下的非平稳序列):

    3fdaf9a5394db2f34c33698ac5b38629.png
    单位根检验流程

    ADF检验

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

    eca7bfc0494ff0cbd3d5b8abb34991c7.png

    假设条件不变:

    • 原假设 (存在单位根,时间序列是非平稳的)

    • 备择假设 (不存在单位根,时间序列是平稳的--不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

    检验流程同DF检验一致。若要严格判断序列是否是宽平稳的,可以直接检验是否不含截距项和趋势项平稳;若不能拒绝原假设(如p>0.05),序列非平稳,其实仍有必要检验序列是否是趋势平稳的。非平稳且非趋势平稳,可以使用一阶差分等平稳化方法处理后再做检验,若是趋势平稳,困于过度差分则不宜使用差分方式平稳化。

    生成一个趋势平稳序列:

    import numpy as np
    from matplotlib import pyplot as plt
    
    np.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()
    608a1dc573a5f8056a99fd5360361060.png

    检验是否平稳:

    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())
    b0f4617630382bb55eb7e24d7692f558.png

    说明:
    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())
    0e576b864587670aeb4d78fc1008beea.png

    可以看到差分前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())
    cc9ee8d968c069eaadc04e489bc07bf2.png

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

    PP检验

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

    • 原假设 (存在单位根,时间序列是非平稳的)

    • 备择假设 (不存在单位根,时间序列是平稳的--不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

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

    import numpy as np
    from arch.unitroot import PhillipsPerron
    
    np.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())
    2e3dc4bcbee31301493bab9ef35bffdc.png

    不指定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 DFGLS
    
    np.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())
    f4ae6d74d3d1f8b58293d6b202732b39.png

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

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

    import numpy as np
    from arch.unitroot import DFGLS
    
    np.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())
    3c7c39e2cf20bd430feeb7626258c5c2.png

    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 KPSS
    
    np.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())
    08d047200def0cfa5949e1b1d5b4c570.png

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

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

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

    Method/ModelPackage/Module (function/class)
    Augmented Dickey-Fuller teststatsmodels.tsa.stattools (adfuller)
    arch.unitroot (ADF)
    Phillip-Perron testarch.unitroot (PhillipsPerron)
    Dickey-Fuller GLS Testarch.unitroot (DFGLS)
    KPSS teststatsmodels.tsa.stattools (kpss)
    arch.unitroot (KPSS)
    Zivot-Andrew teststatsmodels.tsa.stattools (zivot_andrews)
    arch.unitroot (ZivotAndrews)
    Variance Ratio testarch.unitroot (VarianceRatio)

    参考链接
    [1]  http://course.sdu.edu.cn/G2S/eWebEditor/uploadfile/20140525165255371.pdf
    [2]  https://max.book118.com/html/2016/0518/43276093.shtm
    [3]  https://doc.mbalib.com/view/ef1783f2fa1892f6ad016281ed743d78.html
    [4]  https://www.stata.com/manuals13/tsdfgls.pdf
    [5]  https://zhuanlan.zhihu.com/p/50553021
    [6]  https://arch.readthedocs.io/en/latest/index.html

    ---------End---------

    顺便给大家推荐下我的微信视频号「Python数据之道」,欢迎扫码关注。

    e046097669d75a147132673799429bdb.gif

    展开全文
  • 时间序列的平稳性检验方法汇总。主要检验方法为:DF检验、ADF检验、PP检验、DF-GLS检验、KPSS检验等,含代码示例,并增加了预备知识:时间序列的确定趋势、随机趋势、d阶单整及单位根概念的解释。

    上文我们已经知道了什么是时间序列的平稳性,也见到了一些平稳时间序列和非平稳的时间序列,那么当我们有一个新的时间序列数据时,怎么判断它是否是平稳的呢?

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

    1. 图形分析方法
    2. 简单统计方法
    3. 假设检验方法

    一、图形分析方法

    图形分析方法是一种最基本、最简单直接的方法,即绘制图形,肉眼判断。

    可直接可视化时间序列数据,也可以可视化时间序列的统计特征。

    可视化数据

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

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

    import numpy as np
    import pandas as pd
    import akshare as ak
    from matplotlib import pyplot as plt
    
    np.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);而对于非平稳的数据,退化会发生得更慢,或存在先减后增或者周期性的波动等变动。

    自相关的计算公式为根据滞后期k将序列拆成等长的两个序列,计算这两个序列的相关性得到滞后期为k时的自相关性。

    举例:

    X = [ 2 , 3 , 4 , 3 , 8 , 7 ] \small X = [2,3,4,3,8,7] X=[2,3,4,3,8,7]

    A = [ 2 , 3 , 4 , 3 , 8 ] \small A = [2,3,4,3,8] A=[2,3,4,3,8]

    B = [ 3 , 4 , 3 , 8 , 7 ] \small B = [3,4,3,8,7] B=[3,4,3,8,7]

    X ˉ = ∑ i = 1 6 X i = 4.5 \small \bar{X}=\sum_{i=1}^{6}X_i=4.5 Xˉ=i=16Xi=4.5

    s 2 ( X ) = 1 6 ∑ i = 1 6 ( X i − X ˉ ) ( X i − X ˉ ) = 4.916. \small s^2(X)=\frac{1}{6}\sum_{i=1}^{6}{(X_i-\bar{X})(X_i-\bar{X})}=4.916. s2(X)=61i=16(XiXˉ)(XiXˉ)=4.916.

    r ( 1 ) = 1 5 ∑ i = 1 5 ( A i − X ˉ ) ( B i − X ˉ ) = 1.75 \small r(1)=\frac{1}{5}\sum_{i=1}^{5}{(A_i-\bar{X})(B_i-\bar{X})}=1.75 r(1)=51i=15(AiXˉ)(BiXˉ)=1.75

    A C F ( 1 ) = r ( 1 ) s 2 ( X ) = 1.75 4.91666667 = 0.3559322 \small ACF(1)=\frac{r(1)}{s^2(X)}=\frac{1.75}{4.91666667}=0.3559322 ACF(1)=s2(X)r(1)=4.916666671.75=0.3559322

    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_pacf
    
    fig, 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 np
    
    np.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

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


    三、假设检验方法

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

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



    预备知识


    确定趋势

    如果时间序列有“确定趋势”,比如
    y t = β 0 + β 1 t + ε t y_t=\beta_0+\beta_1t+\varepsilon_t yt=β0+β1t+εt
    其中, β 1 t \beta_1 t β1t 即为确定趋势。
    E ( y t ) = β 0 + β 1 t \small E(y_t)=\beta_0+\beta_1t E(yt)=β0+β1t
    期望 E ( y t ) \small E(y_t) E(yt)中有时间变量,随时间变化,所以不是平稳时间序列。

    含有确定趋势的序列的差分过程是过度差分:
    y t − y t − 1 = α + ε t − ε t − 1 y_t-y_{t-1}=\alpha+\varepsilon_t-\varepsilon_{t-1} ytyt1=α+εtεt1
    过度差分不但会使序列样本容量减少,还会使序列的方差变大。差分后的序列会存在自相关性,但这种自相关性是毫无意义的。

    所以应该使用“退势”的方法获得平稳序列,如下:
    y t ∗ = y t − β 1 t = β 0 + e t y_t^*=y_t-\beta_1t=\beta_0+e_t yt=ytβ1t=β0+et
    但是 β 1 \beta_1 β1 如何确定,趋势拟合。消除序列中的时间趋势后,即为平稳序列,所以称这样的序列为“趋势平稳”序列或“退势平稳”序列。

    随机趋势

    另一种导致时间序列非平稳的因素为“随机趋势”。比如随机游走模型:
    y t = y t − 1 + ε t y_t=y_{t-1}+\varepsilon_t yt=yt1+εt,其中 { ε t } \small \{ \varepsilon_t \} {εt} 为白噪声
    y t − y t − 1 = ε i y_t-y_{t-1}=\varepsilon_i ytyt1=εi
    来自 { ε t } \small \{ \varepsilon_t \} {εt} 的任何波动对 { y t } \small \{ y_t \} {yt} 都具有永久性的冲击,最主要的是其影响力不随时间而衰减,称 { ε t } \small \{ \varepsilon_t \} {εt} 为这个模型的“随机趋势”。

    带漂移项的随机游走模型:
    y t = β 0 + y t − 1 + ε t y_t=\beta_0+ y_{t-1}+\varepsilon_t yt=β0+yt1+εt, 其中 β 0 ≠ 0 \beta_0 \neq 0 β0=0 为常数
    y t − y t − 1 = β 0 + ε t y_t-y_{t-1}=\beta_0+\varepsilon_t ytyt1=β0+εt

    除持续受到来自随机趋势 { ε t } \small \{ \varepsilon_t \} {εt} 的影响外,还受一个常数项 β 0 \small \beta_0 β0 的影响。

    以上对随机游走或带漂移项的随机游走进行一阶差分,均可消除随机趋势的影响,得到一个平稳序列,故称“差分平稳”序列。

    d阶单整

    称平稳的时间序列为“零阶单整”(Integrated of order zero),记为 I ( 0 ) \small I(0) I(0)

    如果时间序列的一阶差分是平稳的,则称为“一阶单整”(Integrated of order one),记为 I ( 1 ) \small I(1) I(1),也称为“单位根过程”(unit root process)。

    更一般地,如果时间序列的 阶差分为平稳过程,则称为“d阶单整”(Integrated of order d),记为 I ( d ) \small I(d) I(d)

    什么是单位根

    考虑如下基础模型:
    y t = β 1 y t − 1 + ε t y_t=\beta_1 y_{t-1}+\varepsilon_t yt=β1yt1+εt,其中 { ε t } \small \{ \varepsilon_t \} {εt} 为白噪声
    和随机游走模型很像,只不过多了个系数 β 1 \beta_1 β1

    我们知道随机游走是非平稳的,但是当 ∣ β 1 ∣ < 1 \small |\beta_1|<1 β1<1 时,这个序列就变成平稳的了。

    y t = ( β 1 ) t [ y 0 ] + ∑ i = 1 t − 1 ( β 1 ) i ε i y_t=(\beta_1)^{t}[y_0]+\sum_{i=1}^{t-1}(\beta_1)^i \varepsilon_i yt=(β1)t[y0]+i=1t1(β1)iεi
    ∣ β 1 ∣ < 1 \small |\beta_1|<1 β1<1 时,随着 t t t 的增大, y t y_t yt 最终会收敛,长期来看 { y t } \{ y_t \} {yt} 是平稳的。
    β 1 = 1 \small \beta_1=1 β1=1 时, { y t } \{ y_t \} {yt} 为无规律非平稳的随机游走过程;
    β 1 > 1 \small \beta_1>1 β1>1 时, { y t } \{ y_t \} {yt} 为爆炸式增长的非平稳过程。

    β 1 \beta_1 β1 等于1时 β 1 \beta_1 β1 就是我们所说的单位根。

    画图对比以下可能会更清晰一些:

    import numpy as np
    from matplotlib import pyplot as plt
    
    np.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 y
    
    plt.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()
    

    一阶差分方程

    $y_t=\beta_0+\beta_1y_{t-1}+\varepsilon_t $ ( a ) (a) (a)
    $y_t=\beta_0+\beta_1y_{t-1} $ ( b ) (b) (b)
    $y_t=\beta_1y_{t-1} $ ( c ) (c) (c)
    ( a ) (a) (a) 为一阶随机差分方程(因为含有随机项)
    ( b ) (b) (b) 无随机项为确定性差分方程(但非齐次,因为含常数项 β 0 \beta_0 β0
    ( c ) (c) (c) 为对应的齐次差分方程

    根据差分方程理论, ( a ) (a) (a) 的稳定性和 ( b ) (b) (b) 的稳定性是一样的,而 ( b ) (b) (b) 是否稳定取决于 ( c ) (c) (c) 是否稳定,所以判断一个差分方程是否稳定,只要看它对应的齐次差分方程是否有稳定的通解即可。

    以上齐次差分方程对应的特征方程为: λ − β 1 = 0 \lambda - \beta_1=0 λβ1=0 λ \lambda λ 称为差分方程的特征根。

    只有 ∣ λ ∣ < 1 |\lambda|<1 λ<1,即特征方程的根落在复平面的单位圆以内的时候,过程才会平稳。若果根正好落在圆上,称为单位根,为非平稳过程,比如随机游走的情形。如果落在圆外,则为爆炸式增长的非平稳过程。

    差分方程写成滞后算子的形式是这样的: ( 1 − β 1 L ) y t = 0 (1-\beta_1L)y_t=0 (1β1L)yt=0,[ L \small L L 为滞后算子]

    对应特征方程(逆特征方程)为: 1 − β 1 z = 0 1-\beta_1z=0 1β1z=0,[ z z z 称为自回归滞后算子多项式的特征根。]

    显然,差分方程的特征值λ与自回归滞后算子多项式的特征根z是互为倒数。
    ∣ λ ∣ |\lambda| λ 均小于1(特征方程的根都在单位圆内)时是平稳的,对应的 ∣ z ∣ |z| z 均大于1(逆特征方程的根都在圆外)时是平稳的。

    更一般的n阶差分方程
    y t = β 1 y 1 + β 2 y 2 + . . . + β n y n y_t=\beta_1y_1+\beta_2y_2+...+\beta_ny_n yt=β1y1+β2y2+...+βnyn

    对应的齐次差分方程为:
    y t − β 1 y 1 − β 2 y 2 − . . . − β n y n = 0 y_t-\beta_1y_1-\beta_2y_2-...-\beta_ny_n=0 ytβ1y1β2y2...βnyn=0

    该齐次差分方程的特征方程为:
    λ n − β 1 λ n − 1 − β 2 λ n − 2 − . . . − β n = 0 \lambda^n-\beta_1\lambda^{n-1}-\beta_2\lambda^{n-2}-...-\beta_n=0 λnβ1λn1β2λn2...βn=0
    根均在单位圆内是平稳的。

    滞后算子形式(逆特征方程)为:
    1 − β 1 z − β 2 λ 2 − . . . − β λ n = 0 1-\beta_1z-\beta_2\lambda^2-...-\beta\lambda^n=0 1β1zβ2λ2...βλn=0

    根均在单位圆外是平稳的。

    一般直接计算高阶差分方程的根比较复杂,有些简单规则可以用来检验高阶差分方程的稳定性。

    n阶差分方程中,所有特征根均位于单位圆内的充分条件为:

    ∑ i = 1 n β i < 1 \small \displaystyle \sum_{i=1}^{n}\beta_i<1 i=1nβi<1

    n阶差分方程中,所有特征根均位于单位圆内的必要条件为:

    ∑ i = 1 n ∣ β i ∣ < 1 \small \displaystyle \sum_{i=1}^{n}|\beta_i|<1 i=1nβi<1

    如果 ∑ β i = 1 \small \sum \beta_i=1 βi=1,至少有一个特征根等于1。

    一个或多个特征根等于1的时间序列,称为单位根过程

    单位根(unit root)检验就是检验该差分方程的特征方程(characteristic equation)的各个特征根(characteristic root)是均小于1,还是存在等于1的情况。没有检验均大于1的情况,是因为当根均大于1时为爆炸型发散序列,日常数据中基本不存在。




    检验方法


    DF检验

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

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

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

    对应检验回归式为:
    (i) 无漂移项自回归过程:
    Y t = ρ Y t − 1 + ε t , ( t = 1 , 2 , . . . , n ) , Y 0 = 0 \small Y_t=\rho Y_{t-1}+\varepsilon_t,(t=1,2,...,n),Y_0=0 Yt=ρYt1+εt,(t=1,2,...,n),Y0=0
    (ii) 带漂移项自回归过程:
    Y t = μ + ρ Y t − 1 + ε t , ( t = 1 , 2 , . . . , n ) , Y 0 = 0 \small Y_t=\mu + \rho Y_{t-1}+\varepsilon_t,(t=1,2,...,n),Y_0=0 Yt=μ+ρYt1+εt,(t=1,2,...,n),Y0=0
    (iii) 带漂移项和趋势项自回归过程:
    Y t = μ + β t + ρ Y t − 1 + ε t , ( t = 1 , 2 , . . . , n ) , Y 0 = 0 \small Y_t=\mu + \beta t+\rho Y_{t-1}+\varepsilon_t,(t=1,2,...,n),Y_0=0 Yt=μ+βt+ρYt1+εt,(t=1,2,...,n),Y0=0
    其中 μ \mu μ 是常数项, β t \beta t βt 是时间趋势项, ε t \varepsilon_t εt 为白噪声无自相关性。

    • 原假设 H 0 : ρ = 1 \small H_0: \rho=1 H0:ρ=1(存在单位根,时间序列是非平稳的)
    • 备择假设 H 1 : ρ < 1 \small H_1: \rho<1 H1:ρ<1(不存在单位根,时间序列是平稳的–不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

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

    下图是网络中看到的单位根检验流程图以供参考(根据该流程可以确定序列是何种类型下的平稳,即便非平稳也可知道是何种类型下的非平稳序列):

    单位根检验流程

    ADF检验

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

    假设条件不变:

    • 原假设 H 0 : ρ = 1 \small H_0: \rho=1 H0:ρ=1(存在单位根,时间序列是非平稳的)
    • 备择假设 H 1 : ρ < 1 \small H_1: \rho<1 H1:ρ<1(不存在单位根,时间序列是平稳的–不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

    检验流程同DF检验一致。若要严格判断序列是否是宽平稳的,可以直接检验是否不含截距项和趋势项平稳;若不能拒绝原假设(如p>0.05),序列非平稳,其实仍有必要检验序列是否是趋势平稳的。非平稳且非趋势平稳,可以使用一阶差分等平稳化方法处理后再做检验,若是趋势平稳,困于过度差分则不宜使用差分方式平稳化。

    生成一个趋势平稳序列:

    import numpy as np
    from matplotlib import pyplot as plt
    
    np.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检验的补充。

    • 原假设 H 0 : ρ = 1 \small H_0: \rho=1 H0:ρ=1(存在单位根,时间序列是非平稳的)
    • 备择假设 H 1 : ρ < 1 \small H_1: \rho<1 H1:ρ<1(不存在单位根,时间序列是平稳的–不含截距项和趋势项平稳/含截距项平稳/含截距项和趋势平稳)

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

    import numpy as np
    from arch.unitroot import PhillipsPerron
    
    np.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 DFGLS
    
    np.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 DFGLS
    
    np.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 KPSS
    
    np.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中也实现了单位根检验方法,结果是一样的。

    Method/ModelPackage/Module (function/class)
    Augmented Dickey-Fuller teststatsmodels.tsa.stattools (adfuller)
    arch.unitroot (ADF)
    Phillip-Perron testarch.unitroot (PhillipsPerron)
    Dickey-Fuller GLS Testarch.unitroot (DFGLS)
    KPSS teststatsmodels.tsa.stattools (kpss)
    arch.unitroot (KPSS)
    Zivot-Andrew teststatsmodels.tsa.stattools (zivot_andrews)
    arch.unitroot (ZivotAndrews)
    Variance Ratio testarch.unitroot (VarianceRatio)

    参考链接

    [1]http://course.sdu.edu.cn/G2S/eWebEditor/uploadfile/20140525165255371.pdf [2]https://max.book118.com/html/2016/0518/43276093.shtm [3]https://doc.mbalib.com/view/ef1783f2fa1892f6ad016281ed743d78.html [4]https://www.stata.com/manuals13/tsdfgls.pdf [5]https://zhuanlan.zhihu.com/p/50553021 [6]https://arch.readthedocs.io/en/latest/index.html

    请添加图片描述

    展开全文
  • 对序列的平稳性检验中最常用的方法是单位根的检验。单位根检验是指检查序列中是否存在单位根,如果存在单位根就是非平稳时间序列了。下面是找的解释为什么单位根存在就是非平稳时间序列的原因。 作者:五雷 链接...

    对序列的平稳性的检验中最常用的方法是单位根的检验。单位根检验是指检查序列中是否存在单位根,如果存在单位根就是非平稳时间序列了。下面是找的解释为什么单位根存在就是非平稳时间序列的原因。

    作者:五雷
    链接:https://www.zhihu.com/question/22385598/answer/21221607
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
     

    1. 首先要理解什么是平稳的时间序列,一般时间序列书中给出的平稳的定义以弱平稳为主也就是一个随机变量{y_{t} }的无条件期望不变、方差恒定且协方差不随时间改变,也就是E[y_{t}]=a,Var[y_{t}]=\sigma^{2},Cov(y_{t},y_{t-i})=\sigma_{i},注意关键在于方差是有限的,并且协方差是不随时间改变的。为什么这么设定?主要是给定这些假设前提后,就可以便于技术上的处理,例如平稳变量的谱分析;
    2. 然后,需要知道一般什么样的时间序列是平稳的,例如最常用的ARMA过程y_{t}=A(L)y_{t-1}+B(L)\epsilon_{t},关键在于理解这个方程实际上是一个随机差分方程,差分项就是变量自身,随机项就是\epsilon_{t},将上面这个方程稍微变换,可以看到可以写成y_{t}=B(L)\epsilon_{t}/(1-A(L)),这也就是随机微分方程的一个解,方程1-A(L)=0称为逆特征方程,解也就是逆特征解,跟差分方程的齐次解成倒数关系。现在可以知道,差分方程要平稳,那么其解应该在单位圆内,或者对应的逆特征方程的特征根在单位圆外。如果有根在单位圆上,那么对应着就是有单位根了;
    3. 最后,看什么样的序列存在单位根,最简单的情况y_{t}=y_{t-1}+\epsilon_{t},可以看到对应的特征根是1,这样得出的解为y_{t}=\sum_{i=0}^{\infty }{\epsilon_{t-i}},可以看到这种情况下,离当前时间t很久远的时刻的一个随机冲击对现在的影响仍然没有衰减,这样就是单位根过程了。如果时间序列存在这种情况,对时间序列的未来值的预测就难以进行。再从平稳的定义看,此时随机变量的方差就会逐渐增大到\infty,而不会是有限的方差,这样长期的时间序列就没有预测意义了。

    上面陈述的就是最基本的单位根与非平稳时间序列的关系,那么怎么检验单位根过程?最基本的或者最通用的检验是ADF检验,要理解ADF检验需要弄清假设检验的一般原理,知道检验统计量的size distortion和power的含义,然后就能清楚为什么普通的t检验不能检验是否存在单位根而需要通过monte carlo实验来获取临界值了。系统的学习请参考hamilton~

     

    展开全文
  • 目录时间序列预测时间序列的平稳平稳平稳三级目录 时间序列预测 按照时间的顺序把随机事件变化发展的过程记录下来就构成了一个时间序列。 x1,x2,x3,x4,...,xt 对时间序列进行观察、研究,找寻他变化发展的规律...
  • 2.1 平稳性检验 一 、概率分布与特征统计量 Xt,t=1,2,⋅⋅⋅,tX_t,t=1,2,···,tXt​,t=1,2,⋅⋅⋅,t 在描述一个随机变量时是用 分布函数F(x)F(x)F(x) 特征统计量: 期望E(Xt)E(X_t)E(Xt​),方差D(Xt)D(X_t...
  • 时间序列 简而言之,时间序列就是带时间戳的数值序列。...所谓时间序列的平稳性,是指时间序列的均值,方差以及协方差都是常数,与时间t无关。这样的序列才可以作为我们基于历史预测未来的基础。 满足以上条件属...
  • 平稳性定义所谓时间序列的平稳性,是指时间序列的均值,方差以及协方差都是常数,与时间t无关。这样的序列才可以作为我们基于历史预测未来的基础。满足以上条件属于严平稳,一般达到弱平稳都是可以接受的。平稳性是...
  • 平稳性定义所谓时间序列的平稳性,是指时间序列的均值,方差以及协方差都是常数,与时间t无关。这样的序列才可以作为我们基于历史预测未来的基础。满足以上条件属于严平稳,一般达到弱平稳都是可以接受的。平稳性是...
  • 数学建模数据分析——趋势性检验和平稳性检验 在数学建模比赛中,经常需要对数据进行分析和预处理,常见的比如趋势分析(上升/下降/无明显趋势)和突变分析,很多时候靠人的经验观察得出结论,但这是不够严谨的。...
  • 用 Python 检验时间序列的平稳性

    千次阅读 多人点赞 2020-10-27 08:40:00
    在做时间序列分析时,我们经常要对时间序列进行平稳性检验,而我们常用的软件是SPSS或SAS,但实际上python也可以用来做平稳性检验,而且效果也非常好,今天笔者就讲解一下如何用pyth...
  • [时间序列分析][1]--平稳性,白噪声的检验

    万次阅读 多人点赞 2017-03-20 21:50:02
    [时间序列分析][1]--平稳性,白噪声的检验  这是一个全新的专题,讲关于时间序列分析的。还是老规矩,我使用mathematica来实现。    我个人认为时间序列分析是一门挺重要的科目,如果做建模什么的一定是知道的,...
  • ——平稳性意义如何检验时间序列数据的平稳性?——单位根检验数据不平稳怎么办?——协整检验单整、协整(cointegration)协整检验总结——时间序列数据的一般处理流程 为什么要把时间序列变成平稳的?——平稳性...
  • 时空平稳性,空间自相关、异质性与非平稳性 时间平稳性 时间序列平稳性分为强(严)平稳和弱平稳。其中, 强平稳时序可以理解为对于任意一段时序数据[X1,X2,…Xn],对于任意k时段平移序列[X1+k,X2+k,…Xn+k]与其...
  • R语言:纯随机性检验

    千次阅读 2020-04-19 20:44:46
    (通过平稳性检验判断序列的平稳性) 对于非平稳序列,由于它不具有二阶平稳的性质,所以对它的统计分析要费一些周折,通常要通过进一步的检验、变换或处理,才能确定适当的拟合模型。 对于平稳序列,情况就简单多了...
  • 时间序列学习笔记(2)平稳性

    千次阅读 2017-06-30 22:08:54
    平稳性检验 时序图检验 自相关图检验 自协方差函数 自相关系数 非平稳序列确定性分析 非平稳序列的平稳化 时间序列分解 确定性因素分解 趋势分析 长期趋势分析方法 平滑法分析预测 移动平均 纯随机检验平稳性的相关...
  • 稳定性检验

    千次阅读 2019-09-15 11:13:42
    3种主要的稳健性检验途径 1. 从数据出发, 替换不同的样本进行检验样本是否有问题; 2. 从变量出发,根据其它不同指标对样本进行分类后,检查分类后的样本是否对y特征的显著性有影响; 3. 从计量方法出发, 用...
  • 数据的平稳性

    万次阅读 2015-05-02 15:48:17
    一、数据平稳性 李子奈曾指出,一些非平稳的经济时间序列往往表现出共同的变化趋势,而这些序列间本身不一定有直接的关联,此时,对这些数据进行回归,尽管有较高的R平方,但其结果是没有任何实际意义的。这种情况...
  • 时间序列的平稳性、随机性检验 在拿到时间序列数据后,首先要对数据的随机性和平稳性进行检测, 这两个检测是时间序列预测的重要部分。根据不同检测结果需要采取不同的分析方法。 为什么时间序列要求平稳性呢?平稳...
  • 时间序列分析之ADF检验

    万次阅读 多人点赞 2019-02-06 18:59:09
    在使用很多时间序列模型的时候,如 ARMA、ARIMA,都会要求时间序列是平稳的,所以一般在研究一段时间序列的时候,第一步都需要进行平稳性检验,除了用肉眼检测的方法,另外比较常用的严格的统计检验方法就是ADF检验...
  • (1)平稳性是什么含义? (2)统计分析、时间序列分析对数据的要求? (3)平稳对时间序列有什么用? (4)平稳序列的成分是什么?是不含趋势,还是什么都不含? (5)平稳序列与纯随机序列的区别? 3. 自...
  • 平稳性定义 平稳性是时间序列中最重要的概念之一。 一个平稳的序列意味着它的均值、方差和协方差不随时间变化。 图一:均值是变化的(增长),整体是向上增长的趋势。在- 个平稳的序列里,它不应该有任何的变化...
  • 单纯计算ACF值是没有意义的,我们还需要对 ACF(k) 进行显著性检验,这通常使用ACF图来进行检验,在Python中画ACF图的代码如下: from statsmodels.graphics.tsaplots import plot_acf import matplotlib.pyplot...
  • 文章目录为什么平稳如此重要自回归AR模型一阶自回归过程二阶自回归过程一般自回归过程R语言实现 为什么平稳如此重要 我们知道若随机时间序列XtX_tXt​有如下性质: ①均值E(Xt)=μE(X_{t})=\muE(Xt​)=μ ,均值是与...
  • AR模型与数据平稳性之间的关系

    千次阅读 2017-12-19 22:17:00
     前几天碰到一个序列分析的问题,涉及到自回归(auto-regression, AR)等模型,但如何确定序列的平稳性呢? 发现金融数据分析里,这方面的知识很多,以后用到可以借鉴,例如伍德里奇《计量经济...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,665
精华内容 1,066
关键字:

平稳性检验的意义