时间序列预测 — CNN-LSTM实现多变量多步光伏预测(Tensorflow)

目录

1 数据处理

1.1 导入库文件

1.2 导入数据集

1.3 缺失值分析

2 构造训练数据

​3 模型训练

3.1 CNN-LSTM网络 

3.2 模型训练

4 模型预测


 专栏链接:https://blog.csdn.net/qq_41921826/category_12495091.html

1 数据处理

1.1 导入库文件

import scipy
import pandas as pd
import numpy as np
import math
import datetime
from matplotlib import pyplot as plt# 导入深度学习框架tensorflow
import tensorflow as tf    
from tensorflow import keras 
from tensorflow.keras import Sequential, layers, callbacks
from tensorflow.keras.layers import Input, Reshape,Conv2D, MaxPooling2D, LSTM, Dense, Dropout, Flatten, Reshapefrom sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error, mean_absolute_percentage_error # 忽略警告信息
import warnings
warnings.filterwarnings('ignore')  
plt.rcParams['font.sans-serif'] = ['SimHei']     # 显示中文
plt.rcParams['axes.unicode_minus'] = False  # 显示负号
plt.rcParams.update({'font.size':18})  #统一字体字号

1.2 导入数据集

实验数据集采用数据集6:澳大利亚电力负荷与价格预测数据(下载链接),数据集包括包括数据集包括日期、小时、干球温度、露点温度、湿球温度、湿度、电价、电力负荷特征,时间间隔30min。选取两年的数据进行实验,对数据进行可视化:

# 导入数据
data_raw = pd.read_excel("E:\\课题\\08数据集\\澳大利亚电力负荷与价格预测数据\\澳大利亚电力负荷与价格预测数据.xlsx")
data_raw = data_raw[-365*24*2*2-1:-1]
data_raw
from itertools import cycle
# 可视化数据
def visualize_data(data, row, col):cycol = cycle('bgrcmk')cols = list(data.columns)fig, axes = plt.subplots(row, col, figsize=(16, 4))fig.tight_layout()if row == 1 and col == 1:  # 处理只有1行1列的情况axes = [axes]  # 转换为列表,方便统一处理for i, ax in enumerate(axes.flat):if i < len(cols):ax.plot(data.iloc[:,i], c=next(cycol))ax.set_title(cols[i])else:ax.axis('off')  # 如果数据列数小于子图数量,关闭多余的子图plt.subplots_adjust(hspace=0.6)plt.show()visualize_data(data_raw.iloc[:,2:], 2, 3)

​​

​单独查看部分功率数据,发现有较强的规律性。

​​

1.3 缺失值分析

首先查看数据的信息,发现并没有缺失值

data_raw.info()

​​进一步统计缺失值,通过统计数据可以看到,数据比较完整,不存在缺失值。其他异常值和数据处理可以自行处理。

data_raw.isnull().sum()

2 构造训练数据

选取数据集,去掉时间特征

data = data_raw.iloc[:,2:].values

构造训练数据,也是真正预测未来的关键。首先设置预测的timesteps时间步、predict_steps预测的步长(预测的步长应该比总的预测步长小),length总的预测步长,参数可以根据需要更改。

timesteps = 48*7 #构造x,为96*5个数据,表示每次用前96*5个数据作为一段
predict_steps = 48 #构造y,为96个数据,表示用后96个数据作为一段
length = 48 #预测多步,预测96个数据
feature_num = 5 #特征的数量

通过前5天的timesteps个数据预测后一天的predict_steps个数据,需要对数据集进行滚动划分(也就是前timesteps行的特征和后predict_steps行的标签训练,后面预测时就可通过timesteps行特征预测未来的predict_steps个标签)。因为是多变量,特征和标签分开划分。

# 构造数据集,用于真正预测未来数据
# 整体的思路也就是,前面通过前timesteps个数据训练后面的predict_steps个未来数据
# 预测时取出前timesteps个数据预测未来的predict_steps个未来数据。
# 单变量划分只需对单个变量划分,多变量划分特征和标签分开划分
def create_dataset(datasetx, datasety=None, timesteps=36, predict_size=6):datax = []  # 构造xdatay = []  # 构造yfor each in range(len(datasetx) - timesteps - predict_size):x = datasetx[each:each + timesteps]# 判断是否是单变量分解还是多变量分解if datasety is not None:y = datasety[each + timesteps:each + timesteps + predict_size]else:y = datasetx[each + timesteps:each + timesteps + predict_size, 0]datax.append(x)datay.append(y)return datax, datay

​​数据处理前,需要对数据进行归一化,按照上面的方法划分数据,这里返回划分的数据和归一化模型,因为是多变量,特征和标签分开归一化,不然后面归一化会有信息泄露的问题。函数的定义如下:

# 数据归一化操作
def data_scaler(datax, datay=None, timesteps=36, predict_steps=6):# 数据归一化操作scaler1 = MinMaxScaler(feature_range=(0, 1))   datax = scaler1.fit_transform(datax)# 用前面的数据进行训练,留最后的数据进行预测# 判断是否是单变量分解还是多变量分解if datay is not None:scaler2 = MinMaxScaler(feature_range=(0, 1))datay = scaler2.fit_transform(datay)trainx, trainy = create_dataset(datax, datay, timesteps, predict_steps)trainx = np.array(trainx)trainy = np.array(trainy)return trainx, trainy, scaler1, scaler2else:trainx, trainy = create_dataset(datax, timesteps=timesteps, predict_size=predict_steps)trainx = np.array(trainx)trainy = np.array(trainy)return trainx, trainy, scaler1, None

然后对数据按照上面的函数进行划分和归一化。通过前5天的96*5数据预测后一天的96个数据,需要对数据集进行滚动划分(也就是前96*5行的特征和后96行的标签训练,后面预测时就可通过96*5行特征预测未来的96个标签)

datax = data[:,:-1]
datay = data[:,-1].reshape(data.shape[0],1)
trainx, trainy, scaler1, scaler2 = data_scaler(datax, datay)

​3 模型训练

3.1 CNN-LSTM网络 

CNN-LSTM 是一种结合了 CNN 特征提取能力与 LSTM 对时间序列长期记忆能力的混合神经网络。

CNN 主要由四个层级组成, 分别为输入层、 卷积层、 激活层(Relu 函数)和池化层。 每一层都会将数据处理之后送到下一层, 其中最重要的是卷积层, 这个层级起到的作用是将特征数据进行卷积计算, 将计算好的结果传到激活层, 激活函数对数据进行筛选。最后一层是 LSTM 层, 这一层是根据 CNN 处理后的特征数据,对其模型进行进一步的维度修偏, 权重修正等工作, 为下一步输出精度较高的预测值做好准备, 在 LSTM 训练的过程中, 由于其神经网络内部包括了输入、 遗忘和输出门, 通常的做法是通过增减遗忘门和输入门的个数, 来控制算法的精度。
 

来源:基于改进的 CNN-LSTM 短期风功率预测方法研究

对于输入到 CNN-LSTM 的数据,首先,经过 CNN 的卷积层对局部特征进行提取,将提取后的特征向量传递到池化层进行特征向量的下采样和数据体量的压缩。然后,将经过卷积层和池化层处理后的特征向量经过一个扁平层转化成一维向量输入到 LSTM 中, 每一层 LSTM 后加一个随机失活层以防止模型过拟合。
 

3.2 模型训练

首先搭建模型的常规操作,然后使用训练数据trainx和trainy进行训练,进行50个epochs的训练,每个batch包含64个样本。此时input_shape划分数据集时每个x的形状。(建议使用GPU进行训练,因为本人电脑性能有限,建议增加epochs值)

# CNN_LSTM模型
def CNN_LSTM_model_train(trainx, trainy, timesteps, feature_num, predict_steps):# 调用GPU加速gpus = tf.config.experimental.list_physical_devices(device_type='GPU')for gpu in gpus:tf.config.experimental.set_memory_growth(gpu, True)# 定义CNN-LSTM模型start_time = datetime.datetime.now()model = Sequential()model.add(Input((timesteps, feature_num)))model.add(Reshape((timesteps, feature_num, 1)))model.add(Conv2D(filters=64,kernel_size=3,strides=1,padding="same",activation="relu"))model.add(MaxPooling2D(pool_size=2, strides=1, padding="same"))model.add(Dropout(0.3))model.add(Reshape((timesteps, -1)))model.add(LSTM(128, return_sequences=True, dropout=0.2))  # 添加dropout层model.add(LSTM(64, return_sequences=False, dropout=0.2))  # 添加dropout层model.add(Dense(64, activation="relu"))  # 增加Dense层节点数量model.add(Dense(predict_steps))model.compile(loss="mean_squared_error", optimizer="adam", metrics=['mse'])model.summary()# 模型训练model.fit(trainx, trainy, epochs=50, batch_size=128)end_time = datetime.datetime.now()running_time = end_time - start_time# 保存模型model.save('CNN_LSTM_model.h5')# 返回构建好的模型return model

对划分的数据进行训练 

model = CNN_LSTM_model_train(trainx, trainy, timesteps, feature_num, predict_steps)

4 模型预测

首先加载训练好后的模型

# 加载模型
from tensorflow.keras.models import load_model
model = load_model('BiLSTM_model.h5')

准备好需要预测的数据,训练时保留了6天的数据,将前5天的数据作为输入预测,将预测的结果和最后一天的真实值进行比较。

y_true = datay[-timesteps-predict_steps:-timesteps]
x_pred = datax[-timesteps:]

预测并计算误差,并进行可视化,将这些步骤封装为函数。​​​​​​​

# 预测并计算误差和可视化
def predict_and_plot(x, y_true, model, scaler, timesteps):# 变换输入x格式,适应LSTM模型predict_x = np.reshape(x, (1, timesteps, feature_num))  # 预测predict_y = model.predict(predict_x)predict_y = scaler.inverse_transform(predict_y)y_predict = []y_predict.extend(predict_y[0])# 计算误差r2 = r2_score(y_true, y_predict)rmse = mean_squared_error(y_true, y_predict, squared=False)mae = mean_absolute_error(y_true, y_predict)mape = mean_absolute_percentage_error(y_true, y_predict)print("r2: %.2f\nrmse: %.2f\nmae: %.2f\nmape: %.2f" % (r2, rmse, mae, mape))# 预测结果可视化cycol = cycle('bgrcmk')plt.figure(dpi=100, figsize=(14, 5))plt.plot(y_true, c=next(cycol), markevery=5)plt.plot(y_predict, c=next(cycol), markevery=5)plt.legend(['y_true', 'y_predict'])plt.xlabel('时间')plt.ylabel('功率(kW)')plt.show()return y_predict
y_predict = predict_and_plot(x_pred, y_true, model, scaler2, timesteps)

最后得到可视化结果和计算的误差,可以通过调参和数据处理进一步提升模型预测效果。

  • r2: 0.19
  • ​​rmse: 725.34
  • mae: 640.73
  • mape: 0.08

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

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

相关文章

『番外篇二』Swift “黑魔法”之动态获取类实例隐藏属性的值

概览 在 Swift 代码的调试中,我们时常惊叹调试器的无所不能:对于大部分“黑盒”类实例的内容,调试器也都能探查的一清二楚。 想要自己在运行时也能轻松找到 Thread 实例“私有”属性的值吗(比如 seqNum)? 在本篇博文中您将学到如下内容: 概览1. 借我,借我,一双慧眼吧…

深入理解LightGBM

1. LightGBM简介 GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛&#…

IT 人员与加密程序:如何战胜病毒

&#x1f510; 加密程序是攻击者在成功攻击组织时使用最多的恶意软件类型。它们通常会发送到一个庞大的电子邮件地址数据库&#xff0c;看起来像 Word 或 Excel 文档或 PDF 文件。 想象一下&#xff0c;你是会计部门的一名员工。这种格式的文件在电子文档管理系统中被广泛使用…

如何查看Linux中glibc的Version

用ldd --version ldd --version 运行libc.so 你没有看错&#xff0c;libc.so是一个可执行程序。 但前提是你要找到它。因为它并不在PATH所包含的目录下。 ppdell:~$ ldd which cat | grep libclibc.so.6 > /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0e6fb34000)ppdell:~…

dcoker-compose一键部署EFAK —— 筑梦之路

简介 EFAK&#xff08;Eagle For Apache Kafka&#xff0c;以前称为 Kafka Eagle&#xff09;是一款由国内公司开源的Kafka集群监控系统&#xff0c;可以用来监视kafka集群的broker状态、Topic信息、IO、内存、consumer线程、偏移量等信息&#xff0c;并进行可视化图表展示。独…

跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发)

本文为转载 原文链接&#xff1a; 采用Qt快速绘制多条曲线&#xff08;折线&#xff09;&#xff0c;跟随鼠标动态显示线上点的值&#xff08;基于Qt的开源绘图控件QCustomPlot进行二次开发&#xff09; 内容如下 QCustomPlot是一个开源的基于Qt的第三方绘图库&#xff0c;能…

干货 | 一文搞定 pytest 自动化测试框架(一)

简介 pytest 是一个成熟的全功能 Python 测试工具&#xff0c;可以帮助您编写更好的程序。它与 Python 自带的 Unittest 测试框架类似&#xff0c;但 pytest 使用起来更简洁和高效&#xff0c;并且兼容 unittest 框架。pytest 有以下实用特性&#xff1a; pytest 能够支持简单…

Spring容器中scope为prototype类型Bean的回收机制

文章目录 一、背景二、AutowireCapableBeanFactory 方法 autowireBean 分析三、Spring 容器中 scope 为 prototype 类型 Bean 的回收机制四、总结 一、背景 最近做 DDD 实践时&#xff0c;遇到业务对象需要交给 Spring 管理才能做一些职责内事情。假设账号注册邮箱应用层代码流…

DDD落地:爱奇艺打赏服务,如何DDD架构?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 谈谈你的DDD落地经验&#xff1f; 谈谈你对DDD的理解&#x…

【Kubernetes】存储类StorageClass

存储类StorageClass 一、StorageClass介绍二、安装nfs provisioner&#xff0c;用于配合存储类动态生成pv2.1、创建运行nfs-provisioner需要的sa账号2.2、对sa授权2.3、安装nfs-provisioner程序 三、创建storageclass&#xff0c;动态供给pv四、创建pvc&#xff0c;通过storage…

二百一十五、Flume——Flume拓扑结构之复制和多路复用的开发案例(亲测,附截图)

一、目的 对于Flume的复制和多路复用拓扑结构&#xff0c;进行一个小的开发测试 二、复制和多路复用拓扑结构 &#xff08;一&#xff09;结构含义 Flume 支持将事件流向一个或者多个目的地。 &#xff08;二&#xff09;结构特征 这种模式可以将相同数据复制到多个channe…

开辟“护眼绿洲”,荣耀何以为师?

文 | 智能相对论 作者 | 佘凯文 俗话说&#xff0c;眼睛是心灵的窗户&#xff0c;可如今&#xff0c;人们对于这扇“窗户”的保护&#xff0c;似乎越来越不重视。 据人民日报今年发布的调查显示&#xff0c;中国眼病患病人数2.1亿&#xff0c;近视患者人数多达6亿&#xff0…

多功能神器,强劲升级,太极2.x你值得拥有!

嗨&#xff0c;大家好&#xff0c;今天给大家分享一个好用好玩的软件。那就是太极2.x软件&#xff0c;最近在1.0版本上进行了全新升级&#xff0c;升级后的功能更强更稳定&#xff0c;轻度用户使用基本功能就已经足够了&#xff0c;我们一起来看看吧&#xff01; 首页 首页左…

input、el-input输入框输入规则

一、input 只能输入框只能输入正整数&#xff0c;输入同时禁止了以0开始的数字输入&#xff0c;防止被转化为其他进制的数值。 <!-- 不能输入零时--> <input typetext οninput"valuevalue.replace(/^(0)|[^\d]/g,)"><!-- 能输入零时--> <inp…

【SpringBoot】之Mybatis=Plus集成及使用(入门级)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringBoot开发之Mybatis-Plus系列》。&#x1…

WPF仿网易云搭建笔记(2):组件化开发

文章目录 前言专栏和Gitee仓库依赖属性实战&#xff1a;缩小&#xff0c;全屏&#xff0c;关闭按钮依赖属性操作封装主窗口传递this本身给TitleView标题控件主要代码MainWindow.xmalMainWindow.cs依赖属性方法封装TitleView.csTitleViewModelTitleViewModel实现效果 前言 这次…

有什么好用的资产设备管理系统?工单管理系统在设备管理上有什么作用?

设备管理对于企业而言是非常重要的&#xff0c;像互联网企业、医院、化工企业、制造企业等&#xff0c;都需要用到贵重设备或者仪器。这些设备仪器不仅本身造价成本高&#xff0c;还和生产活动息息相关&#xff0c;所以必须做好日常的维护管理才能确保企业生产活动正常进行。而…

计算机网络:物理层(三种数据交换方式)

今天又学到一个知识&#xff0c;加油&#xff01; 目录 前言 一、电路交换 二、报文交换 三、分组交换 1、数据报方式 2、虚电路方式 3、比较 总结 前言 为什么要进行数据交换&#xff1f; 一、电路交换 电路交换原理&#xff1a;在数据传输期间&#xff0c;源结点与…

新手HTML和CSS的常见知识点

​​​​ 目录 1.HTML标题标签&#xff08;到&#xff09;用于定义网页中的标题&#xff0c;并按照重要性递减排列。例如&#xff1a; 2.HTML段落标签&#xff08;&#xff09;用于定义网页中的段落。例如&#xff1a; 3.HTML链接标签&#xff08;&#xff09;用于创建链接…

【网络编程之初出茅庐】

前言&#xff1a;本章主要先讲解一些基本的网络知识&#xff0c;先把基本的知识用起来&#xff0c;后续会更深入的讲解底层原理。 网络编程的概念 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数…