Python中非平稳时间序列的处理

徐大白
2周前 阅读 116 点赞 1

以下应用有什么共同点:预测未来三个月的一个家庭的电力消耗;估计在一定时期内道路的交通量;以及预测一个股票在纽约证券交易所上交易的价格。

以上都涉及时间序列数据的概念!如果没有“时间”成分,你就无法准确地预测这些结果。随着越来越多的数据的产生,时间序列预测越来越成为数据科学家掌握的关键技术。

但是时间序列是一个复杂的话题,涉及多个方面。

首先,如果我们希望预测模型工作得很好,使时间序列平稳是关键。为什么?因为你收集的大部分数据都有非平稳的趋势。如果峰值是不稳定的,你怎么能保证模型能正常工作?

本文的重点是研究时间序列数据平稳性的方法。本文假定读者熟悉时间序列ARIMA平稳性概念。下面是一些关于基础知识的参考:

目录表

1.平稳性简介

2.加载数据

3.检验平稳性的方法

——3.1 ADF试验

——3.2 KPSS试验

4.平稳性类型

——4.1 严格平稳

——4.2 趋势平稳

——4.3 差分平稳

5.制作时间序列平稳

——5.1 差分法

——5.2 季节性差异

——5.3 对数变换

1.平稳性介绍

“平稳性”是在使用时间序列数据时会遇到的最重要的概念之一。平稳序列是均值、方差和协方差的性质不随时间变化的序列。

让我们用直观的例子来理解这一点。考虑下面的三张图:

  • 第一张图,我们可以清楚地看到,平均值随着时间的推移而变化(增加),从而导致上升趋势。因此,这是一个非平稳序列。对于平稳性序列,它不应该表现出一种趋势。
  • 第二张图,我们当然看不到序列中的趋势,但是序列的方差是时间的函数。如前所述,平稳序列必须具有恒定方差。
  • 第三张图,随着时间的增加,差值变得更近,这意味着协方差是时间的函数。

上面所示的三个例子都表示非平稳时间序列。现在看看第四张图:

在这种情况下,平均值、方差和协方差不随时间的变化而变化。这就是平稳时间序列的样子。

想象一下-用上述哪张图来预测未来的价值会更容易?第四张图,对吧?大多数统计模型要求系列是平稳的的,以作出有效和精确的预测。

综上所述,平稳时间序列的性质(即均值、方差和协方差)并不依赖于时间。在下一节中,我们将介绍各种方法来检查给定序列是否平稳。

2.加载数据

在本节和接下来的几节中,我将介绍检查时间序列数据平稳性的方法,以及处理任何非平稳序列所需的技术。我还提供了应用各种技术的Python代码。你可以从这个链接下载我们要使用的数据集。

在我们开始分析数据集之前,让我们先加载和预处理数据。

#loading important libraries
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

#reading the dataset
train = pd.read_csv('AirPassengers.csv')

#preprocessing
train.timestamp = pd.to_datetime(train.Month , format = '%Y-%m')
train.index = train.timestamp
train.drop('Month',axis = 1, inplace = True)

#looking at the first few rows
#train.head()

3.检验平稳性的方法

下一步是确定给定的序列是否是平稳的,并相应地处理它。本节将介绍一些常用的方法来执行此检验。

3.1 视觉检验

回想我们在上一节中使用的图。我们能够通过简单地观察每一张图片而识别出平均值和方差随时间而变化的序列。类似地,我们可以绘制数据并确定该序列的属性是否随时间而变化。

train['#Passengers'].plot()

虽然在上面的序列中我们有一个趋势(变化的平均值)是很明显的,但是这种可视化方法并不总能给出准确的结果。最好用一些统计检验来证实观测结果。

3.2 统计检验

我们可以使用统计测试来代替视觉测试,如单位根平稳性检验。单位根表示给定序列的统计性质不随时间变化,这是平稳时间序列的条件。下面是数学解释:

假设我们有一个时间序列:

yt = a*yt-1 + ε t

其中yt 是时刻t和ε t的值为误差项。为了计算yt ,我们需要yt-1的值,即:

yt-1 = a*yt-2 + ε t-1

如果我们对所有的观测都这样做,yt的值将是:

yt = an*yt-n + Σεt-i*ai

如果在上述方程中a的值是1(单位),那么预测将等于 yt-n 和从 t-n 到 t 的所有误差之和,这意味着方差将随时间增加。这是一个时间序列中的单位根。我们知道,对于平稳时间序列来说,方差不一定是时间的函数。单位根检验通过检查a=1的值来检查该序列中的单位根的存在。下面是两种最常用的单位根固定试验

3.3 ADF检验(增广迪基-福勒检验(Augmented Dickey-Fuller test))

Dickey Fuller检验是最受欢迎的统计检验之一。它可以用来确定序列中单位根的存在,从而帮助我们理解序列是否是平稳的。这个测试的零假设和对立假设是:

  • 零假设:该序列具有单位根(A=1的值)
  • 对立假设:序列没有单位根。

如果我们不能拒绝零假设,我们可以说该序列是非平稳的。这意味着序列可以是线性的或者差分平稳的(我们将在下一节中了解更多关于差分平稳的信息)。

Python代码:

#define function for ADF test
from statsmodels.tsa.stattools import adfuller
def adf_test(timeseries):
    #Perform Dickey-Fuller test:
    print ('Results of Dickey-Fuller Test:')
    dftest = adfuller(timeseries, autolag='AIC')
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
    for key,value in dftest[4].items():
       dfoutput['Critical Value (%s)'%key] = value
    print (dfoutput)

#apply adf test on the series
adf_test(train['#Passengers'])

ADF检验结果:ADF检验给出以下结果——检验统计量、p值和临界值在1%、5%和10%置信区间。我们对这个序列的测试结果是:

Results of Dickey-Fuller Test:
Test Statistic                   0.815369
p-value                          0.991880
#Lags Used                      13.000000
Number of Observations Used    130.000000
Critical Value (1%)             -3.481682
Critical Value (5%)             -2.884042
Critical Value (10%)            -2.578770
dtype: float64

平稳性检验:如果检验统计量小于临界值,我们可以拒绝零假设(即序列是平稳的)。当检验统计量大于临界值时,我们无法拒绝零假设(这意味着序列不是平稳的)。

在上面的例子中,检验统计量>临界值,这意味着该序列不是平稳的。这证实了我们最初在视觉检验中看到的观察结果。

3.4 KPSS(Kwiatkowski-Phillips-Schmidt-Shin) 试验


KPSS是另一个检验时间序列平稳性的检验(比Dickey Fuller检验稍受欢迎)。KPSS检验的零假设和对立假设与ADF测试相反,这常常造成混淆。

KPSS检验的作者将零假设定义为过程是趋势平稳的,是单位根序列的备选假设。我们将在下一节中详细了解趋势平稳性。现在,让我们专注于实现,看看KPSS测试的结果。

  • 零假设:这个过程是趋势平稳的。
  • 对立假设:序列有单位根(序列不是平稳的)。

Python代码:

#define function for kpss test
from statsmodels.tsa.stattools import kpss
#define KPSS
def kpss_test(timeseries):print ('Results of KPSS Test:')
    kpsstest = kpss(timeseries, regression='c')
    kpss_output = pd.Series(kpsstest[0:3], index=['Test Statistic','p-value','Lags Used'])
    for key,value in kpsstest[3].items():
    kpss_output['Critical Value (%s)'%key] = value
print (kpss_output)

KPSS试验的结果如下:KPSS试验-检验统计量,P值,以及临界值在1%、2.5%、5%和10%置信区间的结果。对于空中乘客数据集,以下是结果:

Results of KPSS Test:
Test Statistic            1.052175
p-value                   0.010000
Lags Used                14.000000
Critical Value (10%)      0.347000
Critical Value (5%)       0.463000
Critical Value (2.5%)     0.574000
Critical Value (1%)       0.739000
dtype: float64

平稳性检验:如果检验统计量大于临界值,我们拒绝零假设(序列不是平稳的)。如果检验统计量小于临界值,则不能拒绝零假设(序列是平稳的)。对于航空旅客数据,在所有置信区间,检验统计量的值都大于临界值,因此可以说该序列不是平稳的。

在准备时间序列数据模型之前,我通常都要进行统计测试。有一次,两次测试都显示出矛盾的结果。一个测试表明,该系列是固定的,而另一个表明,系列不是!我被困在这一段时间,试图弄清楚这是怎么可能的。事实证明,有不止一种类型的平稳性。

综上所述,ADF检验具有线性或差分平稳的替代假设,而KPSS检验识别一系列的趋势平稳性。

4.平稳性类型

让我们了解不同类型的平稳性以及如何解释上述测试的结果。

严格平稳:严格平稳序列满足平稳过程的数学定义。对于严格平稳序列,均值、方差和协方差不是时间的函数。目的是将一个非平稳序列转换成严格平稳序列进行预测。

趋势平稳一个没有单位根但呈现趋势的系列被称为趋势平稳序列。一旦趋势被移除,所得序列将是严格平稳的。KPSS检验将一系列在没有单位根的情况下分类为固定的。这意味着该序列可以是严格平稳的或趋势平稳的。

差分平稳:一个差分平稳的时间序列落在不同的平稳状态下。ADF检验也被称为差异平稳性检验。

应用任意两个检验方法总是更好的,所以我们确信这个序列是真正静平稳的。让我们看看应用这些平稳性检验的可能结果。

  • 案例1:两种检验都表明序列不是平稳的——序列不是平稳的。
  • 案例2:两种检验都表明序列是平稳的——序列是平稳的。
  • 案例3:KPSS检验=平稳,ADF检验=非平稳——趋势平稳,去除趋势使系列严格平稳
  • 情况4:KPSS检验=非平稳,ADF检验=平稳——差分平稳,用差分可使序列平稳

5.制作时间序列平稳

现在我们已经熟悉了平稳性的概念及其不同类型,我们终于可以继续进行系列平稳实操了。始终记住,要想使用时间序列预测模型,必须先将任何非平稳序列转换为平稳序列。

5.1 差分法

在该方法中,我们计算系列中的连续项的差。差分通常被执行以去除不同的平均值。数学上,差异可以写成:

yt = yt – y(t-1)

其中yt是时间t的值

在我们的系列中应用差分并绘制结果:

train['#Passengers_diff'] = train['#Passengers'] - train['#Passengers'].shift(1)
train['#Passengers_diff'].dropna().plot()

5.2 季节性差异

在季节差异中,我们不计算连续值之间的差异,而是计算观测值与同一季节的先前观测值之间的差异。例如,星期一的观察将从上星期一的观察中减去。从数学上讲,它可以写成:

yt = yt – y(t-n)

n=7
train['#Passengers_diff'] = train['#Passengers'] - train['#Passengers'].shift(n)

5.3 变换

变换用于平稳序列的非恒定方差。常用的变换方法有幂变换、平方根法和对数变换法。让我们对航空乘客数据集做一个快速log转换和差异:

train['#Passengers_log'] = np.log(train['#Passengers'])
train['#Passengers_log_diff'] = train['#Passengers_log'] - train['#Passengers_log'].shift(1)
train['#Passengers_log_diff'].dropna().plot()

正如你所看到的,这张图与之前的图相比有了显著的改进。你可以在该序列中使用平方根或幂变换,看看它们是否产生更好的结果。

小结

在这篇文章中,我们涵盖了不同的方法,可以用来检查平稳性的时间序列。


原文链接:A Gentle Introduction to Handling a Non-Stationary Time Series in Python

翻译:徐大白



| 1
登录后可评论,马上登录吧~
评论 ( 0 )

还没有人评论...