Python時間序列LSTM預測系列教程(9)-多變量

多變量LSTM預測模型(3)



前置教程:


定義&訓練模型


1、數據劃分成訓練和測試數據
本教程用第一年數據做訓練,剩餘4年數據做評估
2、輸入=1時間步長,8個feature
3、第一層隱藏層節點=50,輸出節點=1
4、用平均絕對誤差MAE做損失函數、Adam的隨機梯度下降做優化
5、epoch=50, batch_size=72

模型評估


1、預測後需要做逆縮放
2、用RMSE做評估

代碼解析

# coding=utf-8                                                                                                                                                                                   
from math import sqrt
from numpy import concatenate
from matplotlib import pyplot
from pandas import read_csv
from pandas import DataFrame
from pandas import concat
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
 
#轉成有監督數據
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    #數據序列(也將就是input)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names+=[('var%d(t-%d)'%(j+1, i)) for j in range(n_vars)]
    #預測數據(input對應的輸出值)
    for i in range(0, n_out, 1):
        cols.append(df.shift(-i))
        if i==0:
            names+=[('var%d(t)'%(j+1)) for j in range(n_vars)]
        else:
            names+=[('var%d(t+%d))'%(j+1, i)) for j in range(n_vars)]
    #拼接
    agg = concat(cols, axis=1)
    if dropnan:
        agg.dropna(inplace=True)
    return agg
 
#數據預處理
#--------------------------
dataset = read_csv('data_set/air_pollution_new.csv', header=0, index_col=0)
values = dataset.values
 
#標籤編碼
encoder = LabelEncoder()
values[:,4] = encoder.fit_transform(values[:,4])
#保證爲float
values = values.astype('float32')
#歸一化
 scaler = MinMaxScaler(feature_range=(0,1))
scaled = scaler.fit_transform(values)
#轉成有監督數據
reframed = series_to_supervised(scaled, 1, 1)
#刪除不預測的列
reframed.drop(reframed.columns[9:16], axis=1, inplace=True)
print reframed.head()
 
#數據準備
#--------------------------
values = reframed.values
n_train_hours = 365*24 #拿一年的時間長度訓練
#劃分訓練數據和測試數據
train = values[:n_train_hours, :]
test = values[n_train_hours:, :]
#拆分輸入輸出
train_x, train_y = train[:, :-1], train[:, -1]
test_x, test_y = test[:, :-1], test[:, -1]
#reshape輸入爲LSTM的輸入格式
train_x = train_x.reshape((train_x.shape[0], 1, train_x.shape[1]))
test_x = test_x.reshape((test_x.shape[0], 1, test_x.shape[1]))
print 'train_x.shape, train_y.shape, test_x.shape, test_y.shape'
print train_x.shape, train_y.shape, test_x.shape, test_y.shape
 
#模型定義
#-------------------------
model = Sequential()
model.add(LSTM(50, input_shape=(train_x.shape[1], train_x.shape[2])))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')
 
#模型訓練
#------------------------
history = model.fit(train_x, train_y, epochs=50, batch_size=72, validation_data=(test_x, test_y), verbose=2, shuffle=False)
 
#輸出
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='test')
pyplot.legend()
pyplot.show()
 
#預測
#------------------------
yhat = model.predict(test_x)
test_x = test_x.reshape(test_x.shape[0], test_x.shape[2])
#預測數據逆縮放
inv_yhat = concatenate((yhat, test_x[:, 1:]), axis=1)       
inv_yhat = scaler.inverse_transform(inv_yhat)
inv_yhat = inv_yhat[:, 0]
#真實數據逆縮放
test_y = test_y.reshape(len(test_y), 1)
inv_y = concatenate((test_y, test_x[:, 1:]), axis=1)
inv_y = scaler.inverse_transform(inv_y)
inv_y = inv_y[:, 0]
#計算rmse
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
print 'Test RMSE:%.3f'%rmse



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章