结合VMD、CNN和LSTM的方法,可以充分利用它们各自的优势,实现对复杂非线性信号的高效建模和预测,通过VMD将原始信号分解为多个模态分量,然后将这些分量作为CNN-LSTM模型的输入,可以更好地捕捉信号的局部特征和时空关系,从而提高了模型的预测能力和泛化能力,本文旨在探讨VMD-CNN-LSTM方法在信号处理和时间序列预测中的应用,重点介绍其算法实现和实验结果
1. VMD-LSTM参考
基于VMD分解的VMD-LSTM时间序列预测模型实现,大力提升预测精度!
VMD-LSTM将VMD用于对原始时间序列进行分解,得到多个本征模态函数, 每个本征模态函数代表了原始信号在不同频率和振幅上的成分,具有更好的局部特征表示,将这些本征模态函数作为输入序列,每个模态分别构建一个LSTM预测模型进行学习预测,从而提高模型的预测性能,在接下来将引入CNN探讨在相同数据集上VMD-CNN-LSTM与VMD-LSTM模型精度比较
2. VMD-CNN-LSTM流程图
2. 代码实现
2.1 数据解读
import pandas as pd
df = pd.read_excel('数据.xlsx',index_col=0, parse_dates=['数据时间'])
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(15, 5))
plt.plot(df['总有功功率(kw)'], label='原始数据', color='r', alpha=0.3)
plt.title('时序图')
plt.grid(True)
plt.legend()
plt.show()
在电力行业,对每日功率波动进行准确预测对于电网调度和能源规划至关重要。通过深度学习模型,可以更好地理解数据的复杂关系,从而提高预测的准确性,首先,加载数据(此数据已经过一定的异常值、缺失值处理)该数据为每日平均总有功功率(kw)
2.2 CNN-LSTM模型建立
# 0-1标准化
arr_max = np.max(np.array(df))
arr_min = np.min(np.array(df))
data_bz = (np.array(df)-arr_min)/(arr_max-arr_min)
data_bz = data_bz.ravel() # 转换为一维数组
def dataset(data, win_size=12):
X = [] # 用于存储输入特征的列表
Y = [] # 用于存储目标值的列表
# 遍历数据,形成样本窗口
for i in range(len(data) - win_size):
temp_x = data[i:i + win_size] # 提取窗口大小范围内的输入特征
temp_y = data[i + win_size] # 提取对应的目标值
X.append(temp_x)
Y.append(temp_y)
# 转换列表为 NumPy 数组
X = np.asarray(X)
Y = np.asarray(Y)
return X, Y
data_x, data_y = dataset(data_bz, 12)
data_x = np.expand_dims(data_x, axis=2) # 为Conv1D扩展维度
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Conv1D, MaxPooling1D, Flatten
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn import metrics
from tensorflow.keras.layers import TimeDistributed
plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
train_x, test_x, train_y, test_y = train_test_split(data_x, data_y, test_size=0.2, shuffle=False)
cnn_lstm = Sequential()
cnn_lstm.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(train_x.shape[1], train_x.shape[2])))
cnn_lstm.add(MaxPooling1D(pool_size=2))
cnn_lstm.add(LSTM(256))
cnn_lstm.add(Dense(1, activation='sigmoid'))
cnn_lstm.compile(loss='mse', optimizer='adam')
history = cnn_lstm.fit(train_x, train_y, epochs=18, batch_size=64, validation_split=0.2, shuffle=False)
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'], c='r')
plt.legend(['loss', 'val_loss'])
plt.show()
y_pred = cnn_lstm.predict(test_x)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test_y, np.array([i for arr in y_pred for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test_y, np.array([i for arr in y_pred for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test_y, np.array([i for arr in y_pred for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度 (R^2):", r2)
在这里没有使用包装器(TimeDistributed)处理数据序列,而是直接将数据输入到模型中,通常会导致模型只能处理固定长度的序列,这意味着模型只能接受固定长度的输入序列,并且不会自动适应不同长度的序列,使用包装器处理数据序列可以让模型更灵活地处理不同长度的序列,因为包装器会自动处理序列长度的变化,并将相同的操作应用于每个时间步。这样可以使模型更好地适应不同长度的序列,并且可以提高模型的性能和泛化能力
def predict_future_values(model, sequence, future_steps):
prediction_results = []
for _ in range(future_steps):
# 检查序列的维度并调整形状
if len(sequence.shape) == 1:
sequence = sequence.reshape(1, sequence.shape[0], 1)
elif len(sequence.shape) == 2:
sequence = sequence.reshape(1, sequence.shape[0], sequence.shape[1])
# 对当前序列进行预测
next_day_prediction = model.predict(sequence)
# 将预测结果加入到结果列表中
prediction_results.append(next_day_prediction[0, 0])
# 更新序列,舍弃第一个时间步,将预测结果加入序列末尾
sequence = np.append(sequence[:, 1:, :], next_day_prediction.reshape(1, 1, 1), axis=1)
return prediction_results
sequence = test_x[-1]
future_predictions = predict_future_values(cnn_lstm, sequence, 30)
print("未来30天的预测值:", future_predictions)
series = np.array(future_predictions)*(arr_max-arr_min)+arr_min
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test_y*(arr_max-arr_min)+arr_min, color = 'c', label = '每日实际功率波动曲线')
plt.plot(y_pred*(arr_max-arr_min)+arr_min, color = 'r', label = '预测每日功率波动曲线')
plt.plot(range(len(y_pred), len(y_pred)+len(series)), series, color = 'b', label = '向后预测30天')
plt.title('每日实际功率波动与预测每日功率波动比对图')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.3 VMD分解时间序列
from vmdpy import VMD
# VMD 的一些参数
alpha = 1300 # 适度的频带宽度约束
tau = 0. # 容忍噪声(没有严格的保真度要求)
K = 5 # 3个模态
DC = 0 # 不强制直流分量
init = 1 # 均匀初始化角频率
tol = 1e-7
# 运行 VMD
u, u_hat, omega = VMD(df['总有功功率(kw)'], alpha, tau, K, DC, init, tol)
# 可视化分解后的 5 个 IMF
# 可视化分解后的 5 个 IMF
plt.figure(figsize=(15, 8))
for i in range(K):
plt.subplot(K, 1, i+1)
plt.plot(u[i, :])
plt.title(f'IMF {i+1}')
plt.xlabel('时间')
plt.ylabel('幅度')
plt.tight_layout()
plt.show()
# 保存每个 IMF 到不同的 DataFrame
imf_dataframes = {}
for i in range(len(u)):
imf_name = 'imf_{}'.format(i+1)
imf_dataframes[imf_name] = pd.DataFrame({'Value': u[i]})
通过代码,可以清晰地展示VMD分解后得到的每个本征模态函数,以及得到分解后的数据(如果为了进一步提高模型可以引入遗传算法等找到最优参数),接下来将对每一个分解数据进行CNN-LSTM模型建立
2.3.1 IMF1-CNN-LSTM
arr_max_1 = np.max(np.array(imf_dataframes['imf_1']))
arr_min_1 = np.min(np.array(imf_dataframes['imf_1']))
data_bz_1 = (np.array(imf_dataframes['imf_1'])-arr_min_1)/(arr_max_1-arr_min_1)
data_bz_1 = data_bz_1.ravel() # 转换为一维数组
data_x_1, data_y_1 = dataset(data_bz_1, 12)
data_x_1 = np.expand_dims(data_x_1, axis=2)
train_x_1, test_x_1, train_y_1, test_y_1 = train_test_split(data_x_1, data_y_1, test_size = 0.2, shuffle = False)
cnn_lstm_1 =Sequential()
cnn_lstm_1.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(train_x_1.shape[1], train_x_1.shape[2])))
cnn_lstm_1.add(MaxPooling1D(pool_size=2))
cnn_lstm_1.add(LSTM(256))
cnn_lstm_1.add(Dense(1, activation='sigmoid'))
cnn_lstm_1.compile(loss='mse', optimizer='adam')
history_1 = cnn_lstm_1.fit(train_x_1, train_y_1, epochs=18, batch_size=64, validation_split=0.2, shuffle=False)
plt.plot(history_1.history['loss'])
plt.plot(history_1.history['val_loss'], c='r')
plt.legend(['loss', 'val_loss'])
plt.show()
y_pred_1 = cnn_lstm_1.predict(test_x_1)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test_y_1, np.array([i for arr in y_pred_1 for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test_y_1, np.array([i for arr in y_pred_1 for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test_y_1, np.array([i for arr in y_pred_1 for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
sequence = test_x_1[-1]
future_predictions = predict_future_values(cnn_lstm_1, sequence, 30)
print("未来30天的预测值:", future_predictions)
series_1 = np.array(future_predictions)*(arr_max_1-arr_min_1)+arr_min_1
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test_y_1*(arr_max_1-arr_min_1)+arr_min_1, color = 'c', label = 'imf_1测试集实际功率波动曲线')
plt.plot(y_pred_1*(arr_max_1-arr_min_1)+arr_min_1, color = 'r', label = 'imf_1测试集预测功率波动曲线')
plt.plot(range(len(y_pred_1), len(y_pred_1)+len(series_1)), series_1, color = 'b', label = 'imf_1向后预测30天功率波动曲线')
plt.title('imf_1')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.3.2 IMF2-CNN-LSTM
arr_max_2 = np.max(np.array(imf_dataframes['imf_2']))
arr_min_2 = np.min(np.array(imf_dataframes['imf_2']))
data_bz_2 = (np.array(imf_dataframes['imf_2'])-arr_min_2)/(arr_max_2-arr_min_2)
data_bz_2 = data_bz_2.ravel() # 转换为一维数组
data_x_2, data_y_2 = dataset(data_bz_2, 12)
data_x_2 = np.expand_dims(data_x_2, axis=2)
train_x_2, test_x_2, train_y_2, test_y_2 = train_test_split(data_x_2, data_y_2, test_size = 0.2, shuffle = False)
cnn_lstm_2 = Sequential()
cnn_lstm_2.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(train_x_2.shape[1], train_x_2.shape[2])))
cnn_lstm_2.add(MaxPooling1D(pool_size=2))
cnn_lstm_2.add(LSTM(256, return_sequences=True)) # 添加一个额外的LSTM层
cnn_lstm_2.add(LSTM(128)) # 添加第二个LSTM层
cnn_lstm_2.add(Dense(64, activation='relu')) # 添加一个全连接层
cnn_lstm_2.add(Dense(1, activation='sigmoid'))
cnn_lstm_2.compile(loss='mse', optimizer='adam')
history_2 = cnn_lstm_2.fit(train_x_2, train_y_2, epochs=50, batch_size=64, validation_split=0.2, shuffle=False)
plt.plot(history_2.history['loss'])
plt.plot(history_2.history['val_loss'], c='r')
plt.legend(['loss', 'val_loss'])
plt.show()
y_pred_2 = cnn_lstm_2.predict(test_x_2)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test_y_2, np.array([i for arr in y_pred_2 for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test_y_2, np.array([i for arr in y_pred_2 for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test_y_2, np.array([i for arr in y_pred_2 for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
sequence = test_x_2[-1]
future_predictions = predict_future_values(cnn_lstm_2, sequence, 30)
print("未来30天的预测值:", future_predictions)
series_2 = np.array(future_predictions)*(arr_max_2-arr_min_2)+arr_min_2
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test_y_2*(arr_max_2-arr_min_2)+arr_min_2, color = 'c', label = 'imf_2测试集实际功率波动曲线')
plt.plot(y_pred_2*(arr_max_2-arr_min_2)+arr_min_2, color = 'r', label = 'imf_2测试集预测功率波动曲线')
plt.plot(range(len(y_pred_2), len(y_pred_2)+len(series_2)), series_2, color = 'b', label = 'imf_2向后预测30天功率波动曲线')
plt.title('imf_2')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.3.3 IMF3-CNN-LSTM
arr_max_3 = np.max(np.array(imf_dataframes['imf_3']))
arr_min_3 = np.min(np.array(imf_dataframes['imf_3']))
data_bz_3 = (np.array(imf_dataframes['imf_3'])-arr_min_3)/(arr_max_3-arr_min_3)
data_bz_3 = data_bz_3.ravel() # 转换为一维数组
data_x_3, data_y_3 = dataset(data_bz_3, 12)
data_x_3 = np.expand_dims(data_x_3, axis=2)
train_x_3, test_x_3, train_y_3, test_y_3 = train_test_split(data_x_3, data_y_3, test_size = 0.2, shuffle = False)
cnn_lstm_3 =Sequential()
cnn_lstm_3.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(train_x_3.shape[1], train_x_3.shape[2])))
cnn_lstm_3.add(MaxPooling1D(pool_size=2))
cnn_lstm_3.add(LSTM(256))
cnn_lstm_3.add(Dense(1, activation='sigmoid'))
cnn_lstm_3.compile(loss='mse', optimizer='adam')
history_3 = cnn_lstm_3.fit(train_x_3, train_y_3, epochs=18, batch_size=64, validation_split=0.2, shuffle=False)
plt.plot(history_3.history['loss'])
plt.plot(history_3.history['val_loss'], c='r')
plt.legend(['loss', 'val_loss'])
plt.show()
y_pred_3 = cnn_lstm_3.predict(test_x_3)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test_y_3, np.array([i for arr in y_pred_3 for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test_y_3, np.array([i for arr in y_pred_3 for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test_y_3, np.array([i for arr in y_pred_3 for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
sequence = test_x_3[-1]
future_predictions = predict_future_values(cnn_lstm_3, sequence, 30)
print("未来30天的预测值:", future_predictions)
series_3 = np.array(future_predictions)*(arr_max_3-arr_min_3)+arr_min_3
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test_y_3*(arr_max_3-arr_min_3)+arr_min_3, color = 'c', label = 'imf_3测试集实际功率波动曲线')
plt.plot(y_pred_3*(arr_max_3-arr_min_3)+arr_min_3, color = 'r', label = 'imf_3测试集预测功率波动曲线')
plt.plot(range(len(y_pred_3), len(y_pred_3)+len(series_3)), series_3, color = 'b', label = 'imf_3向后预测30天功率波动曲线')
plt.title('imf_3')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.3.4 IMF4-CNN-LSTM
arr_max_4 = np.max(np.array(imf_dataframes['imf_4']))
arr_min_4 = np.min(np.array(imf_dataframes['imf_4']))
data_bz_4 = (np.array(imf_dataframes['imf_4'])-arr_min_4)/(arr_max_4-arr_min_4)
data_bz_4 = data_bz_4.ravel() # 转换为一维数组
data_x_4, data_y_4 = dataset(data_bz_4, 12)
data_x_4 = np.expand_dims(data_x_4, axis=2)
train_x_4, test_x_4, train_y_4, test_y_4 = train_test_split(data_x_4, data_y_4, test_size = 0.2, shuffle = False)
cnn_lstm_4 =Sequential()
cnn_lstm_4.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(train_x_4.shape[1], train_x_4.shape[2])))
cnn_lstm_4.add(MaxPooling1D(pool_size=2))
cnn_lstm_4.add(LSTM(256))
cnn_lstm_4.add(Dense(1, activation='sigmoid'))
cnn_lstm_4.compile(loss='mse', optimizer='adam')
history_4 = cnn_lstm_4.fit(train_x_4, train_y_4, epochs=18, batch_size=64, validation_split=0.2, shuffle=False)
plt.plot(history_4.history['loss'])
plt.plot(history_4.history['val_loss'], c='r')
plt.legend(['loss', 'val_loss'])
plt.show()
y_pred_4 = cnn_lstm_4.predict(test_x_4)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test_y_4, np.array([i for arr in y_pred_4 for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test_y_4, np.array([i for arr in y_pred_4 for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test_y_4, np.array([i for arr in y_pred_4 for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
sequence = test_x_4[-1]
future_predictions = predict_future_values(cnn_lstm_4, sequence, 30)
print("未来30天的预测值:", future_predictions)
series_4 = np.array(future_predictions)*(arr_max_4-arr_min_4)+arr_min_4
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test_y_4*(arr_max_4-arr_min_4)+arr_min_4, color = 'c', label = 'imf_4测试集实际功率波动曲线')
plt.plot(y_pred_4*(arr_max_4-arr_min_4)+arr_min_4, color = 'r', label = 'imf_4测试集预测功率波动曲线')
plt.plot(range(len(y_pred_4), len(y_pred_4)+len(series_4)), series_4, color = 'b', label = 'imf_4向后预测30天功率波动曲线')
plt.title('imf_4')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.3.5 IMF5-CNN-LSTM
arr_max_5 = np.max(np.array(imf_dataframes['imf_5']))
arr_min_5 = np.min(np.array(imf_dataframes['imf_5']))
data_bz_5 = (np.array(imf_dataframes['imf_5'])-arr_min_5)/(arr_max_5-arr_min_5)
data_bz_5 = data_bz_5.ravel() # 转换为一维数组
data_x_5, data_y_5 = dataset(data_bz_5, 12)
data_x_5 = np.expand_dims(data_x_5, axis=2)
train_x_5, test_x_5, train_y_5, test_y_5 = train_test_split(data_x_5, data_y_5, test_size = 0.2, shuffle = False)
cnn_lstm_5 =Sequential()
cnn_lstm_5.add(Conv1D(filters=64, kernel_size=3, activation='relu', input_shape=(train_x_5.shape[1], train_x_5.shape[2])))
cnn_lstm_5.add(MaxPooling1D(pool_size=2))
cnn_lstm_5.add(LSTM(256))
cnn_lstm_5.add(Dense(1, activation='sigmoid'))
cnn_lstm_5.compile(loss='mse', optimizer='adam')
history_5 = cnn_lstm_5.fit(train_x_5, train_y_5, epochs=18, batch_size=64, validation_split=0.2, shuffle=False)
plt.plot(history_5.history['loss'])
plt.plot(history_5.history['val_loss'], c='r')
plt.legend(['loss', 'val_loss'])
plt.show()
y_pred_5 = cnn_lstm_5.predict(test_x_5)
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test_y_5, np.array([i for arr in y_pred_5 for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test_y_5, np.array([i for arr in y_pred_5 for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test_y_5, np.array([i for arr in y_pred_5 for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
sequence = test_x_5[-1]
future_predictions = predict_future_values(cnn_lstm_5, sequence, 30)
print("未来30天的预测值:", future_predictions)
series_5 = np.array(future_predictions)*(arr_max_5-arr_min_5)+arr_min_5
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test_y_5*(arr_max_5-arr_min_5)+arr_min_5, color = 'c', label = 'imf_5测试集实际功率波动曲线')
plt.plot(y_pred_5*(arr_max_5-arr_min_5)+arr_min_5, color = 'r', label = 'imf_5测试集预测功率波动曲线')
plt.plot(range(len(y_pred_5), len(y_pred_5)+len(series_5)), series_5, color = 'b', label = 'imf_5向后预测30天功率波动曲线')
plt.title('imf_5')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.4 VMD-CNN-LSTM
pred = y_pred_1*(arr_max_1-arr_min_1)+arr_min_1+y_pred_2*(arr_max_2-arr_min_2)+arr_min_2+y_pred_3*(arr_max_3-arr_min_3)+arr_min_3+y_pred_4*(arr_max_4-arr_min_4)+arr_min_4+y_pred_5*(arr_max_5-arr_min_5)+arr_min_5
prophet = series_1+series_2+series_3+series_4+series_5
test = test_y*(arr_max-arr_min)+arr_min
plt.figure(figsize=(15,4), dpi =300)
plt.plot(test, color = 'c', label = '测试集实际功率波动曲线')
plt.plot(pred, color = 'r', label = 'vmd_lstm测试集预测功率波动曲线')
plt.plot(range(len(pred), len(pred)+len(prophet)), prophet, color = 'b', label = 'vmd_lstm向后预测30天功率波动曲线')
plt.title('vmd_lstm')
plt.grid(True)
plt.xlabel('时间')
plt.ylabel('总有功功率(kw)')
plt.legend()
plt.show()
2.5 模型评价指标比较
# 计算均方误差(MSE)
mse = metrics.mean_squared_error(test, np.array([i for arr in pred for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test, np.array([i for arr in pred for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test, np.array([i for arr in pred for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
这里的均方误差、均方根误差、平均绝对误差都是对归一化还原数据进行计算得到,前文的CNN-LSTM模型评价指标是对归一化的数据计算得到,为了比较两个模型的差异对前文CNN-LSTM模型也进行还原数据计算评价指标
# 更好对比对lstm数据进行归一化还原输出评价指标
# 计算均方误差(MSE)
test = test_y*(arr_max-arr_min)+arr_min
pred_1 = y_pred*(arr_max-arr_min)+arr_min
mse = metrics.mean_squared_error(test, np.array([i for arr in pred_1 for i in arr]))
# 计算均方根误差(RMSE)
rmse = np.sqrt(mse)
# 计算平均绝对误差(MAE)
mae = metrics.mean_absolute_error(test, np.array([i for arr in pred_1 for i in arr]))
from sklearn.metrics import r2_score # 拟合优度
r2 = r2_score(test, np.array([i for arr in pred_1 for i in arr]))
print("均方误差 (MSE):", mse)
print("均方根误差 (RMSE):", rmse)
print("平均绝对误差 (MAE):", mae)
print("拟合优度:", r2)
结合文章’基于VMD分解的VMD-LSTM时间序列预测模型实现,大力提升预测精度!‘给出完整的模型精度表,综合来看,在同一个数据集下,VMD-CNN-LSTM模型在所有指标(MSE、RMSE、MAE、R2)上表现最佳,其次是VMD-LSTM模型,而LSTM模型表现最差
3. 往期推荐
基于VMD分解的VMD-LSTM时间序列预测模型实现,大力提升预测精度!
可解释性机器学习库Shapash——鸢尾花XGBoost分类解释实现
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~