使用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)
结果分析
模型预测结果如下图所示:
虽然原数据的变化范围较大,导致预测结果在极值处表现较差,但模型基本能够捕捉到能见度的变化趋势。
热门推荐
遇龙河风景区游玩指南:探秘国内遇龙河旅游最佳攻略
男子吃饭突然"石化"手握筷子待急救!医生揭血糖低出事 拆解10症状教自救方法
当糖尿病遇上低血糖,该如何应对?要怎么预防?
“十一”假期,安全第一!这些安全提示请收藏!
第一届“儿童友好公益节”——发现每个孩子都是一座宝藏
小米用户必看:如何轻松设置一键锁屏?
低GI土豆粉条,健康吃法大揭秘!
土豆粉条:糖尿病患者的低GI食材新选择
谷医堂教你科学吃土豆粉条控血糖
糖尿病患者的福音:土豆粉条真的不升糖?
长白山秋冬打卡:天池+长白瀑布全攻略
《荒野起源》带你探秘长白山
无为市房价新动向:政策调控下的跌势分析
江苏淮安十大必吃美食:从软兜长鱼到十三香龙虾,每一道都值得一试!
《三角洲行动》烽火地带战备攻略:武器装备与药品配置详解
《三角洲行动》机密图生存攻略:武器选择与战术配合详解
旅途必备:这些便携美食让你飞得更健康
福建长乐显应宫:千年古建里的神秘传奇
长乐显应宫:融合郑和与妈祖文化的神秘古迹
TSA最新安检规则:轻松掌握飞机食物携带技巧
飞机旅行带吃的?这些小技巧你必须知道!
漳州美食与茶文化:闽南年味的独特魅力
锂电池维修保养的重要性
沈阳中街到方特乐园最新交通攻略
深部脑刺激术:最新帕金森病手抖疗法解析
帕金森病患者的饮食管理指南
揭秘三角洲部队:如何打造超强心理素质?
跟着《去有风的地方》,打卡沙溪古镇古戏台
用认知负荷理论破解函数学习难题
秋冬打卡漳州必吃:卤面、豆花粉丝、猫仔粥