利用ARIMA模型进行时间序列的预测实现

ARIMA模型利用历史数据对时间序列进行预测,属于参数型方法,全称Autoregressive Integrated Moving Average Model,是集合了自回归模型AR(Autoregressive)、移动平均模型MA(Moving Average)和差分过程I(Integrated)的模型。

ARIMA(p,d,q)模型中的参数p, d, q分别来源于对应的三个部分:
AR部分:利用过去的值来预测未来的值,假设是线性关系,即利用过去p个值的加权平均来进行预测;
I差分部分:通过差分操作,来消除时间序列中的趋势和季节性因素,d代表差分的阶数;
MA部分:利用过去的误差来预测未来的值,假设时间序列是平稳的,也假设呈线性关系,利用过去q个白噪声的加权平均来进行预测。

实现ARIMA模型使用statsmodels包:statsmodels.tsa.arima.model.ARIMA

一、基本用法

构建模型

from statsmodels.tsa.arima.model import ARIMA

model = ARIMA(data, order=(7,0,1))
model_fit = model.fit()

模型训练时输入什么类型,则预测输出也是同样的类型,输入array,预测结果也是array, 输入带datetimeindex的series或dataframe,预测结果也是带datetimeindex的series或dataframe,其中datetimeindex需要指定频率,因为ARIMA模型要求时间序列的时间间隔相等。

进行预测时可以用forecastpredict方法。

forecast预测

pred = model_fit.forecast() # 一步预测
pred = model_fit.forecast(steps=5) # 多步预测 指定步数
pred = model_fit.forecast('2012-03-06 14:40:00') # 多步预测 指定end datetime

ARIMA模型本质只能预测未来一步,多步预测采用的是recursive循环的计算方法。

predict预测

# 指定要预测区间的起止index,index是相对于模型训练数据而言的,训练数据的第一个ts的index为0
pred = model_fit.predict(start=start_index, end=end_index) 
# 只有一个输入时,代表start index,预测start index至数据集的最后一个ts
pred = model_fit.predict(1000)
# 指定要预测区间的起止datetime
pred = model_fit.predict(start='2012-03-06 14:20:00', end='2012-03-07 23:55:00')

其中有个参数“dynamic”,dynamic=False代表使用真值true value, dynamic=True则使用预测值predicted value,例如在对 t + 1 t+1 t+1时刻预测时,使用的所有历史值都是真值,但对 t + 2 t+2 t+2时刻预测时,需要用到 t + 1 t+1 t+1时刻的值,可以使用真值,也可以使用模型的预测值。

forecast VS predict

forecast和predict的主要差别在于forecast只能对未来进行计算,而predict可以对过去进行计算,即官方说明中的,forecast是out-of-sample forecasting,predict是In-sample prediction and out-of-sample forecasting。
还有两个方法get_forecastget_prediction,用法与之类似,只是相比forecast和predict会额外返回置信区间。

二、预测实例

数据使用los loop,数据取自数据集METR-LA,由洛杉矶高速公路上的环形探测器检测得到的车速,采样频率5min,共四个月,论文作者取了2012年3月1日-3月7日七天的数据,并对缺失数据进行了线性插值处理。

按照8:2划分训练集和测试集,验证ARIMA模型的准确性。

import pandas as pd
from statsmodels.tsa.arima.model import ARIMA
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimSun']

data = pd.read_csv('./data/los_speed.csv')
time_len = data.shape[0] # 2016个ts
num_nodes = data.shape[1] # 207个检测器

data.index = pd.date_range('2012-03-01', periods=2016 , freq='5min') # 设置datetimeindex
ts = data.iloc[:,10] # 只取某一个检测器
train_size = int(time_len * 0.8)
train_ts, test_ts = ts[0:train_size], ts[train_size:]

训练集train_ts如下:

2012-03-01 00:00:00    55.500000
2012-03-01 00:05:00    58.777778
2012-03-01 00:10:00    61.375000
2012-03-01 00:15:00    62.138889
2012-03-01 00:20:00    62.902778
                         ...    
2012-03-06 13:55:00    64.875000
2012-03-06 14:00:00    63.000000
2012-03-06 14:05:00    64.000000
2012-03-06 14:10:00    64.000000
2012-03-06 14:15:00    64.000000
Freq: 5T, Name: 765604, Length: 1612, dtype: float64

训练集test_ts 如下:

2012-03-06 14:20:00    64.000000
2012-03-06 14:25:00    62.250000
2012-03-06 14:30:00    63.666667
2012-03-06 14:35:00    63.250000
2012-03-06 14:40:00    60.875000
                         ...    
2012-03-07 23:35:00    67.111111
2012-03-07 23:40:00    66.125000
2012-03-07 23:45:00    61.000000
2012-03-07 23:50:00    67.000000
2012-03-07 23:55:00    64.125000
Freq: 5T, Name: 765604, Length: 404, dtype: float64
# 构建模型
model = ARIMA(train_ts,order=[12,0,1]) # 利用过去12条数据来预测未来
properModel = model.fit()

## 预测1,使用预测值预测
# 模型的样本中只有2012-03-06 14:15:00前的数据,无论dynamic取何值,预测时只能用预测值
predict1 = properModel.predict(start='2012-03-06 14:20:00', end='2012-03-07 23:55:00')

## 预测2,使用真值预测
# 为了预测时能使用真值,加上测试数据,但不重新训练模型,即模型的参数不变,只是模型的样本改变了
newModel = properModel.append(test_ts, refit=False)
predict2 = newModel.predict(start='2012-03-06 14:20:00', end='2012-03-07 23:55:00',dynamic=False)

fig, ax = plt.subplots(figsize=(15,4))
ax.plot(test_ts, label='groundtruth')
ax.plot(predict1, label='使用预测值')
ax.plot(predict2, label='使用真值')
plt.legend()
plt.show()

在这里插入图片描述

由图可知,预测时如果只使用预测值,因为采用循环计算策略,会导致误差不断累积;
而如果预测时使用过去的真值,即预测 t + 2 t+2 t+2时刻的值时,使用 t + 1 t+1 t+1时刻的真值,预测 t + 3 t+3 t+3时刻的值时,又使用 t + 2 t+2 t+2时刻的真值,符合实际运行情况,每一步的预测结果的准确度相对稳定,误差不会随着时间而累积。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值