选取数据集
构建三层LSTM神经网络模型对MM264瓦斯浓度进行训练并预测。数据集如下表1所示。
表1 LSTM网络训练数据集(前15行)
序号 | MM264 | 序号 | MM264 | 序号 | MM264 |
1 | 0.1 | 6 | 0.2 | 11 | 0.1 |
2 | 0.2 | 7 | 0.2 | 12 | 0.1 |
3 | 0.1 | 8 | 0.2 | 13 | 0.1 |
4 | 0.2 | 9 | 0.2 | 14 | 0.1 |
5 | 0.1 | 10 | 0.2 | 15 | 0.2 |
MM264瓦斯浓度数据可视化如图1所示:
图6-5 MM264数据展示
LSTM模型定义
LSTM网络模型如下表2所示:
表2 LSTM神经网络模型
Layer (type) | Output Shape | Param # |
lstm (LSTM) | (None, 1, 32) | 4352 |
lstm_1 (LSTM) | (None, 1, 32) | 8320 |
lstm_2 (LSTM) | (None, 32) | 8320 |
dense (Dense) | (None, 1) | 33 |
模型结构解析:
该模型包括三个层次的LSTM层和一个全连接输出层,第一个LSTM层作为输入层,具有32个神经元并返回序列,输出的是一个向量序列,第二层跟第一层一样具有32个神经元并返回序列,第三层也具有32个神经元但是并不返回序列最终只输出一个向量。最后一层全连接层作为输出层,用于回归任务。并且使用均方差作为损失函数同时使用Adam优化器。
LSTM网络训练
LSTM神经网络模型训练如下:
import csv
import math
import numpy
import pandas as pd
import numpy as np
from keras.losses import mean_squared_error, mean_absolute_error
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, LSTM
import matplotlib.pyplot as plt
# 加载数据集
df=pd.read_csv(r'C:\Users\hmzjb\PycharmProjects\pythonProject7\CNN-LSTM\processData\try1.csv')
#选择要处理的列
data = df['MM264'].values.reshape(-1, 1)
# 数据标准化
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data)
# 划分数据集
training_size = int(len(scaled_data) * 0.7)
test_size = len(scaled_data) - training_size
train_data, test_data = scaled_data[0:training_size, :], scaled_data[training_size:len(scaled_data), :]
# 数据预处理
def create_dataset(dataset, time_step=1):
dataX, dataY = [], []
for i in range(len(dataset) - time_step - 1):
a = dataset[i:(i + time_step), 0]
dataX.append(a)
dataY.append(dataset[i + time_step, 0])
return np.array(dataX), np.array(dataY)
time_step = 1
X_train, y_train = create_dataset(train_data, time_step)
X_test, y_test = create_dataset(test_data, time_step)
# Reshape the input to be [samples, time steps, features]
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1])
X_test = X_test.reshape(X_test.shape[0], X_test.shape[1])
# 构建网络模型
model = Sequential()
model.add(LSTM(32, return_sequences=True, input_shape=(time_step, 1)))
model.add(LSTM(32, return_sequences=True))
model.add(LSTM(32))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.summary()
# 训练模型
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=64, verbose=1
首先,先对数据集进行标准化处理,之后再划分训练集和测试集,划分好数据后,将数据处理成LSTM网络模型可训练的数据类型,对样本进行重塑后进行LSTM网络训练。
瓦斯浓度预测
对LSTM模型进行预测并将LSTM模型的预测评估指标保存到文件中,具体操作如下面代码所示:
# 重新编码数据
trainPredict = model.predict(X_train)
testPredict = model.predict(X_test)
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([y_train])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([y_test])
# 改变训练预测方便绘图
trainPredictPlot = numpy.empty_like(scaled_data)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[time_step:len(trainPredict) + time_step, :] = trainPredict
# 位移试验图预测
testPredictPlot = numpy.empty_like(scaled_data)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict) + (time_step * 2) + 1:len(scaled_data) - 1, :] = testPredict
# 绘制基线和预测图
plt.plot(scaler.inverse_transform(scaled_data), label='REAL')
plt.plot(trainPredictPlot,label='predict',color='orange')
plt.plot(testPredictPlot,color='orange')
plt.legend()
plt.ylim(0,2)
plt.show()
首先使用这个模型来预测训练和测试的数据,然后利用定标器对预测值进行逆转换。接下来,创建两个空数组来保存训练和测试数据的预测值。使用训练数据的预测值填充train PredictPlot数组,并用测试数据的预测值填充testPredictPlot数组。最后进行可视化,结果如图2所示:
图2 LSTM神经网络预测结果图
计算LSTM神经网络预测指标:
# 计算 RMSE, MAE, R2
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:, 0]))
TrainMae = mean_absolute_error(trainY[0], trainPredict[:, 0])
Train_sse = numpy.sum((trainY[0] - trainPredict[:, 0]) ** 2)
Train_sst = numpy.sum((trainY[0] - numpy.mean(trainY[0])) ** 2)
Train_r2 = 1 - Train_sse / Train_sst
print("Train RMSE: {:.2f}".format(trainScore))
print("Train MAE: {:.2f}".format(TrainMae))
print("Train R2: {:.2f}".format(Train_r2))
labels = ['MAE', 'RMSE', 'R2']
values = [TrainMae,trainScore, Train_r2]
# 将值转换为字符串
values_str = [format(value) for value in values]
# 将标签和值组合成列表
data = [[label, value_str] for label, value_str in zip(labels, values_str)]
# 数据存入文件
with open(r'C:\Users\hmzjb\PycharmProjects\pythonProject7\CNN-LSTM\预测指标对比\LSTM.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(labels)
writer.writerow(values_str)
在CSV文件中保存时间步长分别为T+1、T+3和T+5的预测指标的数据,如表3所示:
表3 保存后的数据(LSTM)
TIME_STEP | MAE | RMSE | R2 |
T+1 | 0.062252026 | 0.112655254 | 0.66408632 |
T+3 | 0.061546317 | 0.115438102 | 0.63124561 |
T+5 | 0.057148135 | 0.113641526 | 0.61235219 |