时间序列预测 — VMD-LSTM实现单变量多步光伏预测(Tensorflow):单变量转为多变量预测多变量

目录

1 数据处理

1.1 导入库文件

1.2 导入数据集

​1.3 缺失值分析

2 VMD经验模态分解

2.1 VMD分解实验

2.2 VMD-LSTM预测思路

3 构造训练数据

4 LSTM模型训练

5 LSTM模型预测

5.1 分量预测

5.2 可视化


时间序列预测专栏链接:https://blog.csdn.net/qq_41921826/category_12495091.html

1 数据处理

1.1 导入库文件

import time
import datetime
import pandas as pd 
import numpy as np 
import matplotlib.pyplot as plt  
from sampen import sampen2  # sampen库用于计算样本熵
from vmdpy import VMD  # VMD分解库
from itertools import cycleimport tensorflow as tf 
from sklearn.cluster import KMeans
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error, mean_absolute_percentage_error 
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Dropout, LSTM, GRU, Reshape, BatchNormalization
from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint
from tensorflow.keras.optimizers import Adam# 忽略警告信息
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 导入数据集

实验数据集采用数据集8:新疆光伏风电数据集(下载链接),数据集包括组件温度(℃) 、温度(°)    气压(hPa)、湿度(%)、总辐射(W/m2)、直射辐射(W/m2)、散射辐射(W/m2)、实际发电功率(mw)特征,时间间隔15min。对数据进行可视化:

# 导入数据
data_raw = pd.read_excel("E:\\课题\\08数据集\\新疆风电光伏数据\\光伏2019.xlsx")
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[:,1:], 2, 4)

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

​1.3 缺失值分析

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

data_raw.info()

​ 进一步统计缺失值

data_raw.isnull().sum()

2 VMD经验模态分解

2.1 VMD分解实验

使用VMD将目标信号分解成若干个模态,进一步可视化分解结果

# VMD分解函数
# signal: 输入信号
# alpha: 正则化参数
# tau: 时间尺度参数
# K: 分量数量
# DC: 是否包括直流分量
# init: 初始化方法
# tol: 收敛容限
# n_ite: 最大迭代次数
def vmd_decompose(series=None, alpha=2000, tau=0, K=6, DC=0, init=1, tol=1e-7, draw=True): # 得到 VMD 分解后的各个分量、分解后的信号和频率imfs_vmd, imfs_hat, omega = VMD(series, alpha, tau, K, DC, init, tol)  # 将 VMD 分解分量转换为 DataFrame, 并重命名df_vmd = pd.DataFrame(imfs_vmd.T)df_vmd.columns = ['imf'+str(i) for i in range(K)]return df_vmd

因为只是单变量预测,只选取实际发电功率(mw)数据进行实验 

df_vmd = vmd_decompose(data_raw['实际发电功率(mw)'])  # 对 df_raw_data['AQI'] 进行 VMD 分解,并将结果赋值给 df_vmd
# 绘制 df_vmd 的数据,以子图形式显示每个分量
ax = df_vmd.plot(title='VMD Decomposition', figsize=(16,8), subplots=True,fontsize=16)
for a in ax:a.legend(loc='upper right',prop={'size': 14})plt.subplots_adjust(hspace=0.5)

​查看分解后的数据:

df_vmd

​这里我们验证一下分解效果,通过分解变量求和和实际功率值进行可视化比较,发现基本相同。

# 验证分解效果
plt.figure(dpi=100,figsize=(14,5))
plt.plot(df_vmd.iloc[:96*10,:-1].sum(axis=1))
plt.plot(data_raw['实际发电功率(mw)'][:96*10])
plt.legend(['VMD分解求和','原始负荷']) 
# 坐标描述
plt.xlabel('时间')
plt.ylabel('功率(kW)')

2.2 VMD-LSTM预测思路

这里利用VMD-LSTM进行预测的思路是通过VMD将原始功率分解为多个变量,然后将每个分解变量都进行预测,接着将预测的结果添加到历史数据中进行滚动预测,得到需要预测的步数,最后将每个分解变量的预测结果相加得到最终的预测结果。

3 构造训练数据

构造数据前先将数据变为数值类型

df_vmd = df_vmd.values

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

timesteps = 96*7 #构造x,为72个数据,表示每次用前72个数据作为一段
predict_steps = 12 #构造y,为12个数据,表示用后12个数据作为一段
length = 96 #预测多步,预测96个数据,每次预测96个,想想要怎么构造预测才能满足96?
feature_num = 7 #特征个数?

通过前timesteps个数据预测后面predict_steps个数据,需要对数据集进行滚动划分(也就是前timesteps行的数据和后predict_steps行的数据训练,后面预测时就可通过timesteps行数据预测未来的predict_steps行数据)。这里需要注意的是,因为是多变量预测多变量,特征就是标签(例如,前5行[imf_0, imf_1, imf_2, imf_3, imf_4, imf_5]预测第6行[imf_0, imf_1, imf_2, imf_3, imf_4, imf_5],划分数据集时,就用前5行当做train_x,第6行作为train_y,此时的train_y有多列,而不是只有1列)。

# 构造数据集,用于真正预测未来数据
# 整体的思路也就是,前面通过前timesteps个数据训练后面的predict_steps个未来数据
# 预测时取出前timesteps个数据预测未来的predict_steps个未来数据。
def create_dataset(datasetx, datasety=None, timesteps=96*7, predict_size=12):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]datax.append(x)datay.append(y)return datax, datay

​数据处理前,需要对数据进行归一化,按照上面的方法划分数据,这里返回划分的数据和归一化模型(变量和多变量的归一化不同,多变量归一化需要将X和Y分开归一化,不然会出现信息泄露的问题),此时的归一化相当于是单变量归一化,函数的定义如下:

# 数据归一化操作
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

然后分解的数据进行划分和归一化。通过前7天的96*7行数据预测后一天的96个数据,需要对数据集进行滚动划分(也就是前96*7行的数据和后12行的数据训练,后面预测时就可通过96*7行数据测未来的12行数据,然后将12行预测值添加到历史数据中,历史数据变为96*7+12个,再取出后96*7行数据进行预测,得到12行预测值,滚动进行预测直到预测完成,注意此时的预测值是行而不是个)

trainx, trainy, scalerx, scalery = data_scaler(df_vmd, timesteps=timesteps, predict_steps=predict_steps)

4 LSTM模型训练

首先划分训练集、测试集、验证数据:

train_x = trainx[:int(trainx.shape[0] * 0.8)]
train_y = trainy[:int(trainy.shape[0] * 0.8)]
test_x = trainx[int(trainx.shape[0] * 0.8):]
test_y = trainy[int(trainy.shape[0] * 0.8):]
test_x.shape, test_y.shape, train_x.shape, train_y.shape

首先搭建模型的常规操作,然后使用训练数据trainx和trainy进行训练,进行50个epochs的训练,每个batch包含64个样本(建议使用GPU进行训练)。

# 搭建LSTM训练函数
def LSTM_model_train(trainx, trainy, valx, valy, timesteps, 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)# 搭建LSTM模型start_time = datetime.datetime.now()model = Sequential()model.add(LSTM(128, input_shape=(timesteps, trainx.shape[2]), return_sequences=True))model.add(BatchNormalization())  # 添加BatchNormalization层model.add(Dropout(0.2))model.add(LSTM(64, return_sequences=False))model.add(Dense(predict_steps * trainy.shape[2]))model.add(Reshape((predict_steps, trainy.shape[2])))# 使用自定义的Adam优化器opt = Adam(learning_rate=0.001)model.compile(loss="mean_squared_error", optimizer=opt)# 添加早停和模型保存的回调函数es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=10)mc = ModelCheckpoint('best_model.h5', monitor='val_loss', mode='min', save_best_only=True)# 训练模型,这里我假设你有一个验证集(valx, valy)history = model.fit(trainx, trainy, validation_data=(valx, valy), epochs=50, batch_size=64, callbacks=[es, mc])# 记录训练损失loss_history = history.history['loss']end_time = datetime.datetime.now()running_time = end_time - start_timereturn model, loss_history, running_time

然后进行训练,将训练的模型、损失和训练时间保存。

#模型训练
model, loss_history, running_time = LSTM_model_train(train_x, train_y, test_x, test_y, timesteps, predict_steps)
# 将模型保存为文件
model.save('emd_lstm_model.h5')

5 LSTM模型预测

5.1 分量预测

下面介绍文章中最重要,也是真正没有未来特征的情况下预测未来标签的方法。整体的思路也就是取出预测前96*6行数据预测未来的12行数据,然后见12行数据添加进历史数据,再预测12行数据,滚动预测。因为每次只能预测12行数据,但是我要预测96个数据,所以采用的就是循环预测的思路。每次预测的12行数据,添加到数据集中充当预测x,然后在预测新的12行y,再添加到预测x列表中,如此往复,最终预测出96行。(注意多变量预测多变量预测的是多列,预测单变量只有一列)

# #滚动predict
# #因为每次只能预测12个数据,但是我要预测96个数据,所以采用的就是循环预测的思路。
# #每次预测的12个数据,添加到数据集中充当预测x,然后在预测新的12个y,再添加到预测x列表中,如此往复,最终预测出96个点。
def predict_using_LSTM(model, data, timesteps, predict_steps, feature_num, length, scaler):predict_xlist = np.array(data).reshape(1, timesteps, feature_num) predict_y = np.array([]).reshape(0, feature_num)  # 初始化为空的二维数组print('predict_xlist', predict_xlist.shape)while len(predict_y) < length:# 从最新的predict_xlist取出timesteps个数据,预测新的predict_steps个数据predictx = predict_xlist[:,-timesteps:,:]# 变换格式,适应LSTM模型predictx = np.reshape(predictx, (1, timesteps, feature_num)) print('predictx.shape', predictx.shape)# 预测新值lstm_predict = model.predict(predictx)print('lstm_predict.shape', lstm_predict.shape)# 滚动预测# 将新预测出来的predict_steps个数据,加入predict_xlist列表,用于下次预测print('predict_xlist.shape', predict_xlist.shape)predict_xlist = np.concatenate((predict_xlist, lstm_predict), axis=1)print('predict_xlist.shape', predict_xlist.shape)# 预测的结果y,每次预测的12个数据,添加进去,直到预测length个为止lstm_predict = scaler.inverse_transform(lstm_predict.reshape(predict_steps, feature_num))predict_y = np.concatenate((predict_y, lstm_predict), axis=0)print('predict_y', predict_y.shape)return predict_y

然后对数据进行预测,得到预测结果。

from tensorflow.keras.models import load_model
model = load_model('emd_lstm_model.h5')
pre_x = scalerx.fit_transform(df_vmd[-96*8:-96])
y_predict = predict_using_LSTM(model, pre_x, timesteps, predict_steps, feature_num, length, scalerx)

5.2 可视化

对预测的各分解变量和总的预测结果进行可视化。

#分量预测结果
for i in range(y_predict.shape[1]):fig, ax = plt.subplots(dpi=100, figsize=(14, 5))ax.plot(df_vmd[-96:, -i], markevery=5, label='IMF'+str(i)+'_true')ax.plot(y_predict[:, -i], markevery=5, label='IMF'+str(i)+'_predict')ax.set_xlabel('时间')ax.set_ylabel('预测值')ax.legend(loc = 'upper right')plt.show()
# 总预测结果
plt.figure(dpi=100, figsize=(14, 5))
plt.plot(np.sum(y_predict[:, :-1], axis=1), markevery=5, label = 'all_predict')
plt.plot(df_vmd[-96:,-1], markevery=5, label = 'all_true')
plt.legend(loc = 'upper right')

最后对预测结果计算误差。

# 预测并计算误差和可视化
def error_and_plot(y_true,y_predict):# 计算误差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 0
error_and_plot(df_vmd[-96:,-1], np.sum(y_predict[:, :-1], axis=1) )

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

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

相关文章

libexif库介绍

libexif是一个用于解析、编辑和保存EXIF数据的库。它支持EXIF 2.1标准(以及2.2中的大多数)中描述的所有EXIF标签。它是用纯C语言编写的&#xff0c;不需要任何额外的库。源码地址&#xff1a;https://github.com/libexif/libexif &#xff0c;最新发布版本为0.6.24&#xff0c;…

【v8漏洞利用模板】starCTF2019 -- OOB

文章目录 前言参考题目环境配置漏洞分析 前言 一道入门级别的 v8 题目&#xff0c;不涉及太多的 v8 知识&#xff0c;很适合入门&#xff0c;对于这个题目&#xff0c;网上已经有很多分析文章&#xff0c;笔者不再为大家制造垃圾&#xff0c;仅仅记录一个模板&#xff0c;方便…

TYPE-C接口取电芯片介绍和应用场景

随着科技的发展&#xff0c;USB PDTYPE-C已经成为越来越多设备的充电接口。而在这一领域中&#xff0c;LDR6328Q PD取电芯片作为设备端协议IC芯片&#xff0c;扮演着至关重要的角色。本文将详细介绍LDR6328Q PD取电芯片的工作原理、应用场景以及选型要点。 一、工作原理 LDR63…

2024年天津体育学院专升本专业考试体育教育专业素质测试说明

天津体育学院2024年高职升本科招生专业考试体育教育专业素质测试说明 一、测试内容 100米跑、立定跳远、原地推铅球 二、考试规则 1.100米跑可穿跑鞋&#xff08;短钉&#xff09;&#xff0c;起跑采用蹲踞式。抢跑个人累计犯规两次&#xff0c;取消本项考试资格&#xff0c…

解决使用localhost或127.0.01模拟CORS失效

解决使用localhost或127.0.01模拟CORS失效 前言问题发现问题解决 前言 CORS (Cross-Origin Resource Sharing) 指的是一种机制&#xff0c;它允许不同源的网页请求访问另一个源服务器上的某些资源。通常情况下&#xff0c;如果 JavaScript 代码在一个源中发起了 AJAX 请求&…

css的一些属性

我们在写项目的时候&#xff0c;会遇到多种多样的样式&#xff0c;大部分都是由css来实现的&#xff0c;css可以让我们的页面更美观&#xff0c;css通常是配合HTML使用&#xff0c;代码较为简单! 下面我就给大家举几个较为常用的一些css属性。 1.CSS中怎样让元素圆角化&#…

spring boot 2升级为spring boot 3中数据库连接池druid的问题

目录 ConfigurationClassPostProcessor ConfigurationClassBeanDefinitionReader MybatisPlusAutoConfiguration ConditionEvaluator OnBeanCondition 总结 近期给了一个任务&#xff0c;要求是对现有的 spring boot 2.x 项目进行升级&#xff0c;由于 spring boot 2.x 版…

数据结构和算法-交换排序中的快速排序(演示过程 算法实现 算法效率 稳定性)

文章目录 总览快速排序&#xff08;超级重要&#xff09;啥是快速排序演示过程算法实现第一次quicksort函数第一次partion函数到第一次quicksort的第一个quicksort到第二次quicksort的第一个quicksort到第二次quicksort的第二个quicksort到第一次quicksort的第二个quicksort到第…

while猜数字实例——C++版

案例描述&#xff1a;系统随机生成一个1到100之间的数字&#xff0c;玩家进行猜测&#xff0c;如果猜错&#xff0c;提示玩家数字过大或过小&#xff0c;如果猜对恭喜玩家胜利并退出游戏。 逻辑框图&#xff1a; #include<bits/stdc.h> using namespace std; int main()…

The Planets: Mercury

靶场环境 整个靶场的环境&#xff0c;我出现了一点点问题&#xff0c;一直找不到主机的IP地址&#xff0c;后来参考了https://www.cnblogs.com/hyphon/p/16354436.html&#xff0c;进行了相关的配置&#xff0c;最后完成靶机环境的搭建&#xff01; 信息收集 # nmap -sn 192…

Linux Debian12系统gnome桌面环境默认提供截屏截图工具gnome-screenshot

一、简介&#xff1a; 在Debian12中系统gnome桌面环境默认提供一个截图捕获工具screenshot,可以自定义区域截图、屏幕截图、窗口截图和录制视频&#xff0c;截图默认保存在“~/图片/截图”路径下。 可以在应用程序中搜索screenshot,如下图&#xff1a; 也可以在桌面右上角找到…

mysql之视图执行计划

一.视图 1.1视图简介 1.2 创建视图 1.3视图的修改 1.4视图的删除 1.5查看视图 二.连接查询案例 三.思维导图 一.视图 1.1视图简介 虚拟表&#xff0c;和普通表一样使用 MySQL中的视图&#xff08;View&#xff09;是一个虚拟表&#xff0c;其内容由查询定义。与实际表不…

DevSecOps 工具:初学者指南

DevSecOps 是开发、安全和运营的融合&#xff0c;标志着软件开发的范式转变&#xff0c;在整个软件开发生命周期 (SDLC)中无缝集成安全性。 这种方法标志着不再将安全视为开发过程中的一个阶段。除了DevSecOps 的核心原则和最佳实践之外&#xff0c;特定工具也是实施和强化安全…

C++学习笔记——类作用域和抽象数据类型

目录 一、C类作用域 类内作用域 类外作用域 二、类作用域案列详细的解释说明 三、抽象数据类型 四、总结 类作用域 抽象数据类型&#xff08;ADT&#xff09; 五、图书馆管理系统 一、C类作用域 在C中&#xff0c;类作用域是指类定义中声明的标识符&#xff08;成员变…

如何使用UUP从windows更新服务器下载windows10原版镜像

UUP是指Windows 10中的一种更新技术&#xff0c;全称为Unified Update Platform。UUP的目标是提供更快、更高效的更新体验&#xff0c;它通过增量更新的方式来更新操作系统&#xff0c;只下载和安装实际变化的部分&#xff0c;而不是整个更新包。这样可以节省带宽和时间&#x…

时间序列预测 — LSTM实现多变量多步负荷预测(Tensorflow):多输入多输出

目录 1 数据处理 1.1 导入库文件 1.2 导入数据集 ​1.3 缺失值分析 2 构造训练数据 3 LSTM模型训练 4 LSTM模型预测 4.1 分量预测 4.2 可视化 1 数据处理 1.1 导入库文件 import time import datetime import pandas as pd import numpy as np import matplotlib.p…

华为面经总结

为了帮助大家更好的应对面试&#xff0c;我整理了往年华为校招面试的题目&#xff0c;供大家参考~ 面经1 技术一面 自我介绍说下项目中的难点volatile和synchronized的区别&#xff0c; 问的比较细大顶堆小顶堆怎么删除根节点CSRF攻击是什么&#xff0c;怎么预防线程通信方式…

C#不会循环响应的Action设计与实现

目录 一、简述二、测试代码三、测试的输出四、核心代码五、其它 一、简述 特点&#xff1a; 不光是能防止直接的死循环调用&#xff1b;还能防止间接的死循环调用&#xff1b;还支持对不同参数判定&#xff0c;不同参数的调用可以不当循环调用&#xff1b; 消息事件系统中必…

leetcode——杨辉三角

https://leetcode.cn/problems/pascals-triangle/ 杨辉三角&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 核心思想&#xff1a;找出杨辉三角的规律&#xff0c;发…

PromptCast:基于提示学习的时序预测模型!

目前时序预测的SOTA模型大多基于Transformer架构&#xff0c;以数值序列为输入&#xff0c;如下图的上半部分所示&#xff0c;通过多重编码融合历史数据信息&#xff0c;预测未来一定窗口内的序列数值。 受到大语言模型提示工程技术的启发&#xff0c;文章提出了一种时序预测新…