使用 LSTM(长短期记忆网络) 模型对时间序列数据(航空旅客人数数据集)进行预测

news/2024/11/22 22:25:13/

代码功能

  1. 数据准备
    加载数据:从公开的航空旅客人数数据集(Airline Passengers Dataset)中读取时间序列数据。
    对数变换和平稳化:对数据应用 log1p 函数减少趋势和波动,使模型更容易学习规律。
    归一化处理:将数据缩放到 [0, 1] 区间,以适应神经网络训练。
  2. 数据集创建
    滑动窗口机制:使用过去 seq_length(12个月)作为输入,预测下一个月的值。
    划分数据集:将时间序列数据划分为训练集(80%)和测试集(20%)。
  3. 模型定义
    LSTM 模型:
    输入特征维度:每个月的数据点作为输入特征(维度为 1)。
    隐藏层维度:每层隐藏层包含 128 个神经元。
    层数:10 层 LSTM 堆叠,增加模型的表达能力。
    全连接层(FC Layer):LSTM 的输出通过全连接层,生成最终预测值。
  4. 模型训练
    损失函数:使用均方误差(MSE),衡量预测值与真实值之间的误差。
    优化器:使用 Adam 优化器,动态调整学习率提高收敛速度。
    GPU 加速:如果设备支持,则将模型和数据移至 GPU,显著加速训练。
    训练过程中,模型使用批量数据更新权重,逐步最小化损失函数。
  5. 模型评估
    预测值生成:在测试集上进行预测。
    反归一化和还原对数变换:将预测值和真实值转换回原始规模,便于直观对比。
    性能评估:计算均方误差(MSE),衡量模型的预测准确性。
  6. 可视化结果
    实际值 vs. 预测值:绘制原始数据的真实值与预测值对比图,直观展现模型效果。
    在这里插入图片描述

代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import torch
from torch import nn
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from torch.utils.data import DataLoader, TensorDataset# 1. 加载数据
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv"
data = pd.read_csv(url, parse_dates=['Month'], index_col='Month')
data_values = data['Passengers'].values.astype(float).reshape(-1, 1)# 对数变换使数据平稳化
data_log = np.log1p(data_values)# 归一化数据
scaler = MinMaxScaler(feature_range=(0, 1))
normalized_data = scaler.fit_transform(data_log)# 2. 创建数据集函数
def create_dataset(data, seq_length):X, y = [], []for i in range(len(data) - seq_length):X.append(data[i:i + seq_length])y.append(data[i + seq_length])return np.array(X), np.array(y)seq_length = 12  # 使用过去12个月预测下一个月
X, y = create_dataset(normalized_data, seq_length)# 划分训练集和测试集
train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]# 转换为 PyTorch 张量
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_test = torch.tensor(y_test, dtype=torch.float32)# 创建 DataLoader
train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)# 3. 定义 LSTM 模型
class LSTMModel(nn.Module):def __init__(self, input_dim, hidden_dim, output_dim, num_layers):super(LSTMModel, self).__init__()self.hidden_dim = hidden_dimself.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True, dropout=0.2)self.fc = nn.Linear(hidden_dim, output_dim)def forward(self, x):h0 = torch.zeros(num_layers, x.size(0), self.hidden_dim).to(x.device)c0 = torch.zeros(num_layers, x.size(0), self.hidden_dim).to(x.device)out, _ = self.lstm(x, (h0, c0))out = self.fc(out[:, -1, :])return out# 超参数设置
input_dim = 1
hidden_dim = 128
output_dim = 1
num_layers = 10  # 增加到10层 LSTM
learning_rate = 0.0001
num_epochs = 300# 初始化模型、损失函数和优化器
model = LSTMModel(input_dim, hidden_dim, output_dim, num_layers)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)# 检查 GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)# 4. 模型训练
for epoch in range(num_epochs):model.train()for X_batch, y_batch in train_loader:X_batch, y_batch = X_batch.to(device), y_batch.to(device)outputs = model(X_batch)optimizer.zero_grad()loss = criterion(outputs, y_batch)loss.backward()optimizer.step()if (epoch + 1) % 10 == 0:print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")# 5. 模型评估
model.eval()
with torch.no_grad():y_pred = model(X_test.to(device)).cpu().numpy()# 反归一化预测结果
y_test_inv = scaler.inverse_transform(y_test.numpy())
y_pred_inv = scaler.inverse_transform(y_pred)# 计算均方误差 (MSE)
mse = mean_squared_error(np.expm1(y_test_inv), np.expm1(y_pred_inv))  # 还原对数变换
print(f"Mean Squared Error: {mse:.4f}")# 6. 可视化预测结果
plt.figure(figsize=(12, 6))
plt.plot(data.index[-len(y_test):], np.expm1(y_test_inv), label='Actual')
plt.plot(data.index[-len(y_test):], np.expm1(y_pred_inv), label='Predicted', color='orange')
plt.title('Airline Passenger Data Prediction')
plt.xlabel('Date')
plt.ylabel('Passengers')
plt.legend()
plt.show()

http://www.ppmy.cn/news/1549140.html

相关文章

Modern Effective C++ Item 11:优先考虑使用deleted函数而非使用未定义的私有声明

C98 方法:private C98 将特殊成员函数(如拷贝构造函数和拷贝赋值运算符)声明为私有且不定义。这种方法可以防止客户端调用这些函数,但如果在成员函数或友元函数中调用这些函数,会在链接时引发错误。C11 使用 delete …

MongoDB 监控:确保数据库性能和可靠性

MongoDB 监控:确保数据库性能和可靠性 MongoDB 是一个流行的开源 NoSQL 数据库,以其灵活的文档模型和强大的查询语言而闻名。然而,为了确保 MongoDB 的性能和可靠性,监控是至关重要的。本文将讨论 MongoDB 监控的重要性、关键监控…

linux安装TDengine

linux安装TDengine 下载tar.gz安装包,下载地址:使用安装包快速体验 TDengine | TDengine 文档 | 涛思数据 创建TD的安装目录,并将下载好的安装包复制到此目录下。 mkdir /usr/local/tdengine/ 解压安装包 tar -zxvf TDengine-server-3.2.…

[开源] 告别黑苹果!用docker安装MacOS体验苹果系统

没用过苹果电脑的朋友可能会对苹果系统好奇,有人甚至会为了尝鲜MacOS去折腾黑苹果。如果你只是想体验一下MacOS,这里有个更简单更优雅的解决方案,用docker安装MacOS来体验苹果系统。 一、项目简介 项目描述 Docker 容器内的 OSX&#xff08…

labelme格式与yolo格式区别

概述 Labelme格式和YOLO格式是两种用于图像标注的常见格式,主要用于目标检测和图像分割任务。 矩形标注: 矩形标注labelme文件格式(json): { {"version": "2024.11.5.0","flags": {}…

实验室管理解决方案:Spring Boot技术

6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…

「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解

本篇将详细介绍 Cangjie 中的浮点类型,包括浮点数的表示方法、精度、舍入与溢出处理、科学计数法表示、字面量的进制表示、常用运算、类型转换及应用场景,帮助开发者掌握浮点数的使用方法。 关键词 浮点类型表示精度与舍入溢出与下溢科学计数法类型转换…

智慧社区方案提升居民生活质量与管理效率的创新实践

内容概要 智慧社区方案的背景与发展趋势指向了一个日益重要的方向,随着城市化进程的加快,传统的社区管理模式逐渐显得力不从心。在这个时候,智慧社区应运而生,它通过将现代信息技术与社区管理深度结合,为提升居民生活…