基于Python的LSTM网络实现单特征预测回归任务(TensorFlow)

单特征:数据集中只包含2列,时间列+价格列,仅利用价格来预测价格

目录

一、数据集

二、任务目标

三、代码实现

1、从本地路径中读取数据文件

2、数据归一化

3、创建配置类,将LSTM的各个超参数声明为变量,便于后续使用

4、创建时间序列数据

5、划分数据集

6、定义LSTM网络

(1)创建顺序模型实例

(2)添加LSTM层

(3)添加全连接层

7、编译LSTM模型

8、训练模型

9、模型预测

10、数据反归一化

11、绘制图像

12、完整版代码


一、数据集

自建数据集--【load.xlsx】。包含2列:

  • date列时间列,记录2022年6月2日起始至2023年12月31日为止,日度数据
  • price列价格列,记录日度数据对应的某品牌衣服的价格,浮点数)

二、任务目标

实现基于时间序列的单特征价格预测

三、代码实现

1、从本地路径中读取数据文件

  • read_excel函数读取Excel文件(read_csv用来读取csv文件),读取为DataFrame对象
  • index_col='date''date'列设置为DataFrame的索引
  • .values属性获取price列的值,pandas会将对应数据转换为NumPy数组
# 字符串前的r表示一个"原始字符串",raw string
# 文件路径中包含多个反斜杠。如果我们不使用原始字符串(即不使用r前缀),那么Python会尝试解析\U、\N等作为转义序列,这会导致错误
data = pd.read_excel(r'E:\load.xlsx', index_col='date')
# print(data)
prices = data['price'].values
# print(prices)

打印data:

打印prices:

2、数据归一化

  • 归一化:将原始数据的大小转化为[0,1]之间,采用最大-最小值归一化
    • 数值过大,造成神经网络计算缓慢
    • 在多特征任务中,存在多个特征属性,但神经网络会认为数值越小的,影响越小。所以可能关键属性A的值很小,不重要属性B的值却很大,造成神经网络的混淆
  • scikit-learn的转换器通常期望输入是二维的,其中每一行代表一个样本,每一列代表一个特征
    • prices.reshape(-1, 1) 用于确保 prices 是一个二维数组,即使它只有一个特征列
    • -1的意思是让 NumPy 自动计算该轴上的元素数量,以保持原始数据的元素总数不变
    • fit方法计算了数据中每个特征的最小值和最大值,这些值将被用于缩放
    • transform方法使用这些统计信息来实际缩放数据,将其转换到 [0, 1] 范围内
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_prices = scaler.fit_transform(prices.reshape(-1, 1)) # 二维数组
# print(scaled_prices)

打印归一化后的价格数据:

3、创建配置类,将LSTM的各个超参数声明为变量,便于后续使用

  • timestep:时间步长,滑动窗口大小
  • feature_size:每个步长对应的特征数量,这里只使用1维,即每天的价格数据
  • batch_size:批次大小,即一次性送入多少个数据(一时间步长为单位)进行训练
  • output_size:单输出任务,输出层为1,预测未来1天的价格
  • hidden_size:隐藏层大小,即神经元个数
  • num_layers:神经网络的层数
  • learning_rate:学习率
  • epochs:迭代轮数,即总共要让神经网络训练多少轮,全部数据训练一遍成为一轮
  • best_loss:记录损失
  • activation = 'relu':定义激活函数使用relu
class Config():timestep = 7  # 时间步长,滑动窗口大小feature_size = 1 # 每个步长对应的特征数量,这里只使用1维,每天的价格数据batch_size = 1 # 批次大小output_size = 1 # 单输出任务,输出层为1,预测未来1天的价格hidden_size = 128 # 隐藏层大小num_layers = 1 # lstm的层数learning_rate = 0.0001 # 学习率epochs = 500 # 迭代轮数model_name = 'lstm' # 模型名best_loss = 0  # 记录损失activation = 'relu' # 定义激活函数
config = Config()

4、创建时间序列数据

  • 通过滑动窗口移动获取数据,时间步内数据作为特征数据,时间步外1个数据作为标签数据
  • 通过序列的切片实现特征和标签的划分
  • 通过np.array将数据转化为NumPy数组

# 创建时间序列数据
X, y = [], []
for i in range(len(scaled_prices) - config.timestep):# 从当前索引i开始,取sequence_length个连续的价格数据点,并将其作为特征添加到列表 X 中。X.append(scaled_prices[i: i + config.timestep])# 将紧接着这sequence_length个时间点的下一个价格数据点作为目标添加到列表y中。y.append(scaled_prices[i + config.timestep])
X = np.array(X)
print(X)
y = np.array(y)
print(y)

打印特征数据: 

  • 三维数组,X 是由多个二维数组(即多个时间步长的数据)组成的,加之本身是一个列表
  • 每次迭代都会从 scaled_prices 中取出一个长度为 config.timestep 的连续子序列,并将其添加到 X 列表中
  • 由于 scaled_prices 本身是一个二维数组,所以每次取出的子序列也是一个二维数组,形状大致为 [config.timestep, features]
  • 当多个这样的二维数组被添加到 X 列表中时,X 就变成了一个列表的列表,其中每个内部列表都是一个二维数组
  • 它的形状将是 [n_samples - config.timestep, config.timestep, features],这是一个三维数组

打印标签数据:

  • 二维数组,y 是由单个数据点(即单个时间步长的数据)组成的,所以它保持为二维数组
  • 从 scaled_prices 中取出一个单独的数据点(即一个二维数组中的一行),并将其添加到 y 列表中
  • y 列表中的每个元素都是一个一维数组(或可以看作是一个具有多个特征的向量)
  • 它的形状将是 [n_samples - config.timestep, features],这仍然是一个二维数组

5、划分数据集

  • 按照9:1的比例划分训练集和测试集
  • train_test_split:是sklearn.model_selection模块中的一个函数,用于将数据集随机划分为训练集和测试集
  • shuffle=False:表示在划分数据之前不进行随机打乱,意味着数据会按照其原始顺序进行划分
  • 因为时间序列数据具有时序性,用过去时间数据预测新时间数据,要保证时间有序
  • 测试数据为时间序列的末尾数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, shuffle=False)

6、定义LSTM网络

(1)创建顺序模型实例

model = Sequential()

(2)添加LSTM层

  • LSTM:这是 Keras 中提供的 LSTM 层的类。通过调用这个类,创建一个 LSTM 层
  • activation=config.activation:这设置了 LSTM 层中使用的激活函数
  • units=config.hidden_size:这设置了 LSTM 层中的隐藏单元数量
  • input_shape=(config.timestep, config.feature_size):这定义了输入数据的形状,是一个元组
    • 告诉模型,输入数据应该是一个形状为[batch_size, config.timestep, config.feature_size]的三维
    • 其中batch_size是批次中样本的数量,它在模型训练时会自动确定(根据你传递给模型的批次数据大小)
model.add(LSTM(activation=config.activation, units=config.hidden_size, input_shape=(config.timestep, config.feature_size)))
  •  LSTM层的输出是一个三维张量,其形状通常为(seq_len, batch_size, num_directions * hidden_size)
    • seq_len表示序列长度,即时间序列展开的步数
    • batch_size表示数据批次的大小,即一次性输入到LSTM层的数据样本数量
    • num_directions * hidden_size表示隐藏层的输出特征维度
      • 对于单向LSTM,num_directions为1
      • 对于双向LSTM,num_directions为2。hidden_size则是隐藏层节点数,即LSTM单元中隐藏状态的维度
    • 含义:LSTM层的输出包含了每个时间步的隐藏状态

(3)添加全连接层

  • Dense:是 Keras 中用于创建全连接层的类,也就是每个输入节点与输出节点之间都连接有一个权重
  • config.output_size:指定了该全连接层的输出单元数量
model.add(Dense(config.output_size))
  • 由于此例中,全连接层的大小为1,因此LSTM层输出的三维张量在经过全连接层后将被压缩成一个二维张量
  • (batch_size, 1)这样的形状

7、编译LSTM模型

  • model.compile():这个方法是Keras模型的一个函数,用于配置模型训练前的参数
  • optimizer='adam':这里指定了使用Adam优化器来训练模型
  • loss='mean_squared_error':这里指定了损失函数为均方误差(Mean Squared Error, MSE)
model.compile(optimizer='adam', loss='mean_squared_error')

8、训练模型

  • model.fit():是 Keras 模型的一个函数,用于训练模型。它将根据提供的训练数据 X_train 和对应的标签 y_train通过多次迭代(epochs)来训练模型。
  • x=X_train:指定了训练数据的输入
  • y=y_train:指定了训练数据的标签(或目标值)
  • epochs=config.epochs:指定了训练过程中数据集的完整遍历次数。
  • batch_size=config.batch_size:指定了每次更新模型时使用的样本数
  • verbose=2:控制训练过程中的日志输出。verbose=2 表示每个 epoch 输出一行日志,显示训练过程中的损失值和评估指标(如果在编译时指定了评估指标)
  • history 对象是一个记录训练过程中信息的字典,包含了训练过程中的损失值和评估指标(如果有的话)
history = model.fit(x=X_train, y=y_train, epochs=config.epochs, batch_size=config.batch_size, verbose=2)

9、模型预测

  • model.predict():是 Keras 模型的一个函数,它根据提供的输入数据,给出模型对于这些数据的预测结果
predictions = model.predict(X_test)

10、数据反归一化

  • 当模型训练完成后并进行预测时,预测出的值会是缩放后的值(即按照训练数据缩放的比例)
  • 为了得到原始的比例或范围,需要使用缩放器的 inverse_transform 方法来将这些缩放后的值转换回原始的比例或范围
y_test_true_unnormalized = scaler.inverse_transform(y_test)
y_test_preds_unnormalized = scaler.inverse_transform(predictions)
  • 确保模型的预测结果和真实的测试集标签都在同一个比例或范围内,从而可以准确地评估模型的性能,并以更直观、更易于理解的方式呈现预测结果

11、绘制图像

# 设置图形的大小为10x5单位
plt.figure(figsize=(10, 5))# 绘制真实的测试集标签,使用圆圈('o')作为标记,并命名为'True Values' 
plt.plot(y_test_true_unnormalized, label='True Values', marker='o')# 绘制模型的预测值,使用叉号('x')作为标记,并命名为'Predictions' 
plt.plot(y_test_preds_unnormalized, label='Predictions', marker='x')# 设置图形的标题
plt.title('Comparison of True Values and Predictions')# 设置x轴的标签
plt.xlabel('Time Steps')# 设置y轴的标签
plt.ylabel('Prices')# 显示图例 
plt.legend()# 显示图形
plt.show()

12、完整版代码

import pandas as pd
import numpy as np
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from matplotlib import pyplot as plt
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropoutclass Config():timestep = 7hidden_size = 128batch_size = 1output_size = 1epochs = 500feature_size = 1activation = 'relu'
config = Config()# dataframe对象
qy_data = pd.read_excel(r'E:\load.xlsx', index_col='date')
# print(qy_data)
# numpy数组 一维
prices = qy_data['price'].values
# print(prices)scaler = MinMaxScaler()
# 归一化后变成二维数组
scaled_prices = scaler.fit_transform(prices.reshape(-1, 1))
# print(scaled_prices)# Create time series data
X, y = [], []
for i in range(len(scaled_prices) - config.timestep):X.append(scaled_prices[i: i + config.timestep])y.append(scaled_prices[i + config.timestep])
X = np.array(X)
# print(X)
y = np.array(y)
# print(y)# Train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, shuffle=False)# Define the LSTM mode
model = Sequential()
model.add(LSTM(activation=config.activation, units=config.hidden_size, input_shape=(config.timestep, config.feature_size)))
model.add(Dense(config.output_size))# Compile the model
# adam默认学习率是0.01
model.compile(optimizer='adam', loss='mean_squared_error')model.save('LSTM.h5')# Train the model
history = model.fit(x=X_train, y=y_train, epochs=config.epochs, batch_size=config.batch_size, verbose=2)# Predictions
predictions = model.predict(X_test)# Inverse transform predictions and true values
y_test_true_unnormalized = scaler.inverse_transform(y_test)
y_test_preds_unnormalized = scaler.inverse_transform(predictions)# Plot true values and predictions
plt.figure(figsize=(10, 5))
plt.plot(y_test_true_unnormalized, label='True Values', marker='o')
plt.plot(y_test_preds_unnormalized, label='Predictions', marker='x')
plt.title('Comparison of True Values and Predictions')
plt.xlabel('Time Steps')
plt.ylabel('Prices')
plt.legend()
plt.show()

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php开发-个人博客项目文件操作类编辑器上传下载删除读写

特地整了个软件 这就舒服了 文件操作类的开发 文件的任意上传,下载,读取,删除操作等 1.文件上传类-任意文件上传 分为三类 1,代码自主编写的 先写一个html的上传表单,这个网上搜索就有 标题看着不够明确啊&#…

【牛客】【模板】差分

原题链接:登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 差分模板。 b[0]a[0]; b[1]a[1]-a[0]; b[2]a[2]-a[1]; ...... b[n-1]a[n-1]-a[n-2]; b[n]a[n]-a[n-1]; 差分标记:b[l]k,b…

计算机网络chapter1——家庭作业

文章目录 复习题1.1节(1) “主机”和“端系统”之间有何不同?列举几种不同类型的端系统。web服务器是一种端系统吗?(2)协议一词常用来用来描述外交关系,维基百科是如何描述外交关系的&#xff1…

基于Springboot的校园悬赏任务平台(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的校园悬赏任务平台(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…

Codigger:Web应用让开发者拥有更高效的开发之旅

在当今软件开发领域,Web应用以其跨平台、易访问和实时更新的特性,逐渐成为了主流的开发方向。从开发者的视角来看,Codigger借助B/S(浏览器/服务器)架构和云计算技术,为开发者带来了诸多便利和优势。这些优势…

【负载均衡式在线OJ项目day1】项目结构

一.功能 查看题目列表,在线编程,判题功能,即leetcode的部分功能 二.宏观结构 整个项目是BS模式,客户端是浏览器,和用户交互并向服务器发起请求。 服务端从功能上来说分为两个模块,第一个是OJServer&…

C++ 多态(一)

一、多态定义 同一种操作作用于不同的对象时,可以产生不同的行为。在面向对象编程中,多态性是指通过继承和重写实现的,同一个方法在不同的子类中可以表现出不同的行为。多态性可以提高代码的灵活性和可扩展性,使得程序更易于维护…

盘点企业信息防泄密软件对比|揭秘企业信息防泄密软件好用榜

在当今信息化社会,企业信息防泄密软件的需求日益凸显。这些软件不仅关乎企业的核心竞争力,更直接关系到企业的生死存亡。本文将对市面上几款主流的企业信息防泄密软件进行深入对比分析,以期为企业提供有益的参考。 一、企业信息防泄密软件好…

987: 输出用先序遍历创建的二叉树是否为完全二叉树的判定结果

解法: 一棵二叉树是完全二叉树的条件是: 对于任意一个结点,如果它有右子树而没有左子树,则这棵树不是完全二叉树。 如果一个结点有左子树但是没有右子树,则这个结点之后的所有结点都必须是叶子结点。 如果满足以上条…

docker学习笔记(三)搭建NFS服务实验

目录 什么是NFS 简单架构​编辑 一.搭建nfs服务器 二.新建共享目录和网页文件 三.设置共享目录 四:创建使用nfs共享目录的卷 五:创建容器使用nfs-web-1卷 六:测试访问 七:是否同步测试 什么是NFS NFS 服务器:ne…

webpack如何自定义一个loader

我们在使用脚手架的搭建项目的时候往往都会帮我们配置好所需的loader,接下来讲一下我们要如何自己写一个loader应用到项目中(完整代码在最后) 1. 首先搭建一个项目并找到webpack配置文件(webpack.config.js) 在modul…

95、动态规划-编辑距离

递归暴力解法 递归方法的基本思想是考虑最后一个字符的操作,然后根据这些操作递归处理子问题。 递归函数定义:定义一个递归函数 minDistance(i, j),表示将 word1 的前 i 个字符转换成 word2 的前 j 个字符所需的最小操作数。 递归终止条件…

无人直播需要什么软件系统?最新AI实景自动无人直播软件:智能化引领直播拓客新时代

随着互联网的快速发展(无人直播招商加盟:hzzxar)直播行业已经成为商家品牌推广和商品销售的热门方式。近年来,人工智能技术的飞速发展,催生了一款令人惊叹的AI实景自动无人直播软件,为商家提供了全新的直播…

ADG的备库mrp进程状态一直显示WAIT_FOR_LOG

ADG的备库mrp进程状态一直显示WAIT_FOR_LOG 问题描述 在搭建完单机主备的adg后,MRP0进程的状态一直显示WAIT_FOR_LOG,这个和预期的APPLYING_LOG不符。另外经过测试发现,主备插入数据,备库只有当手动切换归档日志,备库…

前后端分离项目中的一些疑惑

1、前后端分离项目,浏览器发起请求后,请求的是前端服务器还是后端服务器? 在前后端分离的项目中,当浏览器发起请求时,它首先会请求的是前端服务器。 前后端分离的工作流程大致如下: 用户在浏览器中输入网…

【Linux】深浅睡眠状态超详解!!!

1.浅度睡眠状态【S】(挂起) ——S (sleeping)可中断睡眠状态 进程因等待某个条件(如 I/O 完成、互斥锁释放或某个事件发生)而无法继续执行。在这种情况下,进程会进入阻塞状态,在阻塞状态下,进程…

开源离线AI笔记应用

前言 Reor 是一款人工智能驱动的桌面笔记应用程序,它能自动链接相关笔记、回答笔记中的问题并提供语义搜索。所有内容都存储在本地,支持 Windows、Linux 和 MacOS。Reor 站在 Ollama、Transformers.js 和 LanceDB 等巨头的肩膀上,使 LLM 和嵌…

C语言—操作符详解(操作符、进制转换、原码反码补码、结构体)

1.操作符分类 算术操作符&#xff1a; 、- 、 * 、 / 、%移位操作符&#xff1a;<< >> //移动的是二进制位位操作符&#xff1a;& | ^ //使用二进制位进行计算赋值操作符&#…

【FX110】2024外汇市场中交易量最大的货币对是哪个?

作为最大、最流动的金融市场之一&#xff0c;外汇市场每天的交易量高达几万亿美元&#xff0c;涉及到数百种货币。不同货币对的交易活跃程度并不一样&#xff0c;交易者需要根据货币对各自的特点去进行交易。 全年外汇市场中涉及美元的外汇交易超过50%&#xff01; 实际上&…

下一代自动化,国外厂商如何通过生成性AI重塑RPA?

企业自动化的未来趋势是什么&#xff1f;科技巨头们普遍认为&#xff0c;由生成性AI驱动的AI Agent将成为下一个重大发展方向。尽管“AI Agent”这一术语尚无统一定义&#xff0c;但它通常指的是那些能够根据指令通过模拟人类互动&#xff0c;在软件和网络平台上执行复杂任务的…