最近我在进行论文的写作,接下来会将自己做的对比算法分享给大家,以帮助像我一样遇到问题想来CSDN上求救的小伙伴们。我采用的数据集为PeMS04和PeMS08,如果有使用相同数据集的小伙伴们可以一起交流。
做到ARIMA对比算法时,发现固定order的ARIMA算法无法做到对所有全时空路网节点的流量进行预测,会出现报错情况。因为路网所有节点的交通流量不一定都符合同一ARIMA参数,便采用auto_arima算法对所有节点的交通流量进行预测。
相关库的引入
import numpy as np
import pandas as pd
from pmdarima.arima import auto_arima # 引入auto_arima算法模型,需要安装一下pmdarima库
from sklearn.preprocessing import MinMaxScaler # 运用MinMax方法对数据进行归一化模块
评价指标
时序预测模型的评价指标通常均采用MAE、MAPE和RMSE三者。相对应的计算方法如下:
def MAE(pred, true):
return np.mean(np.absolute(pred-true))
def MAPE(pred, true):
return np.mean(np.absolute(np.divide((true - pred), true)))
def RMSE(pred, true):
return np.sqrt(np.mean(np.square(pred-true)))
数据加载与预处理
我们采用加利福尼亚州高速公路的数据集PeMS04来进行演示。首先对交通数据集进行读取
data = np.load(r'PeMS04.npz')
。
接下来对数据集进行处理:
1、数据集中包含三个部分:1)交通流量;2)交通占比;3)交通速度。我们使用交通流量进行时序预测。
flow_data = data['data'].transpose([1, 0, 2])[:, :, 0][:, :, np.newaxis] # np.newaxis的作用为增加数据的维度
true = []
predict = [] # 定义存储真实值和预测值的列表
node_num = len(flow_data[:,0,0]) # 路网节点的个数
for node in range(node_num):
node_data = flow_data[node, 13536:16992, :] # 单个节点流量的读取以及小数据集的选取,数据集的大小应与自己算法的测试集的大小一致
node_data = pd.DataFrame(node_data) # 将numpy数据类型转变为pandas
node_data.columns = list('Y')
# 归一化
scaler = MinMaxScaler()
node_data['Y'] = scaler.fit_transform(node_data)
# 设置预测时间长度和历史长度
history_len = 24
predict_len = 1 # 短时交通流预测,长时的话可以更改为需要的时间长度
history = node_data['Y']
构建auto_arima预测模型
for t in range(node_data['Y'].shape[0]-history_len-predict_len+1):
inputs = history[t:history_len+t]
model = auto_arima(inputs, start_p=1, start_q=1,
test='adf',
max_p=3, max_q=3, m=12,
seasonal=True,
d=None,trace=False,
error_action='ignore',
suppress_warnings=True) # 第一步:模型的构建
model.fit(inputs) # 第二步:运用fit命令去拟合模型
y_hat = model.predict(1) # 第三步:进行预测,这个1为单步预测,可以将其设置为>1的整数,进行多步预测
auto_arima模型中的参数我在这里进行简要说明,详细内容大家可以查询CSDN上大佬们的详细解读。auto_arima模型的好处便是不需要选择固定的p,d和q的参数组合,模型会根据自己设定的p,d,q的取值范围自己设置参数组合,并依据模型生成的AIC值和BIC值来对参数组合的最终选择进行确定,最终运用筛选出来的参数组合进行预测。
-
inputs
:为历史时间长度的输入值,通过这些数值对下一个或多个时刻的交通流量值进行预测; -
start_p
:为ARIMA中p的起始值,自回归(“AR”)模型的阶数(或滞后时间的数量),必须是正整数; -
start_q
:为ARIMA中q的初始值,移动平均(MA)模型的阶数。必须是正整数; -
max_p
:为ARIMA中p的最大值必须大于或等于初始值,且为整数; -
max_q
:为ARIMA中q的最大值必须大于或等于初始值,且为整数; -
max_d
:为ARIMA模型中d的最大值,即非季节差异的最大数量。必须是大于或等于d的正整数; -
Seasonal
:是否适合季节性ARIMA。默认是True。注意,如果Seasonal为True,而m = 1,则Seasonal将设置为False; -
m
:m为周期个数; -
d
:时间序列是否平稳,若为None则为不平稳; -
test
:用来检测平稳性的单位根检验的类型,默认为’kpss’;可设置为’adf’; -
trace
:是否打印适合的状态。如果值为False,则不会打印任何调试信息。值为真会打印一些(没必要打印过程所以我设置了False); -
error_action
:如果出于种种原因无法匹配ARIMA,可以控制其错误处理行为,一般选为(‘ignore’); -
suppress_warnings
:如果为True,则来自ARIMA中所有的警告都会被压制。
数据存储
对预测值与真实进行收集:
#预测值反归一化以及预测值存储
y_hat = scaler.inverse_transform(y_hat[:, np.newaxis]) # 反归一化
predict.append(y_hat) # 数据存储
#真实值反归一化以及真实值存储
a = np.array(history[history_len+t:history_len+t+predict_len])
a = scaler.inverse_transform(a[:, np.newaxis])
true.append(a)
预测效果评价
为了评价模型的预测效果,我用开始设定的评价指标对其进行评价。
prediction = np.array(predict)
truth = np.array(true)
prediction = prediction[:, np.newaxis]
truth = truth[:, np.newaxis]
ARIMA_mape = MAPE_np(prediction, truth)
ARIMA_mae = MAE_np(prediction, truth)
ARIMA_rmse = RMSE_np(prediction, truth)
总结
我们使用auto_arima模型时,避免了一个参数无法适应所有道路的情况,可以用一个算法跑完所有的节点。但相对来说,时间消耗非常巨大,大家做对比实验时需要有耐心。