时间序列分析-针对时间序列的特殊方法
平稳性
许多时间序列的统计学模型都是依赖于时间序列是平稳性的这一前提条件,通常来说,一个平稳的时间序列指的是这个时间序列在一段时间内具有稳定的统计值,如均值,方差。由于我们对于一个数据是否平稳是有自己的直觉的,所以在实践的过程中要谨防过于依赖直觉而被直觉所欺骗。
为此我们引入了一些统计上的假设检验来测试一个时间序列数据的平稳性。
其中Augmented Dickey Fuller Test (ADF Test) 是最常使用的一种方法,ADF test也是单位根检验(unit root test)的一种。单位根是一个使得时间序列非平稳的一个特征,从技术上说,在下面的公式中如果alpha=1,那么我们说存在单位根。
其中Yt,Yt−1分别表示t时刻和t-1时刻的时间序列值,Xe表示外生变量,ϵ表示误差项。
从直觉上我们可以理解为,只有当alpha<1时,整个时间序列的趋势才是有可能出现逆转的。而ADF test就是对alpha值的假设检验,它的原假设是alpha =1,即原假设成立,则时间序列非平稳。
但是我们需要记住,ADF test不是一个永远行之有效的方法,它存在一些不足:
- 对于区分近似单位根(near unit roots)和单位根不是很有效
- 当数据点很少时,容易出现假阳性的问题
- 大多数测试不会检测所有导致非平稳的因素,例如有些测试只是检验均值或方差两者之一是否平稳,有些测试只是检验总体分布。因此在使用任何假设检验时都要先充分理解数据的特点和检验的限制因素。
此外还有一种Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test也是常用的时间序列平稳性假设检验,它和ADF的区别是KPSS的原假设是关于平稳过程,而ADF的原假设是关于单位根。
时间序列平稳性的重要性在于:
- 大量的统计学模型基于平稳性的假设
- 对于一个应用于非平稳时间序列的模型,它的准确性和模型指标会随着时间序列本身变化而变化,从而造成模型本身不稳定。
而对于一个非平稳的时间序列,其实是可以通过一些简单的变换使之变成平稳性的。log变换和平方根变换是两个常用的方式,其适用于非等方差的场景。另外可以通过差分的方式消除时间序列趋势。
Python代码实现
from statsmodels.tsa.stattools import adfuller
import pandas as pd
import numpy as np
%matplotlib inline
# 导入原始数据
url = 'data/a10.csv'
df = pd.read_csv(url, parse_dates=['date'], index_col='date')
series = df.loc[:, 'value'].values
df.plot(figsize=(14,8), legend=None, title='a10 - Drug Sales Series')
# 使用ADF Test
result = adfuller(series, autolag='AIC')
print(f'ADF Statistic: {result[0]}')
print(f'n_lags: {result[1]}')
print(f'p-value: {result[1]}')
ADF Statistic: 3.1451856893067363
n_lags: 1.0
p-value: 1.0
p值为1表示没有理由拒绝原假设,也就是存在单位根,时间序列非平稳,这也和我们的直觉是相符的
# 生产一组随机数检验平稳性
series1 = np.random.randn(100)
plt.plot(series1)
result1 = adfuller(series1, autolag='AIC')
print(f'ADF Statistic: {result1[0]}')
print(f'p-value: {result1[1]}')
ADF Statistic: -9.588680806555054
p-value: 2.0639843020333296e-16
p值远远小于0.05,表示拒绝原假设,即时间序列是平稳的
自相关性
自相关性是时间序列的一个重要的概念,指的是时间序列中某一个时刻的值和另一个时刻的具有一定的相关性。举例来说,有一个每天更新的气温数据,你可能会发现每年5月15号和8月15号的气温存在某种关联,当年5月15号更热,则对应的8月15号也更热。当然还有一种可能性是这种关联性趋近于0, 知道5月15号的气温并不会给你任何关于8月15号气温的信息。
为了进一步探索自相关,需要引入两个函数,自相关函数和偏自相关函数来描述这一现象。
The autocorrelation function
自相关(acf)函数描述的是一组时间序列和它前面间隔n个时刻的一组时间序列之前的相关性。
关于acf有一些重要的事实:
- 周期性序列的acf值和原始序列具有相同的周期性
- 对几个周期性序列的和计算acf,和分别计算每个周期性序列的acf再相加,结果是一样的
- 所有时间序列在间隔lag=0时的acf值都为1,也就是时间序列和它本身之前具有完全的正相关性
- 一个完全的白噪声序列,它在任何间隔处的acf都近似于0
- 对于任何一个时间序列,它在5%的置信度下的acf值不显著为0的置信区间临界值为,其中T为样本量,d为时间间隔,从公式中可以得出,随着时间间隔d的增大,置信区间也是在不断增大的,也就是说距离越远的相关性越不可信。
The partial autocorrelation function
偏自相关(pacf)函数描述的是一组时间序列和它前面间隔n个时刻的一组时间序列之前的偏相关性。这里的偏相关性可以从本质上理解为去除了样本之间的干涉,也就是更早时刻的相关性影响。
举例来说,计算时间间隔3的pacf是去除了时间间隔小于3的样本的影响,而只计算由于时间间隔为3时的时间序列之间的相关性,因为时间间隔为1和2的样本的影响已经在前面的pacf函数中计算过了。通过之后python实战的例子可以帮助我们理解这个概念。
关于pacf也有一些有趣的事实:
- 对于周期性时间序列,pacf会迅速趋近于0,而不像是acf一样呈现周期性,因此pacf没有太多冗余信息存在。这对于我们判断要收集多长的时间序列才能获取足够多的信息具有很大的帮助。
- pacf的置信区间临界值和acf相同
在下面的python实战部分,我们会看到一个平稳时间序列的例子和一个非平稳时间序列的例子。
Python代码实现
# 导入气温数据
series = pd.read_csv('data/daily-min-temperatures.csv', header=0, index_col=0,
parse_dates=True, squeeze=True)
# 画出最低气温时间序列
plt.plot(series)
# 画出acf函数
# 蓝色底色区域内画出的是95%置信区间,数据落在蓝色区域内表示在统计学意义上在x轴的时间间隔下具有自相关性
plot_acf(series)
plt.show()
# 画出pacf函数
plot_pacf(series)
plt.show()
# 构造一个非平稳线性增长时间序列
x= np.linspace(1,100,100)
plt.plot(x)
plot_acf(x)
plt.show()
plot_pacf(x)
plt.show()
# 从这个例子可以看到,从lag>=2开始,pacf值几乎都等于0,而lag=1
虚假相关性
时间序列分析的新人分析师通常会从标准的探索性数据开始实践,例如将两个变量相互绘制并计算它们的相关性。当他们注意到变量之间非常强的相关性时,会非常兴奋。但是当分析师向其他人展示他们的发现,会意识到这一切都没有意义。有人会质疑指出相关性有些过于高了,并且当新人分析师尝试用更多变量重新运行他们的分析时,会发现更多变量之间也具有惊人的高相关性。但实际上我们都清楚,现实生活中有不可能有这么多真正的高相关性。
这个情况非常像计量经济学的早期历史。在 19 世纪,当经济学家第一次开始思考商业周期的概念时,他们去寻找影响周期的外部驱动因素,例如太阳黑子(11 年的周期)或各种气象周期(例如 4 年的降水周期)。他们总是得到非常积极和高度相关的结果,即使他们并没有因果关系来解释这些结果。这些都是所谓的虚假相关性。
具有潜在趋势的数据很可能产生虚假的相关性,例如碳排放量的上升和变暖的全球气温之间的相关性。 除了趋势之外,时间序列的其他一些共同特征也会引入虚假相关性:
- 季节性,例如考虑夏天热狗消费量和溺水死亡人数的相关性
- 随着时间的推移,状态变化引起的数据水平或斜率变化
- 累计数量的相关性,这被许多行业广泛用于人为制造更强相关性的技巧
因此在实践中发现极强相关性的时候一定要结合行业经验仔细验证,不能盲目相信数据上的结果。
这个网站http://tylervigen.com/spurious-correlations,记录了许多虚假相关性的例子,表面上看起来相关关系都惊人的高。
例如这个美国在科技领域的花费和自杀率之间的时间序列相关性。
候一定要结合行业经验仔细验证,不能盲目相信数据上的结果。**
这个网站http://tylervigen.com/spurious-correlations,记录了许多虚假相关性的例子,表面上看起来相关关系都惊人的高。
例如这个美国在科技领域的花费和自杀率之间的时间序列相关性。
[外链图片转存中…(img-I2CFeaK9-1646062737559)]