本文是主体是翻译Time Series Analysis (TSA) in Python - Linear Models to GARCH。但是文章主要是python操作,而理论较少,因此在此基础上补充理论,使文章有血更有肉。欢迎在评论区指正。
目录动机
基础平稳性
序列相关(自相关)
为什么要关心自相关白噪声和随机游走
趋势平稳时间序列
对数线性模型
AR(p)
MA(q)
ARMA(p, q)
ARIMA(p, d, q)
ARCH(p)
GARCH(p, q)
参考文献
动机
为什么我们使用这个模型而不是其他模型,这些模型的有什么缺点?让我们来了解他们吧!
#import our Python libraries
import os
import sys
import pandas as pd
import pandas_datareader.data as web
import numpy as np
import statsmodels.formula.api as smf
import statsmodels.tsa.api as smt #tsa为Time Series analysis缩写
import statsmodels.api as sm
import scipy.stats as scs
from arch import arch_model
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
#用pandas_datareader包从雅虎抓取一些数据
end = '-01-01'
start = '-01-01'
get_px = lambda x: web.DataReader(x, 'yahoo', start=start, end=end)['Adj Close']
symbols = ['SPY','TLT','MSFT']
# raw adjusted close prices
data = pd.DataFrame({sym:get_px(sym) for sym in symbols})
lrets = np.log(data/data.shift(1)).dropna()#对数收益
基础平稳性
严平稳:联合正态分布
和
对于所有的$t$都是同样的
弱平稳:
的均值和
与
的协方差随时间不变,只与
有关。
两者关系:若严平稳二阶矩存在,则严平稳可以得出弱平稳,相反则不成立。但是假如序列
是正态分布的,严平稳和弱平稳是等价的。
为什么我们需要平稳性?平稳的时间序列预测更简单,因为我们可以假设未来的统计性质和现在是一样的
在时间序列中大多数模型都假设协方差平稳(如上第三个图),这意味着当描述性统计(均值、方差、相关性)非常依赖于时间序列的平稳性
例如,假如一个时间序列在过去是一直增长的,那么样本均值和方差随着样本量增加也跟着增长,那么在未来均值和方差会一直被低估。如果一个序列的均值和方差没有明确定义,那么它与其他变量的相关性也同样如此
但是我们遇到的大多数金融时间序列是不平稳的,因此时间序列分析中有一大部分需要判断我们要进行预测的序列是否平稳,假如不是,我们需要进行转化成平稳序列(之后我们会讨论)
注:可以使用ADF(Augemented Dickey-Fuller)检验,即单位根检验,判断序列是否平稳。
一般有三个模型:不含漂移项与时间趋势项:
只含漂移项:
两者都含:
一般先要判断序列式哪个模型,然后再进行ADF检验:
原假设:
备择假设:
这里
,因为对原先模型进行了差分。
序列相关(自相关性)
本质上,当我们拟合时间序列时,我们将序列分解为三部分:长期趋势、季节性/循环性、随机性。随机部分叫做残差或误差,它是预测值与观察值的差。当时间序列的随机残差存在自相关时,就序列相关。为什么我们需要关心序列相关
我们关心序列相关是因为它对我们模型预测的正确性有重要的影响,序列相关本质上也和平稳性有关。回顾定义,平稳序列的残差是序列不相关的(应该有条件,见下注)。假如我们模型不能说明这点,模型系数的标准差将被低估,从而扩大T统计量的大小。结果会出现很多type-1错误——我们会拒绝原假设,即使它是对的。通俗来说,忽略自相关意味着模型预测将是空谈,关于模型里独立变量的影响,我们可能得出错误的结论。(注:我们构建的模型,最后的残差一定是序列不相关的,因为序列相关的话就是模型没完全表示,模型就错了)
注:平稳时间序列残差序列不相关,那么平稳序列序列不相关,则 对多所有的 都成立检验序列是否完全不相关,即需要检验所有自相关系数是否为0,即判断是否为白噪声。
混成检验(也称L-B检验)
原假设:
备择假设:
混成检验统计量:
渐进服从自由度为的
分布,m一般等于
决策规则:
,拒绝
。即,Q(m)的值大于自由度为m的卡方分布100(1-α)分位点时,我们拒绝
。也可以则当 p-value 小于等于显著性水平 α时拒绝
。
白噪声和随机游走
白噪声是我们第一个需要理解的时间序列模型。根据定义,作为白噪声过程的时间序列具有连续不相关的误差,并且这些误差的预期均值等于零。对于连续续不相关的误差的另一种描述是独立同分布。这是非常重要,假如我们的时间序列模型合理且成功的抓住了潜在的过程,模型的残差将是独立同分布的,就像一个白噪声过程。因此时间序列分析试图为时间序列拟合一个模型,使残差序列与白噪声难以分辨。
【当一随机过程独立同分布且均值、方差是常数则是白噪声过程。特别是当均值为零,方差为常数时为高斯白噪声(可以看出白噪声是弱平稳的)。此为蔡瑞胸书上定义】
让我们模拟一个白噪声看一看。
def tsplot(y, lags=None, figsize=(10, 8), style='bmh'):
if not isinstance(y, pd.Series): #判断类型
y = pd.Series(y)
with plt.style.context(style):
fig = plt.figure(figsize=figsize)
#mpl.rcParams['font.family'] = 'Ubuntu Mono'
layout = (3, 2)
ts_ax = plt.subplot2grid(layout, (0, 0), colspan=2)
acf_ax = plt.subplot2grid(layout, (1, 0))
pacf_ax = plt.subplot2grid(layout, (1, 1))
qq_ax = plt.subplot2grid(layout, (2, 0))
pp_ax = plt.subplot2grid(layout, (2, 1))
y.plot(ax=ts_ax)
ts_ax.set_title('Time Series Analysis Plots')
smt.graphics.plot_acf(y, lags=lags, ax=acf_ax, alpha=0.5)
smt.graphics.plot_pacf(y, lags=lags, ax=pacf_ax, alpha=0.5)
sm.qqplot(y, line='s', ax=qq_ax)
qq_ax.set_title('QQ Plot')
scs.probplot(y, sparams=(y.mean(), y.std()), plot=pp_ax)
plt.tight_layout()
return
简单模拟个白噪声过程
np.random.seed(1)
# plot of discrete white noise
randser = np.random.normal(size=1000)
tsplot(randser, lags=30)
我们可以看到过程是随机且在0附近波动。ACF和PACF显示没有明显的序列相关。要记住,由于是正态分布采样的结果,我们应该在自相关图中看到大约5%的显著性。最下面,QQ图和概率图是比较数据的概率分布和其他理论的分布。在这里,理论分布是标准正态分布,因此我们的数据是正态分布,符合高斯白噪声。
随机游走:随机游走是时间序列
的模型:
,
是离散的白噪声序列。
随机游走是不平稳的,因为协方差是和时间相关的。如果我们建模的时间序列是随机游走的,那么它是不可预测的。
让我们使用
从标准正态分布采样模拟一个随机游走
# Random Walk without a drift
np.random.seed(1)
n_samples = 1000
x = w = np.random.normal(size=n_samples)
for t in range(n_samples): #应该从1开始,但影响不大,x[-1]也有值
x[t] = x[t-1] + w[t]
tsplot(x, lags=30)
明显看出序列是不平稳的。让我们看看随机游走对我们的模拟数据是否很好的拟合。回忆随机游走模型是
。移项可以得到
。因此,随机游走的一阶差分应该等于白噪声。我们可以对时间序列使用
函数看它是否成立。
# First difference of simulated Random Walk series
tsplot(np.diff(x), lags=30)
我们的定义成立,确实是白噪声过程!假如我们用随机游走拟合SPY价格的一阶差分会如何?
# First difference of SPY prices
tsplot(np.diff(data.SPY), lags=30)
哇,非常像白噪声!但是看QQ图和概率图。这个过程很像标准正态分布但是有厚尾。在ACF和PACF图上有一些重要的序列相关性,在1,5?16?18和21lags。这意味着应该有更好的模型去描述真实的价格变化过程。
趋势平稳时间序列
可以用直线来刻画时间序列。基本方程是:
在这个模型中,因变量的值由
系数和自变量时间来决定。让我们看一个构造的例子,我们假设ABC公司的销售在初始是$50.00(即
或截距项),每隔时间步长增加$25.00(即
)
# simulate linear trend
# example Firm ABC sales are -$50 by default and +$25 at every time step
w = np.random.randn(100)
y = np.empty_like(w)
b0 = -50.
b1 = 25.
for t in range(len(w)):
y[t] = b0 + b1*t + w[t]
tsplot(y, lags=30)
我们可以看到模型的残差是序列相关的,且随着方程滞后的增加线性关系逐渐减少。分布接近正态。在使用线性模型做预测时我们应该考虑并去除序列里面明显的自相关成分。PACF在滞后1的意义表明AR模型可能是适合的。
对数线性模型
对数线性模型和线性模型很像,不同之处在于数据点形成指数函数,其表示关于每个时间步长的恒定变化率。例如,ABC公司销售量每隔一段时间增长X%,下面是一个模拟的销售数据图。
# Simulate ABC exponential growth
# fake dates
idx = pd.date_range('-01-01', '-01-01', freq='M')
# fake sales increasing at exponential rate
sales = [np.exp( x/12 ) for x in range(1, len(idx)+1)]
# create dataframe and plot
df = pd.DataFrame(sales, columns=['Sales'], index=idx)
with plt.style.context('bmh'):
df.plot()
plt.title('ABC Sales')
我们然后可以用自然对数对销售量进行转换。之后线性模型就能很好的拟合数据了。
# ABC log sales
with plt.style.context('bmh'):
pd.Series(np.log(sales), index=idx).plot()
plt.title('ABC Log Sales')
正如我们之前提到的,这些模型有个致命的缺点。它假设序列不相关的误差,正如我们看到的,在线性模型中是不对的。在真实世界中,时间序列通常违背平稳性假设,这使促使我们进入自回归模型。