使用LSTM模型进行时序数据预测
创作时间:
作者:
@小白创作中心
使用LSTM模型进行时序数据预测
引用
CSDN
1.
https://blog.csdn.net/qq_42035021/article/details/141132537
LSTM模型简介
LSTM(Long Short-Term Memory)是一种循环神经网络(RNN)的变体,主要用于解决序列数据处理中的长期依赖问题。LSTM通过引入记忆单元和门控机制,能够有效地捕捉序列中的长期依赖关系,因此在时序数据预测、自然语言处理等领域得到了广泛应用。
研究目标
本项目的目标是使用临近若干时刻的气象观测数据,预测未来3个时刻的能见度。具体来说,我们将使用温度、露点温度、相对湿度、饱和水汽压差和能见度等气象要素作为输入特征,预测未来的能见度变化。
准备工作
环境准备
本项目需要Python 3.x环境,并安装以下必要库:
- PyTorch
- NumPy
- Pandas
- Scikit-learn
数据准备
数据来源为全国气象站逐小时观测数据,包含以下要素:
- 温度(TEM)
- 露点温度(DPT)
- 相对湿度(RHU)
- 饱和水汽压差(VAP)
- 能见度(VIS)
每个时刻的观测数据存储在一个CSV文件中,文件中的行代表不同的站点观测值,列代表不同的要素属性。
数据预处理
读取数据
首先需要从文件中读取数据。代码如下:
import pandas as pd
import os
import numpy as np
indir = r'./filepath' # 保存所有数据文件的文件夹
file_list = os.listdir(indir) # 获得所有数据文件的文件名
feature_vars = ['TEM', 'DPT', 'RHU', 'VAP', 'VIS']
label_vars = 'VIS'
dataset = []
for f in range(len(file_list)):
df = pd.read_csv(os.path.join(indir, f), na_values=[999999, 999107], usecols=['Station_Id_C', 'Lat', 'Lon', 'TEM', 'DPT', 'RHU', 'VAP', 'VIS'])
df = df.dropna(axis=0, how='any').query('Lat>17 & Lat<29 & Lon>108 & Lon<123') # 剔除所有存在空值的行,并提取目标空间范围内的数据
dataset.append(df.loc[:, feature_vars].values)
dataset = np.array(dataset, dtype=np.float32) # (times, stations, features)
创建样本集
什么是样本?
在时序预测中,一个样本通常包含两部分:特征数据和标签数据。特征数据用于预测目标,标签数据则是预测的目标值。例如,如果我们想用当前时刻的温度和气压预测风速,那么温度和气压组成特征数据,风速则是标签数据。
构造样本集
假设我们需要用最近5个时刻的温度和气压数据,去预测未来3个时刻的风速数据。在这种情况下,我们有三个时间维度:
time_step:用于预测的时间窗口长度pred_step:预测的目标时间长度times:原始观测数据的时间长度
代码实现如下:
time_step = 5
pred_step = 3
samples = []
X = []
Y = []
for i in range(dataset.shape[0] - time_step - pred_step + 1):
X.append(dataset[i:i+time_step, :, :-1]) # (time_step, stations, features)
Y.append(dataset[i+time_step:i+time_step+pred_step, :, -1]) # (pred_step, stations)
X = np.array(X).transpose(0, 2, 1, 3) # (new_times, stations, time_step, features)
Y = np.array(Y).transpose(0, 2, 1) # (new_times, stations, pred_step)
samples_x = X.reshape(-1, time_step, features) # 形状为(samples, time_step, features)
samples_y = Y.reshape(-1, pred_step) # 形状为(samples, pred_step)
拆分样本集
将样本集拆分成训练集、验证集和测试集:
from sklearn.model_selection import train_test_split
train_x, tmp_x, train_y, tmp_y = train_test_split(data_x, data_y, train_size=0.6, random_state=42, shuffle=True)
val_x, test_x, val_y, test_y = train_test_split(tmp_x, tmp_y, train_size=0.5, random_state=42, shuffle=True)
样本归一化
为了消除不同特征之间数值范围差异的影响,需要对数据进行归一化处理:
from sklearn.preprocessing import MinMaxScaler
scale_x = MinMaxScaler()
train_x = scale_x.fit_transform(train_x.reshape(-1, len(feature_vars)).reshape(-1, time_step, len(feature_vars))
val_x = scale_x.transform(val_x.reshape(-1, len(feature_vars))).reshape(-1, time_step, len(feature_vars))
test_x = scale_x.transform(test_x.reshape(-1, len(feature_vars))).reshape(-1, time_step, len(feature_vars))
scale_y = MinMaxScaler()
train_y = scale_y.fit_transform(train_y)
val_y = scale_y.transform(val_y)
test_y = scale_y.transform(test_y)
模型训练
定义LSTM模型
使用PyTorch定义LSTM模型:
import torch
import torch.nn as nn
import torch.optim as optim
class LSTMModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers=1, dropout_rate=0.2):
super(LSTMModel, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
self.num_layers = num_layers
self.dropout_rate = dropout_rate
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.dropout = nn.Dropout(dropout_rate)
self.fc1 = nn.Linear(hidden_size, output_size)
self.relu = nn.ReLU()
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)
out, _ = self.lstm(x, (h0, c0))
out = self.dropout(out[:, -1, :])
out = self.fc1(out)
out = self.relu(out)
return out
模型训练
定义数据加载器和训练函数:
def set_loader(x, y, batch_size):
tensor_x = torch.from_numpy(x)
tensor_y = torch.from_numpy(y)
loader = DataLoader(TensorDataset(tensor_x, tensor_y), batch_size=batch_size, shuffle=True)
return loader
def lstm_train(model, epochs, train_loader, val_loader, learning_rate=0.01, plot_loss=False):
loss_function = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
train_losses = []
val_losses = []
for epoch in range(epochs):
model.train()
train_loss = 0.0
for x_batch, y_batch in train_loader:
optimizer.zero_grad()
outputs = model(x_batch)
loss = loss_function(outputs, y_batch)
loss.backward()
optimizer.step()
train_loss += loss.item() * x_batch.size(0)
train_loss /= len(train_loader.dataset)
train_losses.append(train_loss)
model.eval()
val_loss = 0.0
with torch.no_grad():
for x, y in val_loader:
outputs = model(x)
loss = loss_function(outputs, y)
val_loss += loss.item() * x.size(0)
val_loss /= len(val_loader.dataset)
val_losses.append(val_loss)
print(f'Epoch [{epoch+1}/{epochs}], Train Loss: {train_loss:.4f}, Val Loss: {val_loss:.4f}')
if plot_loss:
fig = plt.figure(figsize=[8,6])
ax = fig.add_subplot(111)
ax.plot(train_losses, 'b', label='train_losses')
ax.plot(val_losses, 'r', label='val_losses')
ax.legend()
ax.set_title(f'Epochs:{epochs} learning_rate:{learning_rate}')
plt.show()
return model
模型预测
使用训练好的模型进行预测:
hidden_size = 16
input_size = len(feature_vars)
output_size = pred_time
batch_size = 16
epochs = 500
train_loader = set_loader(train_x, train_y, batch_size)
val_loader = set_loader(val_x, val_y, batch_size)
model = LSTMModel(input_size, hidden_size, output_size, num_layers=1, dropout_rate=0.3)
model = lstm_train(model, epochs, train_loader, val_loader, learning_rate=0.001, plot_loss=False)
model.eval()
with torch.no_grad():
out = model(torch.from_numpy(test_x))
pred = scale_y.inverse_transform(out)
结果分析
模型预测结果如下图所示:
虽然原数据的变化范围较大,导致预测结果在极值处表现较差,但模型基本能够捕捉到能见度的变化趋势。
热门推荐
拍打委中穴:缓解腰背痛的中医养生秘诀
后背疼痛,当心这些隐藏风险!
流感对症治疗药,怎么选?
夏桑菊与999感冒灵能否同服?一文告诉你
张宏伟债务危机全面爆发,东方集团预重整能否化解140亿债务困局?
网贷逾期自救指南:从绝望到逆袭的实用方案
2024年网贷新规:利率下调至13.8%,这些变化与你息息相关
网贷逾期还款,法律帮你搞定!
上海市松江区隔代抚养的祖辈角色探讨
高血压对心血管的影响有多大?
类风湿性关节炎:日常护理与轻松运动全攻略
花木兰:替父从军的传奇与文化符号
京剧中的女英雄:花木兰、穆桂英和秦良玉
生成科学想法快2.5倍,西湖大学Nova系统助力科研创新
一文读懂医学实验设计:5种常用方法与RCT详解
AI驱动科研变革:实验效率大幅提升,但需警惕三大风险
1.8T vs 2.0T:如何选择最适合你的发动机排量?
Excel记账入门:SUMIFS函数实现收支智能管理
《奥特曼激斗英雄》最新版本游戏评测:3D格斗玩法,还原经典体验
加湿器使用不当会致病?这份安全使用指南请收好
揭秘真太阳时:时间测量的天文原理与应用
健康红烧茄子这样做:少油不减味,营养又美味
在线培训软件开发:打造高效企业学习平台的四大优势
电动观光车驶入无人驾驶新赛道
丹后半岛电动游,解锁最美海岸线
电动旅游:绿色出行引领未来旅游新趋势
喜婆婆怎样盘头
喜婆婆怎样盘头
移民美国:无犯罪记录证明的详细要求与流程
无犯罪记录证明:解析其含义与用途