目录 废话不多说,直接上目录
问题背景与理论
在电力负荷预测中,随着电力系统的复杂性增加和不确定性因素的影响,准确的电力负荷预测对于电力系统的调度和稳定运行至关重要。本文采用了一种基于长短期记忆网络(LSTM)结合CEEMDAN分解技术的预测方法,下面从理论层面对相关技术进行简要说明。
1. 长短期记忆网络(LSTM)理论
长短期记忆网络(LSTM,Long Short-Term Memory)是一种特殊的循环神经网络(RNN),专门用于解决传统RNN在处理长序列时存在的梯度消失和梯度爆炸问题。LSTM能够通过“记忆单元”有效保留历史信息,从而在时间序列数据中表现出色。其主要的结构特点包括:
-
记忆单元(Cell State):LSTM的核心是记忆单元,用于保存时间步长之间的信息流。
-
输入门、遗忘门、输出门:这三个门结构控制了信息的流入、保留和输出。通过这些门结构,LSTM能够根据需要选择性地记住或遗忘信息,避免因时间跨度过长而丢失重要特征。
在电力负荷预测中,电力负荷随时间变化具有显著的时序特征。LSTM可以通过学习历史负荷数据,捕捉负荷随时间的变化趋势和周期性特征,从而提高预测精度。
2. CEEMDAN分解理论
CEEMDAN(Complete Ensemble Empirical Mode Decomposition with Adaptive Noise)是一种信号处理技术,用于分解非线性和非平稳的时间序列数据。与传统的经验模态分解(EMD)相比,CEEMDAN通过加入噪声的方式,提高了分解的稳定性和精确性。它将复杂的时间序列分解为一系列具有不同频率特征的本征模态函数(IMF),使得每个IMF表示时间序列的不同组成部分。
在电力负荷预测中,负荷数据通常受到多种复杂因素的影响,存在显著的非线性和非平稳特性。CEEMDAN可以将负荷数据分解为不同的模态分量(IMF),从而分别提取出负荷数据中的周期性、趋势性和随机波动等不同特征。通过对每个分量单独进行建模和预测,可以有效提高整体预测性能。
可参考往期文章:
3. LSTM与CEEMDAN结合的优势
将CEEMDAN分解与LSTM模型结合,能够充分发挥两者的优势:
-
特征提取能力增强:通过CEEMDAN分解,复杂的负荷数据被分解为多个本征模态函数(IMF),从而可以对不同模态分别进行建模,使得每个模态数据的特征更加明显。
-
建模精度提高:LSTM擅长捕捉时间序列中的长短期依赖关系。当负荷数据经过CEEMDAN分解后,LSTM可以更好地学习每个分量的时间序列特征,从而提高整体预测精度。
-
抗噪性增强:CEEMDAN通过引入噪声进行分解,有效提高了模型对非线性和非平稳数据的适应能力,进一步减少噪声干扰。
4. 应用场景与前景
电力负荷预测是电力系统调度、优化运行和可再生能源利用等领域的关键环节。通过将LSTM与CEEMDAN技术结合,能够有效应对电力负荷数据中的不确定性、非线性以及复杂时序特性,预测精度大幅提升。该方法不仅适用于电力行业,还可推广到其他具有复杂时序数据的领域,如金融市场预测、气象预测等。
LSTM与CEEMDAN相结合的电力负荷预测方法,基于对负荷数据的深入挖掘和建模,具有强大的非线性建模能力和时间依赖性捕捉能力。该方法不仅在理论上具有创新性,同时在实际应用中也展现出极高的预测精度和鲁棒性。未来,随着人工智能和大数据技术的进一步发展,该方法在电力行业的应用前景十分广阔。
Python代码实操
导入库和准备数据
# 导入所需的Python库
import os # 操作系统功能
import math # 数学功能
import pandas as pd # 数据处理和分析
import openpyxl
from math import sqrt # 平方根函数
from numpy import concatenate # 数组拼接
import matplotlib.pyplot as plt # 绘图
import numpy as np # 数值计算
# import tensorflow as tf # 深度学习
from sklearn.preprocessing import MinMaxScaler, StandardScaler, LabelEncoder
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from tensorflow.keras.layers import *
from tensorflow.keras.models import *
from pandas import DataFrame, concat
import keras.backend as K
from scipy.io import savemat, loadmat
from sklearn.neural_network import MLPRegressor
from keras.callbacks import LearningRateScheduler
from tensorflow.keras import Input, Model, Sequential
import mplcyberpunk
from qbstyles import mpl_style
import warnings
from prettytable import PrettyTable # 优美打印表格结果
# 忽略警告信息
warnings.filterwarnings("ignore")
这部分代码导入了进行数据分析、模型构建和评估所需的所有Python库。
# 读取数据
dataset = pd.read_csv("电力负荷预测数据.csv", encoding='gb2312')
print(dataset) # 显示数据集内容
dataset_vmd = pd.read_excel("CEEMDAN.xlsx")
values_vmd = dataset_vmd.values
values_vmd = values_vmd.astype('float32')
这里读取了两个数据文件,一个是CSV格式的电力负荷数据,另一个是Excel格式的CEEMDAN分解结果。
# 数据预处理
values = dataset.values[:, 1:] # 选择数据集中除了第一列之外的所有列
values = values.astype('float32') # 转换数据类型为float32
这里对原始数据进行了预处理,选择了除了第一列之外的所有列,并转换了数据类型。
备注
(1)单输入单步预测,就让values等于某一列数据,n_out = 1,n_in, num_samples, scroll_window 根据自己情况来
(2)单输入多步预测,就让values等于某一列数据,n_out > 1,n_in, num_samples, scroll_window 根据自己情况来
(3)多输入单步预测,就让values等于多列数据,n_out = 1,n_in, num_samples, scroll_window 根据自己情况来
(4)多输入多步预测,就让values等于多列数据,n_out > 1,n_in, num_samples, scroll_window 根据自己情况来
values = dataset.values[:,1:] #只取第2列数据,要写成1:2;只取第3列数据,要写成2:3,取第2列之后(包含第二列)的所有数据,写成 1:
定义数据整理函数
# 定义一个函数来整理数据,以适应LSTM模型的输入
def data_collation(data, n_in, n_out, or_dim, scroll_window, num_samples):
res = np.zeros((num_samples, n_in * or_dim + n_out))
for i in range(num_samples):
h1 = data[scroll_window * i: n_in + scroll_window * i, 0:or_dim]
h2 = h1.reshape(1, n_in * or_dim)
h3 = data[n_in + scroll_window * i: n_in + scroll_window * i + n_out, -1].T
h4 = h3[np.newaxis, :]
h5 = np.hstack((h2, h4))
res[i, :] = h5
return res
这个函数用于整理数据,使其适合作为LSTM模型的输入。它根据输入参数的不同,可以处理单输入单步预测、单输入多步预测、多输入单步预测和多输入多步预测。
定义LSTM模型构建函数
这个函数定义了一个LSTM模型,包括输入层、一个LSTM层和一个输出层。模型编译时使用了均方误差作为损失函数,Adam作为优化器。
# 定义一个函数来创建LSTM模型
def lstm_model():
# 定义一个函数来创建LSTM模型
inputs = Input(shape=(vp_train.shape[1], vp_train.shape[2]))
# 创建模型的输入层,输入的形状为vp_train的第二维和第三维(时间步和特征数)
lstm = LSTM(128, activation='selu', return_sequences=False)(inputs)
# 添加一个LSTM层,其中有128个神经元,激活函数为'selu'。
# return_sequences=False表示LSTM层只返回最后一个时间步的输出。
outputs = Dense(vt_train.shape[1])(lstm)
# 创建一个全连接层,神经元的数量等于vt_train的列数(输出维度)
model = Model(inputs=inputs, outputs=outputs)
# 创建模型,指定输入和输出
model.compile(loss='mse', optimizer='Adam')
# 编译模型,设置损失函数为均方误差(mse),优化器为Adam
model.summary()
# 展示模型的结构
return model
# 返回构建的模型
数据处理和模型训练
# 定义输入和输出参数
n_in = 5 # 输入时间步长
n_out = 1 # 输出时间步长
or_dim = values.shape[1] # 特征维度
num_samples = 2000 # 样本数量
scroll_window = 1 # 滑动窗口大小
n_train_number = int(num_samples * 0.85) # 训练集样本数量
n_test_number = num_samples - n_train_number # 测试集样本数量
predicted_data = []
actual_data = []
# 循环处理每个IMF分量
for vmd_num in range(len(values_vmd[0])):
imf = values_vmd[:, vmd_num]
imf = imf.reshape(-1, 1)
combined_data = np.hstack((values[:, 0:-1], imf)) # 合并原始数据和IMF分量
res = data_collation(combined_data, n_in, n_out, or_dim, scroll_window, num_samples)
combined_data = np.array(res)
Xtrain = combined_data[:n_train_number, :n_in * or_dim]
Ytrain = combined_data[:n_train_number, n_in * or_dim:]
Xtest = combined_data[n_train_number:, :n_in * or_dim]
Ytest = combined_data[n_train_number:, n_in * or_dim:]
这部分代码设置了模型的输入和输出参数,然后对每个IMF分量进行循环处理,合并原始数据和IMF分量,然后使用data_collation
函数整理数据。
# 归一化处理
m_in = MinMaxScaler()
vp_train = m_in.fit_transform(Xtrain)
vp_test = m_in.transform(Xtest)
m_out = MinMaxScaler()
vt_train = m_out.fit_transform(Ytrain)
vt_test = m_out.transform(Ytest)
# 重塑数据以适应LSTM模型的输入
vp_train = vp_train.reshape((vp_train.shape[0], n_in, or_dim))
vp_test = vp_test.reshape((vp_test.shape[0], n_in, or_dim))
# 构建和训练LSTM模型
model = lstm_model()
model.fit(vp_train, vt_train, batch_size=32, epochs=50, validation_split=0.25, verbose=2)
这里对数据进行了归一化处理,然后重塑数据以适应LSTM模型的输入。接着构建LSTM模型并进行训练。
# 预测和反归一化
yhat = model.predict(vp_test)
yhat = yhat.reshape(num_samples - n_train_number, n_out)
yy = m_out.inverse_transform(yhat)
predicted_data.append(yy)
actual_data.append(Ytest)
模型训练完成后,使用模型对测试集进行预测,并将预测结果反归一化。
评估模型性能
# 定义MAPE计算函数
def mape(y_true, y_pred):
record = []
for index in range(len(y_true)):
temp_mape = np.abs((y_pred[index] - y_true[index]) / y_true[index])
record.append(temp_mape)
return np.mean(record) * 100
# 定义模型评估函数
def evaluate_forecasts(Ytest, predicted_data, n_out):
mse_dic = []
rmse_dic = []
mae_dic = []
mape_dic = []
r2_dic = []
table = PrettyTable(['测试集指标', 'MSE', 'RMSE', 'MAE', 'MAPE', 'R2'])
for i in range(n_out):
actual = [float(row[i]) for row in Ytest]
predicted = [float(row[i]) for row in predicted_data]
mse = mean_squared_error(actual, predicted)
mse_dic.append(mse)
rmse = sqrt(mean_squared_error(actual, predicted))
rmse_dic.append(rmse)
mae = mean_absolute_error(actual, predicted)
mae_dic.append(mae)
MApe = mape(actual, predicted)
mape_dic.append(MApe)
r2 = r2_score(actual, predicted)
r2_dic.append(r2)
if n_out == 1:
strr = '预测结果指标:'
else:
strr = '第' + str(i + 1) + '步预测结果指标:'
table.add_row([strr, mse, rmse, mae, str(MApe) + '%', str(r2 * 100) + '%'])
return mse_dic, rmse_dic, mae_dic, mape_dic, r2_dic, table
# 调用评估函数并打印结果
mse_dic, rmse_dic, mae_dic, mape_dic, r2_dic, table = evaluate_forecasts(actual_test, pre_test, n_out)
print(table)
测试集指标 | MSE | RMSE | MAE | MAPE | R2 |
---|---|---|---|---|---|
预测结果指标 | 995.954 | 31.559 | 24.035 | 5.316% | 86.786% |
这部分代码定义了MAPE(平均绝对百分比误差)计算函数和模型评估函数,然后调用这些函数来评估模型的性能,并打印出评估结果。
绘制预测结果图
from matplotlib import rcParams
# 设置图表样式
rcParams.update({
"font.family": 'serif',
"font.size": 10,
"mathtext.fontset": 'stix',
"font.serif": ['Times New Roman'],
'axes.unicode_minus': False
})
# 开启交互模式
plt.ion()
for ii in range(n_out):
plt.figure(figsize=(10, 2), dpi=300) # 设置图表大小和分辨率
plt.plot(range(1, len(actual_test) + 1), pre_test[:, ii], linestyle="--", label='Predict') # 绘制预测值
plt.plot(range(1, len(actual_test) + 1), actual_test[:, ii], linestyle="-", label='Real') # 绘制实际值
plt.legend(loc='upper right') # 显示图例
plt.xlabel("Sample Points") # 设置x轴标签
plt.ylabel("Value") # 设置y轴标签
plt.title(f"Step {ii+1} Prediction\nMAPE: {mape(actual_test[:, ii], pre_test[:, ii])}%") # 设置标题和MAPE值
# 关闭交互模式并显示图表
plt.ioff()
plt.show()
关注公众号,后台回复"CEEMDAN+LSTM"即可获得数据与源代码!
往期推荐
数模国赛冲刺 | 预测类创新算法CNN-GRU、LSTM、BiGRU、BiLSTM-Attention
数模国赛冲刺 | 预测类创新算法 TCN-GRU/BiGRU
标签:CEEMDAN,train,dic,数模,import,LSTM,data From: https://blog.csdn.net/EasyMCM/article/details/142994399