LSTM实例解析

大家好,这里是七七,今天带给大家的实例解析。以前也用过几次LSTM模型,但由于原理不是很清楚,因此不能清晰地表达出来,这次用LSTM的时候,去自习研究了原理以及代码,来分享给大家此次经历。


一、简要介绍

由于RNN(循环神经网络)模型的梯度消失现象,会导致RNN模型的失效,因此人们对RNN的隐含层神经元进行改造,便有了LSTM(长度期记忆)模型。

至于对RNN的修改,可参考循环神经网络(RNN)-CSDN博客

 本文来重点介绍这次实现过程中的代码

二、代码部分

1、数据预处理

在构建模型之前,需要先收集数据,并将各种数据存储在表格中,并用python代码导入,这部分是基础部分,与建模无关,就不展示具体代码了。

在搜集了数据之后,我们一般会对数据进行划分,分为训练集和测试集,训练集是来训练模型,测试集是用来测试模型的可信程度。

当不同特征数据的数量级差距比较大时,我们可以对数据进行归一化,从而使得不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性。

而要标准化的具体原因,可看这一部分机器学习——回归_机器学习 回归-CSDN博客

下面这段代码是预处理的过程:

  1. 提取文件数据中的特征数据
  2. 对数据进行归一化处理
  3. 划分测试集与训练集
# 数据预处理
feature_cols = df.columns[:4]
target_col = df.columns[4]# 提取特征和目标变量
features = df[feature_cols].values
target = df[target_col].values.reshape(-1, 1)# 将特征和目标变量分别缩放到 0 到 1 之间
scaler_features = MinMaxScaler(feature_range=(0, 1))
scaler_target = MinMaxScaler(feature_range=(0, 1))scaled_features = scaler_features.fit_transform(features)
scaled_target = scaler_target.fit_transform(target)# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(scaled_features, scaled_target, test_size=0.2, random_state=42)

2、添加时间步长

时间步长用于确定模型在观察数据时每次考虑多少个时间点的信息,这里我们设置其为1,并将时间步长加入数据中。

# 定义时间步长
n_steps = 1# 为训练集和测试集添加时间步长
X_train = X_train.reshape((X_train.shape[0], n_steps, X_train.shape[1]))
X_test = X_test.reshape((X_test.shape[0], n_steps, X_test.shape[1]))

3、构建CNN-LSTM模型

这一步就是单纯地设置模型各个层次的参数了。

  1. 首先创建一个序列,用以之后向里面加入各层
  2. 然后加入一个卷积层,设置参数:卷积核数量为32,卷积核大小为3,padding方式为’same’,步长为1,激活函数为ReLU,并指定输入数据的形状
  3. 添加池化层,设置参数:一维最大池化层,池化窗口大小为1
  4. 添加一个LSTM层,设置参数:设置神经元数量为16,输出完整的序列
  5. 添加一个LSTM层,设置参数:设置神经元数量为8,只输出最后一个时间步的输出
  6. 添加一个全连接层,输出维度为1.
  7. 编译模型,使用均方误差作为损失函数,Adam优化器用于优化模型参数。
model = Sequential()
model.add(Conv1D(filters=32, kernel_size=3, padding='same', strides=1, activation='relu', input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(MaxPooling1D(pool_size=1))
model.add(LSTM(16, return_sequences=True))
model.add(LSTM(8, return_sequences=False))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')

 4、训练模型

这一步就是用我们上面处理好的数据投入模型,就可以进行训练,很简单,就不解释了

# 训练模型,并保存训练历史
history = model.fit(X_train, y_train, epochs=100, batch_size=4, shuffle=False, validation_data=(X_test, y_test))

至此,模型已经训练好了,下一步就需要先对模型进行检测,查看可信度。

5、模型检测

这里我们用多个检测,保证模型是准确的

5.1、rmse检测

这里我们用RMSE来作为检测指标

首先将训练集和测试集输入模型,得到预测结果。由于我们的模型对数据进行了归一化,因此还要对预测数据和原始数据进行反归一化操作之后,再来计算rmse的值。

# 预测
train_predict = model.predict(X_train)
test_predict = model.predict(X_test)# 反向缩放预测值
train_predict = scaler_target.inverse_transform(train_predict)
y_train = scaler_target.inverse_transform(y_train)
test_predict = scaler_target.inverse_transform(test_predict)
y_test = scaler_target.inverse_transform(y_test)# 计算RMSE
train_score = mean_squared_error(y_train, train_predict, squared=False)
print('Train Score: %.2f RMSE' % (train_score))
print(r2_score(y_train,train_predict) )
test_score = mean_squared_error(y_test, test_predict, squared=False)
print('Test Score: %.2f RMSE' % (test_score))
print(r2_score(y_test,test_predict))
# 绘制图像
plt.figure(1, figsize=(12, 6), dpi=80)
plt.plot(history.history['loss'], label='Train')
plt.plot(history.history['val_loss'], label='Validation')
plt.title('Loss Curve')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

此段代码还输出了rmse的loss图像,代表着训练过程中的损失值的变化。我们这里可以明显看出,损失值明显减小且接近0.

5.2预测数据与原始数据对比

这部分是将原始数据作为输入,得到图像,对比。

# 对特征数据进行缩放
scaled_feature_data = scaler_features.transform(features)# 将数据转换成模型期望的形状
scaled_feature_data = scaled_feature_data.reshape((scaled_feature_data.shape[0], n_steps, scaled_feature_data.shape[1]))# 使用模型进行预测
predicted_output = model.predict(scaled_feature_data)# 反向缩放预测值
predicted_output = scaler_target.inverse_transform(predicted_output)plt.figure(2, figsize=(12, 6), dpi=80)
plt.plot(df.index, target, color='k', label='真实值')  # 使用数据的索引作为横坐标
plt.plot(df.index, predicted_output, color='blue', label='预测值')  # 使用数据的索引作为横坐标
plt.xlabel('时间戳', fontsize=20)
plt.ylabel('碳排放量', fontsize=20)
plt.tick_params(labelsize=20)
plt.legend(fontsize=20)
plt.savefig("真实值和预测值对比.svg", dpi=80, format="svg")
plt.show()

5.3计算MAPE值

这部分就不解释了,单纯的实现了公式

# 计算MAPE
def mean_absolute_percentage_error(y_true, y_pred):y_true, y_pred = np.array(y_true), np.array(y_pred)return np.mean(np.abs((y_true - y_pred) / y_true)) * 100train_mape = mean_absolute_percentage_error(y_train, train_predict)
test_mape = mean_absolute_percentage_error(y_test, test_predict)print('Train MAPE: %.2f' % train_mape)
print('Test MAPE: %.2f' % test_mape)

 6、预测

这部分代码是用模型和输入数据,获得预测的输出数据。


prediction_data_path = r'C:\Users\Administrator\Desktop\统计建模\数据\数据集1\cnn-lstm预测得到的数据.xlsx'
prediction_df = pd.read_excel(prediction_data_path)# 提取特征
prediction_features = prediction_df.iloc[:, :4].values# 特征缩放
scaled_prediction_features = scaler_features.transform(prediction_features)# 重塑数据形状
scaled_prediction_features = scaled_prediction_features.reshape((scaled_prediction_features.shape[0], n_steps, scaled_prediction_features.shape[1]))# 进行预测
predictions = model.predict(scaled_prediction_features)# 反向缩放预测结果
unscaled_predictions = scaler_target.inverse_transform(predictions)# 假设你希望将结果保存到一个新的 Excel 文件中
output_path = r'C:\Users\Administrator\Desktop\统计建模\数据\数据集1\预测结果.xlsx'
prediction_df['预测结果'] = unscaled_predictions
prediction_df.to_excel(output_path, index=False)# 或者你也可以直接打印预测结果
print("预测结果:", unscaled_predictions)

三、总代码展示

import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense
from sklearn.model_selection import train_test_split
from keras.layers import Conv1D, MaxPooling1D
from sklearn.metrics import mean_absolute_error,mean_squared_error,r2_score
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import StandardScalerplt.rcParams['font.sans-serif']=[u'simHei']
plt.rcParams['axes.unicode_minus']=False# 读取数据
file_path = r'C:\Users\Administrator\Desktop\统计建模\数据\数据集1\用于sp模型的数据.xlsx'
df = pd.read_excel(file_path)#预测
path =r'C:\Users\Administrator\Desktop\统计建模\数据\数据集1\cnn-lstm预测得到的数据.xlsx'# 数据预处理
feature_cols = df.columns[:4]
target_col = df.columns[4]# 提取特征和目标变量
features = df[feature_cols].values
target = df[target_col].values.reshape(-1, 1)# 将特征和目标变量分别缩放到 0 到 1 之间
scaler_features = MinMaxScaler(feature_range=(0, 1))
scaler_target = MinMaxScaler(feature_range=(0, 1))scaled_features = scaler_features.fit_transform(features)
scaled_target = scaler_target.fit_transform(target)# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(scaled_features, scaled_target, test_size=0.2, random_state=42)# 定义时间步长
n_steps = 1# 为训练集和测试集添加时间步长
X_train = X_train.reshape((X_train.shape[0], n_steps, X_train.shape[1]))
X_test = X_test.reshape((X_test.shape[0], n_steps, X_test.shape[1]))# 搭建CNN-LSTM融合神经网络
model = Sequential()
model.add(Conv1D(filters=32, kernel_size=3, padding='same', strides=1, activation='relu', input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(MaxPooling1D(pool_size=1))
model.add(LSTM(16, return_sequences=True))
model.add(LSTM(8, return_sequences=False))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam')# 训练模型,并保存训练历史
history = model.fit(X_train, y_train, epochs=100, batch_size=4, shuffle=False, validation_data=(X_test, y_test))prediction_data_path = r'C:\Users\Administrator\Desktop\统计建模\数据\数据集1\cnn-lstm预测得到的数据.xlsx'
prediction_df = pd.read_excel(prediction_data_path)# 提取特征
prediction_features = prediction_df.iloc[:, :4].values# 特征缩放
scaled_prediction_features = scaler_features.transform(prediction_features)# 重塑数据形状
scaled_prediction_features = scaled_prediction_features.reshape((scaled_prediction_features.shape[0], n_steps, scaled_prediction_features.shape[1]))# 进行预测
predictions = model.predict(scaled_prediction_features)# 反向缩放预测结果
unscaled_predictions = scaler_target.inverse_transform(predictions)# 假设你希望将结果保存到一个新的 Excel 文件中
output_path = r'C:\Users\Administrator\Desktop\统计建模\数据\数据集1\预测结果.xlsx'
prediction_df['预测结果'] = unscaled_predictions
prediction_df.to_excel(output_path, index=False)# 或者你也可以直接打印预测结果
print("预测结果:", unscaled_predictions)# 预测
train_predict = model.predict(X_train)
test_predict = model.predict(X_test)# 反向缩放预测值
train_predict = scaler_target.inverse_transform(train_predict)
y_train = scaler_target.inverse_transform(y_train)
test_predict = scaler_target.inverse_transform(test_predict)
y_test = scaler_target.inverse_transform(y_test)# 计算RMSE
train_score = mean_squared_error(y_train, train_predict, squared=False)
print('Train Score: %.2f RMSE' % (train_score))
print(r2_score(y_train,train_predict) )
test_score = mean_squared_error(y_test, test_predict, squared=False)
print('Test Score: %.2f RMSE' % (test_score))
print(r2_score(y_test,test_predict))
# 绘制图像
plt.figure(1, figsize=(12, 6), dpi=80)
plt.plot(history.history['loss'], label='Train')
plt.plot(history.history['val_loss'], label='Validation')
plt.title('Loss Curve')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()# 对特征数据进行缩放
scaled_feature_data = scaler_features.transform(features)# 将数据转换成模型期望的形状
scaled_feature_data = scaled_feature_data.reshape((scaled_feature_data.shape[0], n_steps, scaled_feature_data.shape[1]))# 使用模型进行预测
predicted_output = model.predict(scaled_feature_data)# 反向缩放预测值
predicted_output = scaler_target.inverse_transform(predicted_output)plt.figure(2, figsize=(12, 6), dpi=80)
plt.plot(df.index, target, color='k', label='真实值')  # 使用数据的索引作为横坐标
plt.plot(df.index, predicted_output, color='blue', label='预测值')  # 使用数据的索引作为横坐标
plt.xlabel('时间戳', fontsize=20)
plt.ylabel('碳排放量', fontsize=20)
plt.tick_params(labelsize=20)
plt.legend(fontsize=20)
plt.savefig("真实值和预测值对比.svg", dpi=80, format="svg")
plt.show()# 计算MAPE
def mean_absolute_percentage_error(y_true, y_pred):y_true, y_pred = np.array(y_true), np.array(y_pred)return np.mean(np.abs((y_true - y_pred) / y_true)) * 100train_mape = mean_absolute_percentage_error(y_train, train_predict)
test_mape = mean_absolute_percentage_error(y_test, test_predict)print('Train MAPE: %.2f' % train_mape)
print('Test MAPE: %.2f' % test_mape)
# 绘制MAPE图像
plt.figure(figsize=(12, 6), dpi=80)
plt.plot(y_test, label='真实值')
plt.plot(test_predict, label='预测值')
plt.title('MAPE图像')
plt.xlabel('样本编号')
plt.ylabel('碳排放量')
plt.legend()
plt.show()

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

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

相关文章

网络设置 —— Http 响应头和请求头的设置

get请求可以使用GetAsync方法 Post请求 使用PostAsync, delete请求 使用DeleteAsync Put请求 使用PutAsync 请求的完整写法 HttpResponseMessage res await new HttpClient().SendAsync(reg); string data awai…

JAVA 中 HTTP 基本认证(Basic Authentication)

目录 服务端这么做服务端告知客户端使用 Basic Authentication 方式进行认证服务端接收并处理客户端按照 Basic Authentication 方式发送的数据 客户端这么做如果客户端是浏览器如果客户端是 RestTemplat如果客户端是 HttpClient 其它参考 服务端这么做 服务端告知客户端使用 …

AWS CloudWatch日志组中关于中文关键字的查询

问题 在AWS CloudWatch日志组中,想要查询出包含中文关键字的错误日志,结果,AWS说语法错误。 最开始,使用如下查询,查询可能的错误日志: 查询语句,如下: {($.log %ERROR%) }具体效…

CSS预处理器Sass详解

CSS预处理器Sass 1. 变量(Variables): 变量在Sass中以$开头,用于存储值,以便在多个地方重用。 $primary-color: #007BFF;body {color: $primary-color;}2. 嵌套规则(Nested Rules)&#xff1a…

C语言中字符串相关的函数解析

C语言中没有string类型,字符串通常放在常量字符串或字符数组中,下面来介绍一些常用的字符串相关的操作函数。 strlen strlen用来求一个字符串的长度,其函数原型如下: size_t strlen ( const char * str ); 使用strlen需要注意以…

ACL的几种类型

ACL(Access Control List,访问控制列表)主要有以下几种类型: 数字型ACL:这是传统的ACL标识方法,创建ACL时指定一个唯一的数字来标识该ACL。命名型ACL:通过名称代替编号来标识ACL,用…

实战Java虚拟机-高级篇

一、GraalVM 什么是GraalVM GraalVM是Oracle官方推出的一款高性能JDK,使用它享受比OpenJDK或者OracleJDK更好的性能。GraalVM的官方网址:https://www.graalvm.org/官方标语:Build faster, smaller, leaner applications。 更低的CPU、内存…

js实现鼠标拖拽多选功能

实现功能 在PC端的H5页面中&#xff0c;客户拖动鼠标可以连选多个选项 效果展示 具体代码如下 <!DOCTYPE html> <html><head><title>鼠标拖拽多选功能</title><script src"https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js&quo…

ClickHouse配置与使用

静态IP配置 # 修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33# 修改文件内容 TYPEEthernet PROXY_METHODnone BROWSER_ONLYno BOOTPROTOstatic IPADDR192.168.18.128 NETMASK255.255.255.0 GATEWAY192.168.18.2 DEFROUTEyes IPV4_FAILURE_FATALno IPV6INIT…

《深入解析:近邻算法的原理、实现与应用》

《深入解析&#xff1a;近邻算法的原理、实现与应用》 引言&#xff1a; 在机器学习和数据挖掘领域&#xff0c;近邻算法&#xff08;k-Nearest Neighbors, k-NN&#xff09;是一种基本且常用的分类与回归方法。其核心思想在于根据近邻的信息进行预测&#xff0c;即通过查询输…

Android 屏保开关

设置-显示-屏保&#xff0c; 打开关闭 设置代码在 ./packages/apps/Settings/src/com/android/settings/dream/DreamMainSwitchPreferenceController.java &#xff0c; Overridepublic boolean isChecked() {return mBackend.isEnabled();}Overridepublic boolean setChecke…

【408真题】2009-12

“接”是针对题目进行必要的分析&#xff0c;比较简略&#xff1b; “化”是对题目中所涉及到的知识点进行详细解释&#xff1b; “发”是对此题型的解题套路总结&#xff0c;并结合历年真题或者典型例题进行运用。 涉及到的知识全部来源于王道各科教材&#xff08;2025版&…

招人啦~数通售后、云计算和云服务的岗位需求

小伙伴们大家好&#xff0c;小誉的就业推荐又来咯。想要跳槽晋升找工作的朋友们&#xff0c;千万不要错过机会哦~ 北京集成商数通售后 薪资:12-18k 1、负责公司系统集成项目的网络技术实施工作&#xff0c;包括项目的网络架构的规划、设计、调整、性能优化; 2、负责从项目开展…

零基础HTML教程(35)--网站的本地部署

文章目录 1. 背景2. 网站的本地部署3. 本地部署的步骤4. 服务器软件介绍5. 本地部署实操5.1 开发一个网站5.2 下载服务器软件5.3 将网站复制到服务器软件下5.4 启动服务器软件5.5 通过Http协议访问网站 6. 小结 1. 背景 我们之前开发的网页&#xff0c;都是编写完成后&#xf…

Sass预处理器相关知识笔记

什么是Sass **Sass&#xff08;Syntactically Awesome Stylesheets&#xff09;**是一种CSS预处理器&#xff0c;它扩展了CSS的功能&#xff0c;使其更加强大和灵活。Sass允许开发者使用变量、嵌套规则、混合&#xff08;mixins&#xff09;、继承等特性&#xff0c;从而更高效…

Day22:Leetcode:654.最大二叉树 + 617.合并二叉树 + 700.二叉搜索树中的搜索 + 98.验证二叉搜索树

LeetCode&#xff1a;654.最大二叉树 1.思路 解决方案&#xff1a; 单调栈是本题的最优解&#xff0c;这里将单调栈题解本题的一个小视频放在这里 单调栈求解最大二叉树的过程当然这里还有leetcode大佬给的解释&#xff0c;大家可以参考一下&#xff1a; 思路很清晰&#xf…

云渲染的线程数是什么意思?

云渲染线程是指在云渲染过程中&#xff0c;同时处理渲染任务的线程数量。 线程是CPU调度和执行的基本单位&#xff0c;每个线程可以独立执行一系列指令。在云渲染场景中&#xff0c;服务器通常配备有高性能的CPU&#xff0c;这些CPU可能拥有几十甚至上百个物理核心&#xff0c…

python多个list组成的list去重 考虑顺序

在Python中&#xff0c;如果你有多个列表组成的列表&#xff0c;并且你想要去除其中的重复元素&#xff0c;同时考虑顺序&#xff0c;你可以使用functools.total_ordering装饰器来简化代码&#xff0c;并使用set来去重。 下面是一个示例代码&#xff1a; from functools impo…

Vue2基础及其进阶面试(一)

简单版项目初始化 新建一个vue2 官网文档&#xff1a;介绍 — Vue.js 先确保下载了vue的脚手架 npm install -g vue-cli npm install -g vue/cli --force vue -V 创建项目 vue create 自己起个名字 选择自己选择特性 选择&#xff1a; Babel&#xff1a;他可以将我们写…

单向无头链表实现

目录 1. 为什么要有链表&#xff1f; 2. 链表的种类 3. 具体功能实现 &#xff08;1&#xff09;节点结构体定义 &#xff08;2&#xff09;申请节点 &#xff08;3&#xff09;尾插 &#xff08;4&#xff09;尾删 &#xff08;5&#xff09;头插 &#xff08;6&#…