Python時間序列LSTM預測系列教程(9)-多變數
阿新 • • 發佈:2019-01-10
# 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