目录
1.基础知识
1.1什么是时间序列
时间间隔不变的情况下收集的不同时间点数据集合,这些集合被分析用来了解长期发展趋势及为了预测未来。时间序列数据当中重要的模型ARIMA模型
1.2应用场景
有规律可循才能进行预测,时间序列数据必须要有惯性,数据的内部有一定的平稳性
- 股票数据:根据股票历史数据的增长情况,预测未来的趋势;
- 降雨量:根据当前降雨量预测未来一周或者一个月的降雨情况.
和自身历史数据相关的数据一般斗可以同时间序列来处理
1.3相关系数
1.3.1自相关函数ACF
ACF:不同时间序列和当前值的相关性(有序随机变量序列和自身相比较)
公式:
作用:反应的是同一序列在不同时序取值之间的相关性
范围:[-1,1]
描述:虚线表示置信区间,置信度如果在95%以内,表示这个区间的值可以相信
1.3.2偏自相关PACF
1.3.3ACF和PACF的异同
对于自相关ACF来说,我们的到的并不是x(t)和x(t-k)之间单纯的相关关系,同时还受到中间k-1个随机变量x(t-1),x(t-2)...x(t-k+1)的影响,而k-1个随机变量又都和x(t-k)具有相关关系,所以自相关系数中还掺杂了其他的变量对x(t)与x(t-k)的影响;剔除了中间的k-1个随机变量的干扰之后,x(t-k)与x(t)影响的相关程度.
最大的区别:ACF包含了其他变量的影响,但是PACF是严格的两个变量之间的相关性.;PACF想计算哪个阶就计算哪个阶而ACF还要把中间的值考虑进去.
1.3平稳性
1.3.1什么是平稳性?
平稳性:均值和方差没有发生明显的变化。
1.3.2平稳性分类
严平稳:均值和方差没有发生明显的变化(分布不随时间的变化而变化)。
- eg:未来时刻t的值要依赖于过去的信息,期望不发生变化。
- 2019年降雨量的趋势和2020年降雨量的趋势是差不多的。
弱平稳:保持均值和相关性系数不发生明显的变化。严平稳太严格了,大多数情况下都是弱平稳。
1.3.2什么样的数据才算平稳?
序列预处理:拿到时间序列数据之后,首先要对它的平稳性和随机性进行检验。根据检验的结果可以讲序列分成不同的类型,对不同类型的序列我们采用不同的分析方法。
什么样的数据才算平稳?:围绕着一个常数上下不波动且波动的范围是有限的,有常数均值和常数方差。如果有明显的趋势或者周期性,那它通常不是平稳序列
1.3.3检验平稳性
方法一:绘制时序图
方法二:利用自相关系数和偏自相关系数检验
- AC:自相关系数
- PAC:偏自相关系数
- Q统计量
- 伴随概率
平稳的自相关图不是截尾(某个值之后直接变成0)就是拖尾(趋近于0),这里的0指的是在置信区间当中.
- AC拖尾,PAC在p阶后截尾,则AR(p)算法;
- AC在q阶后截尾,PAC拖尾,则MA(q)算法;
- AC和PAC都是拖尾,则是ARIMA(p,d,q)算法
方法三:单位根检验
原假设为具有单位根,则非平稳,对于平稳的时间序列就需要在给定的置信水平上显著,拒绝原假设。p>0.99,拒绝原假设,使用ADF检验单位根,如果想要通过其他方式检验,我们可以使用arch库,检验序列中是否存在单位根,如果存在单位根就是非平稳时间序列。
1.3.4如何解决不平稳?
差分法:当前值和历史值做减法。
- 一阶差分:t2-t1,t3-t2。
- 二阶查分:在一阶差分的基础上再做一次差分。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
x=np.linspace(1,100,40)
y=np.random.randint(20,25,size=40)
y=pd.Series(y)
y1=y.diff(1)
y2=y1.diff(1)
plt.figure(figsize=(16,3))
plt.plot(x,y,label='x,y')
plt.plot(x,y1,label='x,y1')
plt.plot(x,y2,label='x,y2')
plt.legend()
1.5时间序列和回归的异同点
- 回归分析假设每个数据点之间独立,而时间序列则是利用数据之间的相关性进行预测;
- 回归分析和自回归模型看上去有很大的相似性。但是由于缺失了独立性,利用线性回归求解的自回归模型参数会是有偏的。但又由于这个解是一致的,所以在实际应用中还是利用线性回归来近似AR模型,忽视或者假设数据的独立性很可能会造成模型的失效。金融市场的预测建模尤其需要注意这一点。
2.ARIMA模型
2.1自回归模型-AR
AR:描述当前值和历史值之间的关系,用变量自身的历史时间数据对自身进行预测。
公式:
yt表示当前值,u表示常数项 p表示阶数 ri表示自相关系数 表示误差
限制
- 用自身的数据做预测
- 必须是平稳的
- 适用于预测与前期相关的现象.
- 具有自相关性如果自相关系数小于0.5,那么就不能采用自回归
2.2移动平均模型-MA
MA:该模型主要关注的是自回归模型中的误差项的累加
公式:q阶自回归模型
作用:有效的消除了预测中的随机波动
2.3ARIMA模型
ARIMA是自回归与移动平均的结合.差分自回归移动平均模型
公式:
原理
将非平稳的时间序列转换成平稳的时间序列然后将因变量进对他的滞后值以及随机误差项的现值和滞后值进行回归所建立的模型.
,
表示系数;p和q表示观察到的阶数,u表示常数即截距,
表示误差
3.时间序列建模
3.1环境搭建
- 下载statsmodels
- 切换到存放到该文件的目录下,不加载缓存安装:pip3 --no-cache-dir install 安装路径
- acf和pacf帮助我们进行模型参数的选择
3.2ARIMA建模流程
- 将序列平稳(方差法确定d值)
- p和q阶数确定:ACF和PACF
- ARIMA(p,d,q)
- 通过AIC和BIC选择更加简单的模型
3.3模型参数选择
3.3.1使用ACF和PACF看图选择
3.3.2通过AIC和BIC绘图选择
- AIC赤池信息准则:AIC=2k-2ln(L)
- BIC贝叶斯信息准则:BIC=kln(n)-2ln(L),引入了样本的数量对我们的行为准则也有影响
- k表示模型参数的个数,n表示样本的数量,L表示似然函数
- k越小越好,L越大越好
3.3.3通过遍历的方式选择
from __future__ import absolute_import,division,print_function
import sys
import os
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import statsmodels.api as sm
import statsmodels.formula.api as snf
import statsmodels.tsa.api as smt
import seaborn as sns
pd.set_option('display.float_format',lambda x:"%.5f"%x)
np.set_printoptions(precision=5,suppress=True)
pd.set_option('display.max_columns',100)
pd.set_option('display.max_rows',100)
sns.set(style='ticks',context='poster')
fig=plt.figure(figsize=(12,8))
ax1=fig.add_subplot(211)
fig=sm.graphics.tsa.plot_acf(sentiment_short,lags=20,ax=ax1)
ax1.xaxis.set_ticks_position('bottom')
fig.tight_layout()
ax2=fig.add_subplot(212)
fig=sm.graphics.tsa.plot_pacf(sentiment_short,lags=20,ax=ax2)
ax2.xaxis.set_ticks_position('bottom')
fig.tight_layout()
import itertools
p_min=0
d_min=0
q_min=0
p_max=4
d_max=0
q_max=4
result_bic=pd.DataFrame(
index=['AR{}'.format(i) for i in range(p_min,p_max+1)],
columns=['MA{}'.format(i) for i in range(q_min,q_max+1)]
)
for p,d,q in itertools.product(range(p_min,p_max+1),
range(d_min,d_max+1),
range(q_min,q_max+1)):
if p==0 and d==0 and q==0:
result_bic.loc['AR{}'.format(p),'MA{}'.format(q)]=np.nan
continue
try:
model=sm.tsa.SARIMAX(train_data,order=(p,d,q))
results=model.fit()
result_bic=result_bic[result_bic.columns].astype(float)
fig,ax=plt.subplots(figsize=(10,8))
ax=sns.heatmap(
result_bic,
mask=result_bic.isnull(),
ax=ax,
annot=True,
fmt='.2f',
)
ax.set_title("BIC")
result_bic.loc['AR{}'.format(p),'MA{}'.format(q)]=results.bic
except:
continue
3.4模型残差检验
ARIMA模型的残差是否是平均值为0且方差为常数的正太分布
检验方法:QQ图(如果是线性,那就是正太分布);画出来的图如果符合一条直线,那就符合正太分布,否则不符合
model_results.plot_diagnostics(figsize=(16,12))
3.5pandas构造时间序列
时间序列一般有三种方式:
- 时间戳:具有到某个时间点
- 时间周期
- 时间间隔
重要函数:date_range()
创建时间序列
# 这里可以如果有结束时间,那么就不可以有时间周期
rng=pd.date_range(
start='2018/07/01', # 起始时间
periods=10, # 时间周期
freq='D' # 以天为迭代周期,叠加天M,Y,H,3D
)
pd.date_range('2010-01-01','2011-01-01',freq='1D1H')
pd.date_range(dt.datetime(2016,1,1),periods=20)
time.truncate(before='2016-1-10') # 获取2016-1-10之前的时间
time.truncate(after='2016-1-10') # 获取2016-1-10之后的时间
pd.Timestamp('2016-07-10 10:15:2') # 时间戳
pd.Period('2016-01') # 时间区间
pd.Timedelta('1 day') # 时间偏移量
pd.Period('2016-01-01')+pd.Timedelta('1 day') # 运算
ts_period=ts.to_period() # 将时间戳转换成时间周期
ts_period['2016-07-10 08:30':'2016-07-10 11:45'] # 时间周期的切片包含结尾值
ts['2016-07-10 08:30':'2016-07-10 11:45'] # 时间戳的切片不包含结尾值
3.6重采样
描述:举个例子,我们现在按月统计了一年当中每周的降雨量,现在我们想要按天统计这一年的降雨量我们称为升采样,如果我们想要按月统计这一年的降雨量,这个叫降采样.
降采样
统计90天每天的降雨量
rng=pd.date_range('2011/01/01',periods=90,freq='D')
ts=pd.Series(np.random.randn(len(rng)),index=rng)
ts.head()
# 降采样:每月统计一次,求取每个月的降雨量总和,降采样
ts.resample('M').sum()
升采样
在进行升采样的时候,样本数量增多,就会出现大量的空样本,这时候我们应该填充,填充的方法有:
- - ffill:空值取前值,ffill(1):填充的个数
- - bfill:空值取后值
- - interpolate('linear'):线性取值
不同频率统计出来的结果是不一样的,这样我们就可以多角度多维度的分析我们的数据
# 每个月的降雨量
rng=pd.date_range('2011/01/01',periods=9,freq='M')
ts=pd.Series(np.random.randn(len(rng)),index=rng)
# 每天的降雨量
ts.resample('D').interpolate('linear')
3.7滑动窗口
举个例子:我现在有2016年1月1日到2020年1月1日的降雨量数据,我们想每10天统计一次,那么窗口的长度就是10,而得到的结果中前9次的统计值都是空值(NaN)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
df=pd.Series(
np.random.randn(600),
index=pd.date_range('2016/7/1',freq='D',periods=600)
)
r=df.rolling(window=10) # 创建华东2窗口
print(r.mean()) # 滑动窗口的均值
plt.figure(figsize=(15,5))
df.plot(style='r--')
df.rolling(window=10).mean().plot(style='b') # 对滑动窗口的值做可视化展示
3.8ARIMA时间序列预测
操作步骤
- 绘制出时间序列数据
- 如果该模型是不平稳的,需要我们进行差分,一阶或者二阶
- 绘制ACF和PACF图选取p和q的值
- 建模ARIMA
- 预测:predict('20140607','20161214',dynamic=True,type=levels)
我们还可以同时间序列做分类的任务:tsfresh包提供了提取当前时间序列特征的模块,分类的目的是什么情况下时间序列的值是正常的什么情况下时间序列的值是异常的.
最后说说数据提取:
- 提取数据的时候我们必须明白属性代表的含义?属性之间的关系?哪些属性会影响我们最终的结果,我们把可能影响我们值的属性提取出来,然后进行预处理,编码,数值填充等操作,还可以根据具体的情况进行降维,最后才是建模和做预测,最后才是模型的评估.