上篇文章简单提到了应该用平稳时间序列作预测,本文将介绍具体概念和缘由。python
平稳序列有三个基本标准:git
一、序列的均值(mean)不该该是时间的函数(意思是不该该随时间变化),而应该是一个常数。下面的左图知足这个条件,而右图的均值受时间的变化影响。
github
二、序列的方差(variance)不该该是时间的函数。这种特性称为homoscedasticity(同方差性)。下图描绘了平稳序列和非平稳序列,注意右图分布的不一样变化范围。
dom
三、t时间段的序列和前一个时间段的序列的协方差(协方差,衡量的是两个变量在一段时间内同向变化的程度)应该只和时间间隔有关,而与时间t无关,在时间序列中,由于是同一个变量在不一样时间段的值序列,因此这里的协方差称为自协方差。右图随着时间的增长,有一段变得愈来愈紧密了。因此右图的序列的协方差不是常数。
函数
带有趋势和季节性成分的时间序列都是非平稳的,下图给出了更多的区分平稳性的例子:
测试
大多数的统计预测方法都是以平稳时间序列为假设前提来设计的。
好比,对于时间序列自回归预测来讲,咱们的假设是变量的历史和现状呈现出的基本特性,在将来阶段的一个长时期里会维持不变,而这里的基本特性通常就是用上面提到的均值、方差、自协方差来表示。
更具体的说,自回归预测模型本质是'利用序列的滞后阶数(lags)做为自变量'的线性回归模型,好比lags=2表示使用变量的t-1和t-2时刻的值做为自变量来预测t时刻的值。那么经过在历史序列上训练模型后,获得的这个线性回归模型的各自变量的系数就表明了各滞后时刻的值与下一时刻值的相关性,若是时间序列接近平稳,这些相关性在将来一段时间内都不会有大的变化,那么预测将来就成为了可能。
因此,相对非平稳序列的预测,平稳序列的预测更简单和可靠。设计
对于非平稳时间序列的预测,咱们须要先将其转换为平稳时间序列,方法包括:code
- 差分(一阶或n阶)
- 取log
- 开根号
- 时间序列分解
- 综合使用上面的方法
通常来讲,作个一阶差分,就能够获得接近平稳的时间序列了,若是方差随时间变化较大,那么先取log再作一阶差分就能够了。blog
好比有一个序列:[1,5,2,12,20]
一阶差分,获得:[5-1, 2-5, 12-2, 20-12] = [4, -3, 10, 8]
二阶差分(即在一阶差分以后,再作一次差分),获得:[-3-4, -10-3, 8-10] = [-7, -13, -2]ip
对于判断时间序列是否平稳,能够经过肉眼观测时间序列图,就相似上面提到的平稳性的3个基本标准,或者
将时间序列分红多个连续的部分,计算各部分的均值、方差和自相关性(或协方差),若是结果相差很大,那么序列就不平稳。可是这些方法都不能量化平稳性,也就是用一个数值来表示出时间序列的平稳性。为此,咱们可使用‘Unit Root Tests’即单位根检验,该方法的思想是若是时间序列有单位根,则就是非平稳的。
如下是经常使用的两个基于单位根检验思想的实现:
- Augmented Dickey Fuller test (ADF Test)
零假设为序列有单位根,是非平稳的,P-Value若是小于显著级别(0.05),则能够拒绝零假设。- Kwiatkowski-Phillips-Schmidt-Shin – KPSS test (trend stationary)
与ADF正好相反,零假设为序列是平稳的。另外,在python中,能够经过指定regression='ct'参数来让kps把“肯定性趋势(deterministic trend)”的序列认为是平稳的。所谓肯定性趋势的序列就是斜率始终保持不变的序列,好比下面这样的:
下面是对应的python代码:
from statsmodels.tsa.stattools import adfuller, kpss df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date']) # ADF Test result = adfuller(df.value.values, autolag='AIC') print(f'ADF Statistic: {result[0]}') print(f'p-value: {result[1]}') for key, value in result[4].items(): print('Critial Values:') print(f' {key}, {value}') # KPSS Test result = kpss(df.value.values, regression='c') print('\nKPSS Statistic: %f' % result[0]) print('p-value: %f' % result[1]) for key, value in result[3].items(): print('Critial Values:') print(f' {key}, {value}')
输出:
ADF Statistic: 3.14518568930674 p-value: 1.0 Critial Values: 1%, -3.465620397124192 Critial Values: 5%, -2.8770397560752436 Critial Values: 10%, -2.5750324547306476 KPSS Statistic: 1.313675 p-value: 0.010000 Critial Values: 10%, 0.347 Critial Values: 5%, 0.463 Critial Values: 2.5%, 0.574 Critial Values: 1%, 0.739
白噪声的遵循均值为0的随机分布,没有丝毫的模式可言。用python制造一个白噪声序列,并可视化以下:
randvals = np.random.randn(1000) pd.Series(randvals).plot(title='Random White Noise', color='k')
- 减去最佳拟合线
- 减去均值线,或者移动平均线
- 减去/除以 利用时间序列分解出的趋势序列
- 季节性窗口内的移动平均法,平滑季节性
- 季节性差分,就是用当前值减去一个季节窗口以前对应的时刻的值
- 减去/除以 利用时间序列分解出的季节性序列
- 经过肉眼看图
- 经过自相关函数判断
from pandas.plotting import autocorrelation_plot df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv') # Draw Plot plt.rcParams.update({'figure.figsize':(9,5), 'figure.dpi':120}) autocorrelation_plot(df.value.tolist())
- 经过时间序列分解出的季节性序列来计算,其思想是越没有季节性,那么Rt的方差和Rt+St的方差越应该区别不大,反之,这个方差的比值越应该小于1,公式以下:
Fs越接近0,越没有季节性,越接近1,季节性越强。
ok,本篇就这么多内容啦~,感谢阅读O(∩_∩)O。