目录:
- 介绍
- 背景
- 数据预处理
- LSTM模型构建
- 模型训练与评估
- 结论
- 参考
介绍
时间序列预测是一种统计技术,用于预测按时间排序的一系列数据点的未来值。它涉及分析历史数据模式以识别数据中的趋势、模式和季节性,然后使用该信息来预测未来值。由于时间序列预测的广泛应用,包括金融、天气预报、销售预测等,因此在各个领域都必不可少。
由于时间序列数据的特征(包括趋势、季节性和噪声),时间序列预测提出了独特的挑战。了解和应对这些挑战对于确保准确可靠的预测至关重要,我们将在接下来的章节中介绍这些挑战。
在本文中,我们重点介绍 LSTM,它代表长短期记忆,是一种循环神经网络 (RNN),因其能够有效地对顺序数据中的长期依赖性进行建模而广受欢迎,使其非常适合用于时间序列预测任务。LSTM 是 RNN 的一种变体,专门用于解决梯度消失问题,这是训练深度神经网络的常见问题。
背景
LSTM 具有独特的架构,允许它们在扩展序列上捕获和存储信息,从而使它们能够处理具有长期依赖性的时间序列数据。LSTM 的关键特征是它的记忆单元,它可以长时间存储信息,并在处理新数据点时有选择地忘记或更新这些信息。这使得 LSTM 能够有效地捕捉时间序列数据中的模式,包括趋势、季节性和其他复杂的依赖关系。
LSTM 捕获序列中的长期依赖性的能力来自于记忆单元和门控机制的结合。记忆单元允许 LSTM 在长序列上存储信息,门机制(输入门、遗忘门和输出门)允许 LSTM 有选择地更新和遗忘信息,使它们能够捕获相关的长期依赖关系,同时忽略不相关的信息。
LSTM模型的架构:
- 记忆单元(记忆门) :允许 LSTM 在长序列上捕获和存储信息。它有一个内部状态,根据门的输入和输出在每个时间步更新
- 输入门:确定当前时间步长的输入量应存储在记忆单元中。它将来自前一个时间步的输入特征和隐藏状态作为输入,并将它们传递给一个 sigmoid 激活函数,该函数为每个特征生成一个介于 0 和 1 之间的值。
- 遗忘门:确定应遗忘或擦除前一时间步长的存储单元中的信息量。它将来自前一个时间步的输入特征和隐藏状态作为输入,并将它们传递给 sigmoid 激活函数。遗忘门的输出与当前记忆单元状态逐元素相乘,允许 LSTM 有选择地从记忆单元中擦除信息。
- 输出门:确定在当前时间步应输出多少存储单元状态。它将来自前一个时间步的输入特征和隐藏状态作为输入,并将它们传递给 sigmoid 激活函数。当前记忆单元状态然后通过 tanh 激活函数,tanh 激活的输出与输出门的输出逐元素相乘,产生 LSTM 的最终输出。
EDA 和数据预处理
如前所述,我们将处理来自 Kaggle 的每日气候数据(来源:www.kaggle.com/datasets/su… ?datasetId=312121&sortBy=voteCount&searchQuery=LSTM ) .
印度德里的数据时间范围为 1 月 13 日至 4 月 17 日,具有温度、湿度、风速和压力等属性。
电子数据分析
我们从时间序列的基本 EDA 开始,观察整个时间段内所有变量的相当稳定的图表。平均温度肯定有季节性,我们将在未来讨论
plt.figure(figsize=( 20 , 10 ))
colors = [ '#FF7F50' , '#DDA0DD' , '#66CDAA' , '#BC8F8F' ]
for i, j in 枚举(df.set_index( 'date' ) .columns):
plt.subplot( len (df.set_index( 'date' ).columns) + 1 , 1 , i + 1 )
plt.plot(df.set_index( 'date' )[j], color=colors[我]);
plt.ylabel(j, fontsize= 16 )
plt.grid()
plt.xlabel( '日期', 字体大小= 16 )
绘制数据中的所有变量
ADF 平稳性检验
我们通过利用 ADF 测试检查然后检查时间序列的平稳性,并观察到 >0.05 的 p 值 0.15 表明时间序列中的非平稳性
test_results = adfuller(df[ "meantemp" ])
print ( f"ADF 测试统计: {test_results[ 0 ]} " )
print ( f"p-value: {test_results[ 1 ]} " )
print ( "临界阈值:" )
for key, value in test_results[ 4 ].items():
print ( f"\t {key} : {value} " )
为了纠正时间序列中的非平稳性,我们对数据进行对数变换以使其平稳
fig, ax = plt.subplots(3, 1, figsize=(20, 15))
ax[0].plot( df [ "date" ], df [ "meantemp" ], label= "原始系列" )
ax[ 1].plot( df [ "date" ], np.log( df [ "meantemp" ]), label= "对数转换后" )
df [ "meantemp_transformed" ] = pd.Series(np.log( df [ " meantemp" ])).diff(periods=12) # 12 个月
df.dropna(inplace=True)
ax[2].plot( df [ "date" ],df ["meantemp_transformed" ], label= "差分后" );
执行对数转换后,我们再次执行 ADF 检验并获得 ~1.34(e-5) 的 ADF 检验的 p 值,这使我们能够拒绝零假设并确认平稳性
缩放
一旦我们有了固定时间序列,我们将使用 MinMaxScaler 缩放数据以将所有值置于 0,1 范围内。缩放具有重要作用,因为它直接影响模型性能,强烈推荐
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df.drop(columns= 'date' ))
df_scaled = pd.DataFrame(df_scaled, columns=df.drop(columns= 'date' ).columns)
经典滑动窗
我们需要将数据框转换为滑动窗口张量,这是 LSTM 模型中需要的输入。我们使用 10 天作为过去数据的窗口
滑动窗口
def create_window ( target, feature, window= 1 , offset= 0 ):
feature_new, target_new = [], []
feature_np = feature.to_numpy()
target_np = target.to_numpy()
对于范围内的 i (window, target.shape[ 0 ] - 偏移量): feature_list = feature_np[i - window:i] feature_new.append(feature_list.reshape(window, feature_np.shape[ 1 ])) target_new.append(target_np[i+offset].reshape( 1 ))返回np.array(feature_new), np.array(target_new) window = 10 feature_columns = [
'湿度' , 'wind_speed' , 'meanpressure' , 'meantemp' ]
特征, target = create_window(df_scaled[ 'meantemp' ],df_scaled[feature_columns], window=window)
df_scaled.head()
训练-测试拆分
最后,在数据预处理中,我们会根据时间顺序将数据拆分为Train-Test
def train_test ( feature, target, perc_train = 0.9 ):
size_train = int ( len (feature) * perc_train)
x_train = feature[ 0 :size_train]
y_train = target[ 0 :size_train]
x_test = feature[size_train: len (feature)]
y_test = target[size_train: len (feature)]
返回x_train, x_test, y_train, y_test
平均温度的训练测试拆分
LSTM 建模构建
我们主要处理了所需的数据预处理,所以现在让我们深入研究模型构建部分。我们将使用具有 LSTM 和密集层的深层网络的顺序模型和均方误差作为我们的评估指标
def model_lstm (x_shape):
模型 = keras. 顺序()
模型。添加( keras.layers.LSTM ( 50 ,return_sequences=True, input_shape=(x_shape[ 1 ], x_shape[ 2 ]))) 模型。添加(keras.layers.LSTM ( 64 , return_sequences = False)) 模型。添加(keras.layers.Dense ( 32 )) 模型。添加(keras.layers.Dense ( 16 ) ) 模型。添加(keras.layers。
密集(x_shape[ 2 ]))
模型。编译(loss= 'mean_squared_error' , optimizer= 'adam' )
返回模型
模型训练与评估
完成模型训练后,我们将进入其性能评估。从下图中,我们可以判断模型性能相当不错,我们能够实现非常低的 MSE 损失,约为 0.003。
总的来说,如果我们看到测试的预测值与原始值的汇编,重叠非常好,表明模型能够理解模式并准确预测
结论
因此,我们总结了我们对 LSTM 的学习和在时间序列数据集上的实际应用。