时间序列是随时间变化的序列,总体可分为 平稳 与 非平稳序列;

 

平稳序列

平稳序列即经由 样本时间序列 得到的拟合曲线在未来一段时间内仍能沿着现有形态发展下去;

数学描述如下

均值和方差 不 随时间 t 变化而变化;

协方差 cov(xt,xt+k) 只与 周期(或者说时间间隔) K 有关,与时间 t 无关;

 

平稳序列又分为严平稳和弱平稳

严平稳:序列值的分布不随时间变化而变化;

如 白噪声序列,无论怎么取,均值为 0,方差为 S^2;

既然没有任何变化,就没有研究的价值了

弱平稳:期望与相关系数(依赖性)不变,也就是说 当前序列值 与 它前些时刻的值 有关,存在依赖性;

有依赖才有研究价值

 

小结

平稳的时间序列才有研究价值;

时间序列分析针对的是 弱平稳序列;

 

差分变换

通常情况下,非平稳序列可通过 差分变换 转化为平稳序列

DataFrame.diff(periods=1, axis=0)

periods:差分步长,xt-xt-periods

axis:维度;

 

fig, axs = plt.subplots(4, 1)

##### 非平稳序列
np.random.seed(12345)
ut = np.random.randint(-30, 30, size=(100))
xt = np.cumsum(ut) + 500
axs[0].plot(xt)


##### 差分变换
df = pd.DataFrame(xt)
df_diff1_1 = df.diff()      ### 1阶差分,步长为1
df_diff1_2 = df.diff(2)     ### 1阶差分,步长为2
df_diff2 = df_diff1_1.diff()    ### 2阶差分,步长为1
axs[1].plot(df_diff1_1)
axs[2].plot(df_diff1_2)
axs[3].plot(df_diff2)
plt.show()

二阶差分是 对 一阶差分 的差分

 

输出:非平稳序列、一阶差分/步长1、1阶差分/步长2、2阶差分/步长1

可以看到 原始数据 非平稳,后面的基本上是平稳序列;

 

平稳性检测

通过差分变换 可以使得 序列平稳,但是该采用什么样的差分变换,变换后是否平稳呢?

我们可以通过 ADF 单位根检验方法 来检测序列的平稳性

 

时间序列处理

事实上,在处理时间序列时,我们首先要检测 序列的平稳性,大致流程如下

 

ADF 平稳性检测

ADF检验总结一句话:如果序列是平稳的,则不存在单位根, 否则就会存在单位根

def adfuller(x, maxlag=None, regression="c", autolag='AIC',
             store=False, regresults=False):
    """
    Parameters
    ----------
    x : array_like, 1d
        The data series to test.
    maxlag : int
        Maximum lag which is included in test, default 12*(nobs/100)^{1/4}.
    regression : {'c','ct','ctt','nc'}
        Constant and trend order to include in regression.
        * 'c' : constant only (default).
        * 'ct' : constant and trend.
        * 'ctt' : constant, and linear and quadratic trend.
        * 'nc' : no constant, no trend.

    Returns
    -------
    adf : float
        The test statistic.
    pvalue : float
        MacKinnon's approximate p-value based on MacKinnon (1994, 2010).
    """

returns:adf 是检测结果,pvalue 是 p 值

 

还用 差分变换 那节的例子,来解释下 ADF 检测的用法

np.random.seed(12345)
ut = np.random.randint(-30, 30, size=(100))
xt = np.cumsum(ut)

print(ts.adfuller(xt))
# (-1.5243530203505073, 0.5214317018385488, 0, 99, {'1%': -3.498198082189098, '5%': -2.891208211860468, '10%': -2.5825959973472097}, 845.9136155157069)

##### 差分变换
df = pd.DataFrame(xt)
df_diff1_1 = df.diff()      ### 1阶差分,步长为1
print(ts.adfuller(df_diff1_1[1:]))
# (-3.849731498648273, 0.0024375726243445746, 12, 86, {'1%': -3.5087828609430614, '5%': -2.895783561573195, '10%': -2.5850381719848565}, 740.2735055354956)
df_diff1_2 = df.diff(2)     ### 1阶差分,步长为2
print(ts.adfuller(df_diff1_2[2:]))
# (-4.012534867488554, 0.001346278712964153, 11, 86, {'1%': -3.5087828609430614, '5%': -2.895783561573195, '10%': -2.5850381719848565}, 736.1426417807885)
df_diff2 = df_diff1_1.diff()    ### 2阶差分,步长为1
print(ts.adfuller(df_diff2[2:]))
# (-5.307353752105175, 5.286830381426628e-06, 10, 87, {'1%': -3.5078527246648834, '5%': -2.895382030636155, '10%': -2.584823877658872}, 744.9060722567168)

输出 第 1 个值我们称为  test result,第 2 个值我们称为 p-value;

ADF 检验的假设是 存在单位根,有两种方式检验 假设 是否成立:

1. 如果 test result 显著小于 3 个置信度(1%、5%、10%) 的临界统计值,说明是 拒绝 原假设的;

2. 如果 p-value 小于 0.05,说明是 拒绝 原假设的;

实例解读

原始数据(非平稳) 检测结果为 -1.5,大于三个临界值 -3.4,-2.8,-2.5,说明 原假设成立,存在单位根,证明为 非平稳序列;

p-value 为 0.5,远大于 0.05,原假设成立,存在单位根,证明为 非平稳序列;

 

这个逻辑挺绕的,总结一下,要想 序列平稳,test result 和 p-value 都要小

 

 

 

参考资料:

https://www.zhihu.com/question/29128649  什么是时间序列模型,什么是弱平稳和严格平稳?

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.diff.html    差分

https://www.lizenghai.com/archives/595.html    基于Python的ADF单位根检验方法——时间序列平稳检验

https://www.zhihu.com/question/25946431    如何将非平稳的时间序列变为平稳的时间序列?

https://blog.csdn.net/qtlyx/article/details/53456480    时间序列分析这件小事(六)--非平稳时间序列与差分

 

https://blog.csdn.net/dingming001/article/details/73732102    差分变换进阶【有空再看看