哪种型号效果更好?
> Source: Photo by Comfreak from Pixabay
在此示例中,ARIMA和LSTM模型用于预测爱尔兰都柏林市议会市政办公室的用电量模式。
有问题的数据来自data.ie。
具体而言,以每15分钟的千瓦消耗量提供数据。
分析分为三个阶段:
· 调用相关的数据处理程序以汇总每天的总千瓦消耗量,即形成每日时间序列。
· 使用ARIMA模型预测整个验证集的千瓦能耗。
· 使用LSTM模型在整个验证集中生成另一个预测,并检查预测是否有所改善。
数据处理
这是加载到Python中的原始数据集。
df=pd.read_csv('dccelectricitycivicsblocks34p20130221-1840.csv',
engine='python',
skipfooter=3)
df
> Source: Jupyter Notebook Output
我们可以看到,对于每个日期,每隔15分钟就会提供一次相关的电量消耗。
但是,在这种情况下,我们希望预测每天的总消费量,并且如果时间序列以15分钟为基础形成,那么波动性将会太大,从而使任何预测都显得肤浅。
在这方面,每天对数据进行排序:
df2=dfame(columns=df.iloc[0])
df3=df2.drop(df.index[0])
df3
df3.drop(df3.index[0])
df4=df3.drop('Date', axis=1)
df5=df4.drop('Values', axis=1)
df5
df6=df5.dropna()
df7=df6.values
df7
dataset=np.sum(df7, axis=1, dtype=float)
dataset
相应的列被重命名,并且每天的千瓦消耗量被汇总。
形成一个包含每日汇总数据的numpy数组:
array([4981.5001927 , 5166.60016445, 3046.35014537, 3101.10013769, 4908.60016439, 4858.50017742, 4905.00019836, 4999.95019526,... 2383.5 , 4481.5 , 4543. , 4390. , 4385. , 4289.5 , 2564. , 2383. ])
这是数据图:
> Source: Jupyter Notebook Output
ARIMA
ARIMA模型(或自回归综合移动平均模型)用于获取相关时间序列的组成部分(即p,d和q参数),并据此做出新的预测。
尽管将使用pmdarima自动选择这些坐标,但定义季节性趋势很重要。
时间序列的前80%(554个观测值)用作训练数据。这是在此训练集上生成的自相关函数的图。
> Source: Jupyter Notebook Output
我们可以看到,在滞后7处识别出最高的正相关性(在负相关性之后)。这表明与原始7天后的千瓦读数之间存在很强的相关性。
在这方面,ARIMA模型的季节性分量被标识为m=7。
在运行ARIMA模型之前,让我们快速浏览一下此时间序列的7天移动平均线,以便更好地可视化整体趋势。
> Source: Jupyter Notebook Output
我们可以看到,该系列的上半年总能耗量似乎正在减少,而下半年则有所增加。
值得注意的是,我们可以看到该系列中途出现了急剧下降,这显然标志着该系列中的异常。
这可能是由于断电或其他一些事件导致富贵论坛用电量突然下降。在运行预测时,我们必须牢记,过去的数据不一定会解释这种"时间序列冲击"。
使用训练数据,现在使用pmdarima进行逐步搜索以最小化AIC值,即选择显示最低AIC的ARIMA模型。
>>> Arima_model=pm.auto_arima(train_df,
start_p=0,
start_q=0,
max_p=10,
max_q=10,
start_P=0,
start_Q=0,
max_P=10,
max_Q=10,
m=7,
stepwise=True,
seasonal=True,
information_criterion='aic',
trace=True,
d=1,
D=1,
error_action='warn',
suppress_warnings=True,
random_state=20,
n_fits=30)
Performing stepwise search to minimize aic
ARIMA(0,1,0)(0,1,0)[7] : AIC=8483.714, Time=0.04 sec
ARIMA(1,1,0)(1,1,0)[7] : AIC=8421.989, Time=0.12 sec
ARIMA(0,1,1)(0,1,1)[7] : AIC=8319.248, Time=0.34 sec
ARIMA(0,1,1)(0,1,0)[7] : AIC=8360.091, Time=0.10 sec
ARIMA(0,1,1)(1,1,1)[7] : AIC=inf, Time=0.78 sec
ARIMA(0,1,1)(0,1,2)[7] : AIC=inf, Time=1.36 sec
ARIMA(0,1,1)(1,1,0)[7] : AIC=8328.690, Time=0.27 sec
ARIMA(0,1,1)(1,1,2)[7] : AIC=inf, Time=2.29 sec
ARIMA(0,1,0)(0,1,1)[7] : AIC=8451.400, Time=0.18 sec
ARIMA(1,1,1)(0,1,1)[7] : AIC=inf, Time=0.81 sec
ARIMA(0,1,2)(0,1,1)[7] : AIC=inf, Time=0.75 sec
ARIMA(1,1,0)(0,1,1)[7] : AIC=8415.537, Time=0.09 sec
ARIMA(1,1,2)(0,1,1)[7] : AIC=inf, Time=1.16 sec
ARIMA(0,1,1)(0,1,1)[7] intercept : AIC=8321.247, Time=1.30 sec
Best model: ARIMA(0,1,1)(0,1,1)[7] Total fit time: 9.588 seconds
最合适的ARIMA模型被标识为ARIMA(0,1,1)(0,1,1)[7]。
现在,可以对接下来的126天进行预测,并将预测结果与在整个验证集中获得的实际结果进行比较。
prediction=pd.DataFrame(Arima_model.predict(n_periods=126), index=val_df)
prediction=np.array(prediction)
调整预测的形状以确保验证集和预测的格式相同:
prediction=prediction.reshape(126,-1)
均方根误差计算如下:
>>> mse=mean_squared_error(val_df, prediction)
>>> rmse=math.sqrt(mse)
>>> print('RMSE: %f' % rmse)
RMSE: 1288.000396
验证集中的平均千瓦消耗为3,862。鉴于RMSE误差占均值大小的33%,这表明ARIMA模型在预测用电量方面可以做得更好。
为了更直观地了解发生了什么,我们来绘制预测和验证数据。
> Source: Jupyter Notebook Output
我们可以看到ARIMA模型很好地反映了该系列的季节性趋势。就是说,图表前半部分的峰值消耗预测似乎比实际要高得多。
此外,我们看到该模型无法捕获整个验证集中大约70-80天之间的千瓦时能耗下降。这种异常可能会导致我们为RMSE值看到的较大误差,因为RMSE旨在更严厉地惩罚异常值。
LSTM
现在,在这组数据上实现了LSTM模型,以检查使用这种方法时预测准确性是否有所提高。
数据以与上述最初相同的方式进行操作,即通过在一天的时间内每15分钟汇总一次用电量来形成每日时间序列。
数据分为训练和验证数据:
train_size=int(len(df) * 0.8)
val_size=len(df) - train_size
train, val=df[0:train_size,:], df[train_size:len(df),:]
形成一个数据集矩阵:
def create_dataset(df, previous=1):
dataX, dataY=[], []
for i in range(len(df)-previous-1):
a=df[i:(i+previous), 0]
dataX.append(a)
dataY.append(df[i + previous, 0])
return np.array(dataX), np.array(dataY)数据归一化
为了使LSTM模型正确解释数据,对数据进行了标准化。
但是,在实施此过程时有一个很大的警告。训练和验证集必须分别分开(如上所述),然后分别对每个训练集进行缩放。
实施LSTM模型时的一个常见错误是仅对整个数据集进行缩放。这是错误的,因为缩放器会将验证集中的值用作缩放的基准,从而导致数据泄漏回到训练集中。
例如,让我们假设假设训练集的规模为1–1000,假设验证集的规模为1–1200。MaxMinScaler会将比例缩小为0–1之间的数字。如果同时在训练集和验证集上对数据进行缩放,那么MaxMinScaler还将使用1–1200的缩放比例作为训练集的基准。这意味着验证集已损害了整个训练集的新量表,从而导致预测不可靠。
因此,我们示例中的数据按如下比例缩放:
scaler=MinMaxScaler(feature_range=(0, 1))
train=scaler_transform(train)
trainval=scaler_transform(val)
valLSTM模型配置
现在已经对数据进行了缩放,因此需要实施回溯期,即在时间t进行预测时,我们希望LSTM模型考虑多少个先前期。
经过反复试验,回溯期5显示了预测时的最低RMSE。
lookback=5
X_train, Y_train=create_dataset(train, lookback)
X_val, Y_val=create_dataset(val, lookback)
然后,将输入调整为具有样本,时间步长,特征的格式。
LSTM网络的定义和训练是:
# Generate LSTM network
model=tf.keras.Sequential()
model.add(LSTM(4, input_shape=(1, lookback)))
model.add(Dense(1))
modelpile(loss='mean_squared_error',
optimizer='adam')
history=model(X_train,
Y_train,
validation_split=0.2,
epochs=100,
batch_size=1,
verbose=2)
这是训练和验证损失的图:
> Source: Jupyter Notebook Output
生成预测,然后将其转换回原始比例(在先前使用MinMaxScaler转换之后):
trainpred=model.predict(X_train)
valpred=model.predict(X_val)
trainpred=scaler.inverse_transform(trainpred)
Y_train=scaler.inverse_transform([Y_train])
valpred=scaler.inverse_transform(valpred)
Y_val=scaler.inverse_transform([Y_val])
predictions=valpred
现在,可以通过将预测与实际验证数据进行比较来计算预测准确性。
首先,这是预测数据与实际数据的曲线图。
> Source: Jupyter Notebook Output
计算RMSE值。
>>> mse=mean_squared_error(Y_val, predictions)
>>> rmse=sqrt(mse)
>>> print('RMSE: %f' % rmse)
RMSE: 410.116102
验证集的平均值为3909。RMSE的大小占平均值的10%,这意味着该模型在预测用电量趋势方面显示出优于ARIMA的性能。
从图中可以看出,LSTM模型擅长于预测消费水平低于正常水平的时期。假设LSTM是一个单步预测模型,即没有时间前五周的值就无法预测时间t的千瓦时,这在某种程度上是可以预期的-这不是长期预测。
也就是说,LSTM模型在解决该系列的波动性方面更为有效。
结论
在此示例中,我们看到了:
· 如何使用Pandas进行数据操作
· 配置ARIMA模型以进行长期预测
· LSTM模型提前一步进行预测
· 如何使用RMSE评估预测准确性
非常感谢您的宝贵时间,相关的GitHub存储库以及数据集和代码示例可在此处找到。
免责声明:本文按"原样"撰写,不作任何担保。本文档旨在概述数据科学概念,不应将其理解为专业建议。本文中的发现和解释是作者的发现,并不受本文提及的任何第三方的认可或附属。
联系客服