时间序列、ARIMA及其衍生

简介

AIOps项目的基线用ARIMA完成,记录一下。

综合转载以下文章:

序列分析

平稳性

  1. 对于纯随机序列,也称为白噪声序列,序列的各项之间没有任何的关系, 序列在进行完全无序的随机波动, 可以终止对该序列的分析。

  2. 对于平稳非白噪声序列, 它的均值和方差是常数。ARMA 模型是最常用的平稳序列拟合模型。

  3. 对于非平稳序列, 由于它的方差和均值不稳定, 处理方法一般是将其转化成平稳序列。 可以使用ARIMA 模型进行分析。

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

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

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

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

  • 宽平稳:也叫弱平稳或者二阶平稳(均值和方差平稳),它应满足:常数均值;常数方差;常数自协方差。

平稳性检验

  1. 时序图检验:根据平稳时间序列的均值和方差都是常数的特性,平稳序列的时序图显示该序列值时钟在一个参数附近随机波动,而且波动的范围是有界的。如果有明显的趋势或者周期性, 那它通常不是平稳序列。

  2. 自相关图检验:平稳序列具有短期相关性, 这个性质表明对平稳序列而言, 通常 只有近期的序列值得影响比较明显, 间隔越远的过去值对现在的值得影响越小。 而非平稳序列的自相关系数衰减的速度比较慢。

  3. 单位根检验:单位根检验是指检验序列中是否存在单位根, 如果存在单位根, 那就是非平稳时间序列。 目前最常用的方法就是单位根检验。

平稳性处理

对不平稳的序列进行处理将其转换成平稳的序列。

1. 对数变换

对数变换主要是为了减小数据的振动幅度,使其线性规律更加明显。对数变换相当于增加了一个惩罚机制,数据越大其惩罚越大,数据越小惩罚越小。这里强调一下,变换的序列需要满足大于0,小于0的数据不存在对数变换。

2. 平滑法

根据平滑技术的不同,平滑法具体分为移动平均法和指数平均法。移动平均即利用一定时间间隔内的平均值作为某一期的估计值,而指数平均则是用变权的方法来计算均值。

3. 差分

时间序列最常用来剔除周期性因素的方法当属差分了,它主要是对等周期间隔的数据进行线性求减。

4. 分解

分解就是将时序数据分离成不同的成分。statsmodels使用的X-11分解过程,它主要将时序数据分离成长期趋势、季节趋势和随机成分。与其它统计软件一样,statsmodels也支持两类分解模型,加法模型和乘法模型,这里只实现加法,乘法只需将model的参数设置为 multiplicative 即可。

1
2
3
4
5
6
from statsmodels.tsa.seasonal import seasonal_decompose
decomposition = seasonal_decompose(ts_log, model="additive")

trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid

得到不同的分解成分后,就可以使用时间序列模型对各个成分进行拟合,当然也可以选择其他预测方法。

ARIMA

AR(自回归模型)

描述当前值与历史值之间的关系, 用变量自身的历史时间数据对自身进行预测。自回归模型必须满足平稳性的要求。

以前 $p$ 期的序列值 $x_{t-1},x_{t-2},…,x_{t-p}$ 为自变量,随机变量 $X_t$ 的取值 $x_t$ 为因变量建立线性回归模型。

统计量 性质
均值 常数均值
方差 常数方差
自相关系数(ACF) 拖尾
偏相关系数(PACF) p阶拖尾

自相关系数(ACF):平稳 $AR(p)$ 模型的自相关系数 $p_k=p(t,t-k)=\frac{\text{cov}(X_t,X_{t-k})}{\sigma_t\sigma_{t-k}}$呈指数级的速度衰减,始终有非零取值,不会在 $k$ 大于某个常数之后就恒等于零,这个性质就是平稳 $AR(p)$ 模型的自相关系数 $p_k$ 具有拖尾性。

偏相关系数(PACF):对于一个平稳 $AR(p)$ 模型,求出延迟 $k$ 期自相关系数 $p_k$ 时,实际上得到的并不是 $X_t$ 与 $X_{t-k}$ 之间单纯的相关关系,因为 $X_t$ 同时还会收到中间 $k-1$ 个随机变量 $X_{t-1},X_{t-2},…,X_{t-k}$ 的影响,所以自相关系数 $p_k$ 里实际上掺杂了其他变量对 $X_t$ 与 $X_{t-k}$ 的相关影响,为了单纯地测度 $X_{t-k}$ 对 $X_t$ 的影响,引进偏自相关系数的概念。

可以证明平稳 $AR(p)$ 模型的偏自相关系数具有 $p$ 阶截尾性。这个性质连同前面的自相关系数的拖尾性是 $AR(p)$ 模型重要的识别依据。

自回归模型的限制:

  1. 自回归模型是使用自身的数据进行预测的

  2. 必须具有平稳性

  3. 必须具有相关性,如果相关性小于 0.5 , 则不宜使用

  4. 自回归模型只适用于预测与自身前期相关的预测。

MA(移动平均模型)

移动平均模型关注的是自回归模型中的误差项的累加,而且能有效地消除预测中的随机波动。

随机变量 $X_t$ 的取值 $x_t$ 与以前各期的序列值无关,建立 $x_t$ 与前 $q$ 期的随机扰动 $\varepsilon_{t-1},\varepsilon_{t-2},…,\varepsilon_{t-q}$ 的线性回归模型。误差项是当期的随机干扰 $\varepsilon_t$,为零均值白噪声序列,$\mu$ 是序列 $\{X_t\}$ 的均值。认为 $x_t$ 主要是受过去 $q$ 期的误差项的影响。

ARMA(自回归平均模型)

自回归和移动平均的结合。

统计量 性质
均值 常数均值
方差 常数方差
自相关系数(ACF) 拖尾
偏相关系数(PACF) 拖尾

ARIMA(差分自回归移动平均模型)

$AR$ 是自回归,$p$ 是自回归项,$MA$ 是移动平均,$q$ 为移动平均项,$d$ 为时间序列称为平稳时所做的差分次数。

原理: 将非平稳时间序列转换成平稳时间序列, 然后将因变量仅对它的滞后值(p阶)以及随机误差项的现值和滞后值进行回顾所建立的模型。

ARIMA 建模一般流程:

  1. 将序列平稳化(差分法确定 $d$)

  2. $p$ 和 $q$ 阶数的确定(ACF 和 PACF 确定)

  3. 建立模型 $ARIMA(p,d,q)$

定阶

ADF定阶d

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

在实际情况中,可以将原始时间序列不断差分直至ADF检验中的 p 值小于0.05。

  1. 模型不用差分意味着原始序列是平稳的;一阶差分意味着原始序列有个固定的平均趋势;二阶差分意味着原始序列有个随时间变化的趋势;
  2. 模型没有差分一般都有常数项;有两阶差分一般没常数项;假如一阶差分模型非零的平均趋势,则有常数项。

偏相关定阶p

观察PACF图,$p$ 阶数选择由某点之后大部分点都在尾部中。

自相关定阶q

观察ACF图,$q$ 阶数选择由某点之后大部分点都在尾部中。

  1. 假如PACF显示截尾或者lag-1的ACF是正的(此时序列仍然有点underdifferenced),则需要考虑AR项;PACF的截尾项表明AR的阶数;
  2. 假如ACF显示截尾或者lag-1的ACF是负的(此时序列有点overdifferenced),则需要加MA项,ACF的截尾项表明AR的阶数;
  3. AR和MA可以相互抵消对方的影响,所以假如用AR-MA模型去拟合数据,仍然需要考虑加些AR或MA项。尤其在原先模型需要超过10次的迭代去converge;
  4. 假如在AR部分有个单位根(AR系数和大约为1),此时应该减少一项AR增加一次差分。
  5. 假如在MA部分有个单位根(MA系数和大约为1),此时应该减少一项AR减少一次差分。
  6. 假如长期预测出现不稳定,则可能AR、MA系数有单位根。

网格搜索定阶pq

现实情况中,常常遇到需要自动化定阶pqd的情况,这时候便无法肉眼观察acf图和pacf图来定阶pq,只能采用网格搜索,利用下面的AIC和BIC选择最好的模型。代码参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def search_param(df_SERIES, max_order=2, period=24):
p = d = q = range(0, max_order + 1)
pdq = list(itertools.product(p, d, q))
seasonal_pdq = [(x[0], x[1], x[2], period) for x in list(itertools.product(p, d, q))]
results = []
results_param = []
for param in pdq:
for param_seasonal in seasonal_pdq:
try:
mod = sm.tsa.statespace.SARIMAX(df_SERIES,
order=param,
seasonal_order=param_seasonal,
enforce_stationarity=False,
enforce_invertibility=False)
result = mod.fit(disp=False)
results.append(result.aic)
results_param.append([param, param_seasonal])
print('ARIMA{}x{} - AIC:{}'.format(param, param_seasonal, result.aic))
sys.stdout.flush()
except:
continue
return results_param[results.index(min(results))]def search_param(df_SERIES, max_order=2, period=24):
p = d = q = range(0, max_order + 1)
pdq = list(itertools.product(p, d, q))
seasonal_pdq = [(x[0], x[1], x[2], period) for x in list(itertools.product(p, d, q))]
results = []
results_param = []
for param in pdq:
for param_seasonal in seasonal_pdq:
try:
mod = sm.tsa.statespace.SARIMAX(df_SERIES,
order=param,
seasonal_order=param_seasonal,
enforce_stationarity=False,
enforce_invertibility=False)
result = mod.fit(disp=False)
results.append(result.aic)
results_param.append([param, param_seasonal])
print('ARIMA{}x{} - AIC:{}'.format(param, param_seasonal, result.aic))
sys.stdout.flush()
except:
continue
return results_param[results.index(min(results))]

季节性

  1. 假如序列有显著是季节性模式,则需要用季节性差分,但是不要使用两次季节性差分或总过超过两次差分(季节性和非季节性);
  2. 假如差分序列在滞后s处有正的ACF,s是季节的长度,则需要加入SAR项;假如差分序列在滞后s处有负的ACF,则需要加入SMA项,如果使用了季节性差异,则后一种情况很可能发生,如果数据具有稳定和合乎逻辑的季节性模式。如果没有使用季节性差异,前者很可能会发生,只有当季节性模式不稳定时才适用。应该尽量避免在同一模型中使用多于一个或两个季节性参数(SAR + SMA),因为这可能导致过度拟合数据和/或估算中的问题。

评价

  • AIC(Akaike Information Criterion):赤池信息准则
  • BIC(Bayesian Information Criterion):贝叶斯信息准则

以上两种评价准则的目的是为了选择出简单有效的模型,$k$ 表示模型参数的个数,$n$表示样本的数量,$L$ 表示似然函数。使得 $k$ 越小,$L$ 似然函数越大越好。AIC 和 BIC 越小越好。实际情况中, AIC 一般会比 BIC 更好。

statsmodels.tsa中的ARIMA及其衍生

statsmodels中,除了普通的ARIMA statsmodels.tsa.arima_process.ArmaProcess,也提供了另外两种更高级的变种,SARIMAX statsmodels.tsa.statespace.sarimax.SARIMAX 和 VARIMAX statsmodels.tsa.statespace.varmax.VARMAX

SARIMAX

Seasonal Autoregressive Integrated Moving-Average with eXogenous regressors,即支持外生变量的季节性ARIMA。

外生变量:在经济计量模型中,外生变量是与模型的随机扰动项不相关的变量。通常,描述影响经济系统运行的,技术、政治、制度、自然条件等外部因素的变量都是外生变量。例如,对于描述某种农产品的市场局部均衡的经济计量模型,天气条件指数不受市场供需局部均衡系统的制约,而它确实影响了农产品的供给量,因此是该系统的外生变量。

季节性除了要设置的季节性周期之外,同样还有 p、q和d 三个参数需要设置。所以使用SARIMAX进行拟合时,网格搜索最多需要搜索六个参数,原始pqd和季节性pqd。另外,季节性对于较长的时间序列的训练非常耗时,这样训练时也很容易出现“假死”状态,就是训练程序已经退出了,但是没有提示。

外生变量,例如在AIOps中,影响每个请求的响应时间的,还有一些隐含因素,例如服务器的网络状态,系统状态和代码状态等多种因素。这些便可以作为外生变量输入。

季节性和外生变量的例子:SARIMAX: Introduction。

另外,之前一直以为ARIMA训练是必须把缺失数据填充后再进行训练的,然后看到SARIMAX的一个example,发现是支持含有缺失数据进行训练的。但是没有尝试比较过填不填充的表现,因为目前只是作为一个比较基线来使用而已。例子:SARIMAX: Model selection, missing data

VARIMAX

Vector Autoregressive Moving-Average with eXogenous regressors,即支持外生变量的向量ARIMA。

简单地说,原本的ARIMA,即便是SARIMAX,也只能对一条序列进行训练和预测,而现实情况中,常常会遇到多条曲线其实是相似的,例如周期性和突变点都是大体一致的,这时候我们想要的是一个可以很好地概括这几条曲线的模型,当然该模型也能很好地泛化到其他类似的曲线。所以基于状态空间的VARIMAX就此而生。它能够对多条序列进行训练。

具体的状态空间是什么东西,还没了解过,听说很难……statsmodels.tsa.statespace中也能够自定义状态空间。例子:VARMAX modelsState space modeling: Local Linear Trends

两个搞不懂的地方:

  1. VARIMAX能够支持多条序列训练,所给的example中,原始序列的输入是两条序列,外生变量的输入是一条序列,那么说明每条外生变量序列都会对输入的所有序列产生影响吗?直觉应该是一对一的。
  2. SARIMAX和VARIMAX为什么不出一个结合?

总结

其实,Python中除了statsmodels提供了ARIMA,从R包移植过来的auto.arima也提供了ARIMA拟合,但是发手写ARIMA的网格搜索也不难,就几行。相比之下,还是statsmodels提供的能够加入外生变量的季节性和向量ARIMA更加丰富。

一分一毛,也是心意。