时间序列LSTM实现

news2024/11/17 22:45:53

这个代码参考了时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)_lstm预测模型-CSDN博客

结合我之前所学的lstm-seq2seq里所学习到的知识对其进行预测

import time
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from matplotlib import pyplot as plt
from sklearn.preprocessing import MinMaxScaler

np.random.seed(0)


def calculate_mae(y_true, y_pred):
    # 平均绝对误差
    mae = np.mean(np.abs(y_true - y_pred))
    return mae


true_data = pd.read_csv(r"C:\Users\33746\Desktop\DailyDelhiClimateTrain.csv")  # 填你自己的数据地址

target = 'meanpressure'

# 这里加一些数据的预处理, 最后需要的格式是pd.series

true_data = np.array(true_data['meanpressure'])

# 定义窗口大小
test_data_size = 32
# 训练集和测试集的尺寸划分
test_size = 0.15
train_size = 0.85
# 标准化处理
scaler_train = MinMaxScaler(feature_range=(0, 1))
scaler_test = MinMaxScaler(feature_range=(0, 1))
train_data = true_data[:int(train_size * len(true_data))]
test_data = true_data[-int(test_size * len(true_data)):]
print("训练集尺寸:", len(train_data))
print("测试集尺寸:", len(test_data))
train_data_normalized = scaler_train.fit_transform(train_data.reshape(-1, 1))
test_data_normalized = scaler_test.fit_transform(test_data.reshape(-1, 1))
# 转化为深度学习模型需要的类型Tensor
train_data_normalized = torch.FloatTensor(train_data_normalized).view(-1)
test_data_normalized = torch.FloatTensor(test_data_normalized).view(-1)


def create_inout_sequences(input_data, tw, pre_len):
    inout_seq = []
    L = len(input_data)
    for i in range(L - tw):
        train_seq = input_data[i:i + tw]
        if (i + tw + 4) > len(input_data):
            break
        train_label = input_data[i + tw:i + tw + pre_len]
        inout_seq.append((train_seq, train_label))
    return inout_seq


pre_len = 4
train_window = 16
# 定义训练器的的输入
train_inout_seq = create_inout_sequences(train_data_normalized, train_window, pre_len)


class LSTM(nn.Module):
    def __init__(self, input_dim=1, hidden_dim=350, output_dim=1):
        super(LSTM, self).__init__()

        self.hidden_dim = hidden_dim
        self.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True)
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        x = x.unsqueeze(1)

        h0_lstm = torch.zeros(1, self.hidden_dim).to(x.device)
        c0_lstm = torch.zeros(1, self.hidden_dim).to(x.device)

        out, _ = self.lstm(x, (h0_lstm, c0_lstm))
        out = out[:, -1]
        out = self.fc(out)

        return out


lstm_model = LSTM(input_dim=1, output_dim=pre_len, hidden_dim=train_window)
loss_function = nn.MSELoss()
optimizer = torch.optim.Adam(lstm_model.parameters(), lr=0.001)
epochs = 10
Train = False  # 训练还是预测

if Train:
    losss = []
    lstm_model.train()  # 训练模式
    start_time = time.time()  # 计算起始时间
    for i in range(epochs):
        for seq, labels in train_inout_seq:
            lstm_model.train()
            optimizer.zero_grad()

            y_pred = lstm_model(seq)

            single_loss = loss_function(y_pred, labels)

            single_loss.backward()
            optimizer.step()
            print(f'epoch: {i:3} loss: {single_loss.item():10.8f}')
            losss.append(single_loss.detach().numpy())
    torch.save(lstm_model.state_dict(), 'save_model.pth')
    print(f"模型已保存,用时:{(time.time() - start_time) / 60:.4f} min")
    plt.plot(losss)
    # 设置图表标题和坐标轴标签
    plt.title('Training Error')
    plt.xlabel('Epoch')
    plt.ylabel('Error')
    # 保存图表到本地
    plt.savefig('training_error.png')
else:
    # 加载模型进行预测
    lstm_model.load_state_dict(torch.load('save_model.pth'))
    lstm_model.eval()  # 评估模式
    results = []
    reals = []
    losss = []
    test_inout_seq = create_inout_sequences(test_data_normalized, train_window, pre_len)
    for seq, labels in train_inout_seq:
        pred = lstm_model(seq)[0].item()
        results.append(pred)
        mae = calculate_mae(pred, labels.detach().numpy())  # MAE误差计算绝对值(预测值  - 真实值)
        reals.append(labels.detach().numpy())
        losss.append(mae)

    print("模型预测结果:", results)
    print("预测误差MAE:", losss)

    plt.style.use('ggplot')

    # 创建折线图
    plt.plot(results, label='real', color='blue')  # 实际值
    plt.plot(reals, label='forecast', color='red', linestyle='--')  # 预测值

    # 增强视觉效果
    plt.grid(True)
    plt.title('real vs forecast')
    plt.xlabel('time')
    plt.ylabel('value')
    plt.legend()
    plt.savefig('test——results.png')

train_data = true_data[:int(train_size * len(true_data))]

test_data = true_data[-int(test_size * len(true_data)):]是在干什么

这两行代码的作用是将数据集 true_data 划分为训练集 train_data 和测试集 test_data。具体来说:

代码解释:

  1. train_data = true_data[:int(train_size * len(true_data))]:

    • train_size 是一个比例值(例如0.8,表示80%),表示训练集占总数据集的比例。

    • len(true_data) 返回 true_data 的长度。

    • train_size * len(true_data) 计算出训练集的大小。

    • int(train_size * len(true_data)) 将计算结果转换为整数,表示训练集的实际样本数量。

    • true_data[:int(train_size * len(true_data))] 使用切片操作从 true_data 的开头到训练集的样本数量,提取出训练集。

  2. test_data = true_data[-int(test_size * len(true_data)):]:

    • test_size 是另一个比例值(例如0.2,表示20%),表示测试集占总数据集的比例。

    • test_size * len(true_data) 计算出测试集的大小。

    • int(test_size * len(true_data)) 将计算结果转换为整数,表示测试集的实际样本数量。

    • true_data[-int(test_size * len(true_data)):] 使用切片操作从 true_data 的末尾到测试集的样本数量,提取出测试集。

示例:

假设 true_data 有100个样本,train_size 为0.8,test_size 为0.2:

  • train_size * len(true_data) = 0.8 * 100 = 80

  • test_size * len(true_data) = 0.2 * 100 = 20

那么:

  • train_data = true_data[:80] 会提取 true_data 的前80个样本作为训练集。

  • test_data = true_data[-20:] 会提取 true_data 的后20个样本作为测试集。

注意事项:

  • 数据顺序:如果 true_data 是有序的(例如时间序列数据),这种划分方式可能会导致训练集和测试集之间存在时间上的重叠,从而引入数据泄露。在这种情况下,应该按照时间顺序进行划分。

  • 随机性:如果 true_data 是无序的,这种划分方式是合理的。但如果数据没有被打乱,建议在划分之前先打乱数据,以确保训练集和测试集能够代表整体数据的分布。

  • 假设 input_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]tw = 3pre_len = 2

  • 第一次循环:

    • i = 0

    • train_seq = [1, 2, 3]

    • train_label = [4, 5]

    • inout_seq = [([1, 2, 3], [4, 5])]

  • 第二次循环:

    • i = 1

    • train_seq = [2, 3, 4]

    • train_label = [5, 6]

    • inout_seq = [([1, 2, 3], [4, 5]), ([2, 3, 4], [5, 6])]

  • 以此类推,直到 i = 7 时,train_seq = [8, 9, 10]train_label = [],此时 i + tw + pre_len 超出 input_data 的范围,循环结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2174729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

革命题材网络电影《突进夹金山》将于10月上线

“长征万里险,最忆夹金山”。这座雪山不仅见证了红军战士们的英勇与牺牲,也成为了中国革命历史上的一座重要里程碑。 革命题材网络电影《突进夹金山》,作为四川省2024年度重点影视剧项目以及纪念红军长征90周年献礼的红色作品,由谢…

死磕P7: JVM类加载那些事儿,一起探知类的前世今生(二)

这是「死磕P7」系列第 006 篇文章,欢迎大家来跟我一起 死磕 100 天,争取在 2025 年来临之际,给自己一个交代。 接上篇,上一篇介绍了 JVM 类加载过程及类的生命周期,回顾一下: 死磕P7: JVM类加载那些事儿&a…

周文强聚焦助学育人,爱心图书室项目圆满完成

日前,一场充满爱心与希望的公益活动在四川甘孜州乡城县尼斯寄宿制小学拉开帷幕。这次名为“520爱心图书室”的公益活动,旨在通过捐赠图书的方式,支持基层青少年的阅读成长。作为此次活动的积极参与者,周文强不仅向学校捐赠了价值1…

python 高效读取多个geojson 写入一个sq3(Sqlite) 、效率提高90%+

1.问题缘由: 由于工作需求,需要将多个(总量10G)geojson文件写入到sq3库,众所周知,sqlite 不支持多线程写入,那该怎么办呢,在网上也查了很多策略,都没有达到立竿见影的效果…

甄选范文“论分布式存储系统架构设计”,软考高级论文,系统架构设计师论文

论文真题 分布式存储系统(Distributed Storage System)通常将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储应用的需要。分布式存储系统采用可扩展的…

车辆重识别(去噪扩散概率模型)论文阅读2024/9/27

[2] Denoising Diffusion Probabilistic Models 作者:Jonathan Ho Ajay Jain Pieter Abbeel 单位:加州大学伯克利分校 摘要: 我们提出了高质量的图像合成结果使用扩散概率模型,一类潜变量模型从非平衡热力学的考虑启发。我们的最…

linux驱动设备程序(内核层、应用层)

一、linux驱动程序 1、分类 字符设备&#xff08;驱动&#xff09;、块设备&#xff08;驱动&#xff09;、网络设备&#xff08;驱动&#xff09;。 2、核心 应用程序运行在用户空间&#xff08;3G&#xff09;&#xff1b;<系统调用>——><陷入>——>&…

正则表达式在过滤交换机lldp信息的应用举例

#include <iostream> #include <string> #include <regex> #include <vector> #include <unordered_map> #include <sstream> #include <unistd.h> // For usleep// 假设存在的 LOG_INFO 和 LOG_WARNING 函数 #define LOG_INFO(...)…

17.第二阶段x86游戏实战2-线程发包和明文包

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

基于docker-compose部署openvas

目录 0.部署openvas 1.编辑docker-compose文件 2.运行compose 3.访问openvas 4.openvas扫描 5.创建任务 6.点击Task Wizard ​编辑 7.输入通讯的IP地址 8.下载报告 9.下载完成 0.部署openvas 1.编辑docker-compose文件 vim docker-compose.yaml version: 3service…

《论文阅读》 用于产生移情反应的迭代联想记忆模型 ACL2024

《论文阅读》 用于产生移情反应的迭代联想记忆模型 ACL2024 前言简介任务定义模型架构Encoding Dialogue InformationCapturing Associated InformationPredicting Emotion and Generating Response损失函数问题前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦…

通信工程学习:什么是MAI多址干扰

MAI:多址干扰 MAI多址干扰(Multiple Access Interference)是无线通信领域,特别是在码分多址(CDMA)系统中,一个关键的干扰现象。以下是对MAI多址干扰的详细解释: 一、定义 多址干扰是指在CDMA系统中,由于多个用户的信号在时域和频域上是混叠的,从而导…

区块链可投会议CCF C--FC 2025 截止10.8 附录用率

Conference&#xff1a;Financial Cryptography and Data Security (FC) CCF level&#xff1a;CCF C Categories&#xff1a;network and information security Year&#xff1a;2025 Conference time&#xff1a;14–18 April 2025, Miyakojima, Japan 录用率&#xff1…

阿里云oss配置

阿里云oss配置 我们可以使用阿里云的对象存储服务来存储图片&#xff0c;首先我们要注册阿里云的账号登录后可以免费试用OSS服务。 之后我们打开控制台&#xff0c;选择对象存储服务&#xff0c;就看到我们下面的画面&#xff1a; 我们点击创建Bucket,之后就会出现如下图界面…

退出系统接口代码开发

退出系统不需要传入参数 请求过滤404的错误--请求次数监听这些都不需要更改 从controller层开始开发代码&#xff0c;因为每个接口都需要增加接口防刷拦截&#xff0c;不然会恶意攻击&#xff0c;所以在这里增加退出系统接口防刷拦截&#xff1b;并退出系统接口没有header和t…

图像分割(九)—— Mask Transfiner for High-Quality Instance Segmentation

Mask Transfiner for High-Quality Instance Segmentation Abstract1. Intrudouction3. Mask Transfiner3.1. Incoherent Regions3.2. Quadtree for Mask RefinementDetection of Incoherent Regions四叉树的定义与构建四叉树的细化四叉树的传播 3.3. Mask Transfiner Architec…

修改Kali Linux的镜像网站

由于官方的镜像可能会出现连接不上的问题导致无法安装我们所需要的包&#xff0c;所以需要切换镜像站为国内的&#xff0c;以下是一些国内常用的Kali Linux镜像网站&#xff0c;它们提供了与Kali Linux官方网站相同的软件包和资源&#xff0c;但访问速度更快&#xff1a; 清华…

Feign:服务挂了也不会走fallback

Feign 本质上是一个 HTTP 客户端&#xff0c;用于简化微服务之间的 HTTP 通信。它允许开发者通过定义接口和注解来声明式地编写 HTTP 客户端&#xff0c;而无需手动编写 HTTP 请求和响应处理的代码。 今天在模拟微服务A feign调用微服务B的时候&#xff0c;把微服务B关了&#…

通过WinCC在ARMxy边缘计算网关上实现智能运维

随着信息技术与工业生产的深度融合&#xff0c;智能化运维成为提升企业竞争力的关键因素之一。ARMxy系列的ARM嵌入式计算机BL340系列凭借其高性能、高灵活性和广泛的适用性&#xff0c;为实现工业现场的智能运维提供了坚实的硬件基础。 1. 概述 ARMxy BL340系列是专为工业应用…

python爬虫案例——抓取链家租房信息(8)

文章目录 1、任务目标2、分析网页3、编写代码1、任务目标 目标站点:链家租房版块(https://bj.lianjia.com/zufang/) 要求:抓取该链接下前5页所有的租房信息,包括:标题、详情信息、详情链接、价格 如: 2、分析网页 用浏览器打开链接,按F12或右键检查,进入开发者模式;因…