# 1. load dataset
from sklearn.metrics import mean_squared_error
from math import sqrt
import numpy as np
from pandas import concat
from matplotlib import pyplot
from keras.layers import Flatten, Dropout
from keras.layers.convolutional import MaxPooling1D
from keras.layers.convolutional import Conv1D
from keras.layers.recurrent import LSTM
from keras.layers import Dense
from keras.models import Sequential
from sklearn.preprocessing import MinMaxScaler
from pandas import read_csv
dataset = read_csv('CNN_LSTM_Attention data.csv')
values = dataset.values
# 2.tranform data to [0,1] 10个属性,第1个是待预测量
scaler = MinMaxScaler(feature_range=(0, 1))
XY = scaler.fit_transform(values)
X = XY[:, 1:10]
Y = XY[:, 0]
# 3.split into train and test sets
n_train_hours = 400 # 400个训练集,剩下的都是验证集
trainX = X[:n_train_hours, :]
trainY = Y[:n_train_hours]
testX = X[n_train_hours:, :]
testY = Y[n_train_hours:]
# LSTM的输入格式要3维,因此先做变换
train3DX = trainX.reshape((trainX.shape[0], 1, trainX.shape[1]))
test3DX = testX.reshape((testX.shape[0], 1, testX.shape[1]))
# 4. Define Network
model = Sequential()
model.add(Conv1D(filters=64, kernel_size=3, padding='same',
strides=1, activation='relu', input_shape=(1, 9)))
model.add(MaxPooling1D(pool_size=1))
model.add(LSTM(units=64, return_sequences=True))
model.add(Flatten())
# 也可以把LSTM和Flatten删除,仅保留LSTM
# model.add(LSTM(units=3))
model.add(Dense(128, activation='relu'))
# model.add(Dropout(0.2))
# 在lstm层之后可以添加隐含层,也可以不加,直接加输出层
model.add(Dense(units=64, kernel_initializer='normal', activation='relu'))
# 最后输出层1个神经元和输出的个数对应
model.add(Dense(units=1, kernel_initializer='normal', activation='sigmoid'))
# 5. compile the network
model.compile(loss='mse', optimizer='adam')
model.summary()
# 6. fit the network
history = model.fit(train3DX, trainY, epochs=200, batch_size=128,
validation_data=(test3DX, testY), verbose=2, shuffle=False)
# 7. evaluate the network
pyplot.subplot(121)
pyplot.plot(history.history['loss'], label='train_loss')
pyplot.plot(history.history['val_loss'], label='test_loss')
pyplot.legend()
# 8. make a prediction and invertscaling for forecast
forecasttestY0 = model.predict(test3DX)
inv_yhat = np.concatenate((testX, forecasttestY0), axis=1)
inv_y = scaler.inverse_transform(inv_yhat)
forecasttestY = inv_y[:, 0]
# calculate RMSE
actualtestY = values[n_train_hours:, 0]
rmse = sqrt(mean_squared_error(forecasttestY, actualtestY))
print('Test RMSE: %.3f' % rmse)
# plot the testY and actualtestY
ax = pyplot.subplot(122)
pyplot.plot(actualtestY, label='actual_y')
pyplot.plot(forecasttestY, label='prediction_y')
ax.yaxis.tick_right()
pyplot.legend()
pyplot.show()
评论18