一、什么是时间序列

时间序列简单的说就是各时间点上形成的数值序列,时间序列分析就是通过观察历史数据预测未来的值。

在这里需要强调一点的是,时间序列分析并不是关于时间的回归,它主要是研究自身的变化规律的(这里不考虑含外生变量的时间序列)。

环境配置

python作为科学计算的利器,当然也有相关分析的包:statsmodels中tsa模块,当然这个包和SAS、R是比不了,但是python有另一个神器:pandas!pandas在时间序列上的应用,能简化我们很多的工作。这两个包pip就能安装。

数据准备

许多时间序列分析一样,本文同样使用航空乘客数据(AirPassengers.csv)作为样例。下载链接。

用pandas操作时间序列

#-*- coding:utf-8 -*-
importnumpy as npimportpandas as pdfrom datetime importdatetimeimportmatplotlib.pylab as plt#读取数据,pd.read_csv默认生成DataFrame对象,需将其转换成Series对象
df = pd.read_csv(‘AirPassengers.csv‘, encoding=‘utf-8‘, index_col=‘Month‘)
df.index= pd.to_datetime(df.index) #将字符串索引转换成时间索引
ts = df[‘Passengers‘] #生成pd.Series对象#查看数据格式
print(ts.head())print(ts.head().index)


不知道为啥,时间隔1000,不过没什么影响。

查看某日的值既可以使用字符串作为索引,又可以直接使用时间对象作为索引

ts[‘2049-01-01‘]
ts[datetime(2049,1,1)]

两者的返回值都是第一个序列值:112

如果要查看某一年的数据,pandas也能非常方便的实现

ts[‘2049‘]

切片操作:

ts[‘2049-1‘ : ‘2049-6‘]

注意时间索引的切片操作起点和尾部都是包含的,这点与数值索引有所不同

pandas还有很多方便的时间序列函数,在后面的实际应用中在进行说明。

二、时间序列分析

1. 基本模型

自回归移动平均模型(ARMA(p,q))是时间序列中最为重要的模型之一,它主要由两部分组成: AR代表p阶自回归过程,MA代表q阶移动平均过程,其公式如下:



依据模型的形式、特性及自相关和偏自相关函数的特征,总结如下:


在时间序列中,ARIMA模型是在ARMA模型的基础上多了差分的操作。

2. 平稳性检验

我们知道序列平稳性是进行时间序列分析的前提条件,很多人都会有疑问,为什么要满足平稳性的要求呢?在大数定理和中心定理中要求样本同分布(这里同分布等价于时间序列中的平稳性),而我们的建模过程中有很多都是建立在大数定理和中心极限定理的前提条件下的,如果它不满足,得到的许多结论都是不可靠的。以虚假回归为例,当响应变量和输入变量都平稳时,我们用t统计量检验标准化系数的显著性。而当响应变量和输入变量不平稳时,其标准化系数不在满足t分布,这时再用t检验来进行显著性分析,导致拒绝原假设的概率增加,即容易犯第一类错误,从而得出错误的结论。

平稳时间序列有两种定义:严平稳和宽平稳

严平稳顾名思义,是一种条件非常苛刻的平稳性,它要求序列随着时间的推移,其统计性质保持不变。对于任意的τ,其联合概率密度函数满足:


严平稳的条件只是理论上的存在,现实中用得比较多的是宽平稳的条件。

宽平稳也叫弱平稳或者二阶平稳(均值和方差平稳),它应满足:

常数均值

常数方差

常数自协方差

平稳性检验:观察法和单位根检验法

基于此,我写了一个名为test_stationarity的统计性检验模块,以便将某些统计检验结果更加直观的展现出来。

#-*- coding:utf-8 -*-
from statsmodels.tsa.stattools importadfullerimportpandas as pdimportmatplotlib.pyplot as pltimportnumpy as npfrom statsmodels.graphics.tsaplots importplot_acf, plot_pacf#移动平均图
defdraw_trend(timeSeries, size):
f= plt.figure(facecolor=‘white‘)#对size个数据进行移动平均
rol_mean = timeSeries.rolling(window=size).mean()#对size个数据进行加权移动平均
rol_weighted_mean = pd.DataFrame.ewm(timeSeries, span=size).mean()
timeSeries.plot(color=‘blue‘, label=‘Original‘)
rolmean.plot(color=‘red‘, label=‘Rolling Mean‘)
rol_weighted_mean.plot(color=‘black‘, label=‘Weighted Rolling Mean‘)
plt.legend(loc=‘best‘)
plt.title(‘Rolling Mean‘)
plt.show()defdraw_ts(timeSeries):
f= plt.figure(facecolor=‘white‘)
timeSeries.plot(color=‘blue‘)
plt.show()‘‘‘Unit Root Test
The null hypothesis of the Augmented Dickey-Fuller is that there is a unit
root, with the alternative that there is no unit root. That is to say the
bigger the p-value the more reason we assert that there is a unit root‘‘‘
deftestStationarity(ts):
dftest=adfuller(ts)#对上述函数求得的值进行语义描述
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] =valuereturndfoutput#自相关和偏相关图,默认阶数为31阶
def draw_acf_pacf(ts, lags=31):
f= plt.figure(facecolor=‘white‘)
ax1= f.add_subplot(211)
plot_acf(ts, lags=31, ax=ax1)
ax2= f.add_subplot(212)
plot_pacf(ts, lags=31, ax=ax2)
plt.show()

观察法,通俗的说就是通过观察序列的趋势图与相关图是否随着时间的变化呈现出某种规律。所谓的规律就是时间序列经常提到的周期性因素,现实中遇到得比较多的是线性周期成分,这类周期成分可以采用差分或者移动平均来解决,而对于非线性周期成分的处理相对比较复杂,需要采用某些分解的方法。下图为航空数据的线性图,可以明显的看出它具有年周期成分和长期趋势成分。平稳序列的自相关系数会快速衰减,下面的自相关图并不能体现出该特征,所以我们有理由相信该序列是不平稳的。



单位根检验:ADF是一种常用的单位根检验方法,他的原假设为序列具有单位根,即非平稳,对于一个平稳的时序数据,就需要在给定的置信水平上显著,拒绝原假设。ADF只是单位根检验的方法之一,如果想采用其他检验方法,可以安装第三方包arch,里面提供了更加全面的单位根检验方法,个人还是比较钟情ADF检验。以下为检验结果,其p值大于0.99,说明并不能拒绝原假设。


3. 平稳性处理