Key Points
- Convert your timeseries data to the the matrix like a moving window, which has the exact number of inputs(n_steps_in) and outpus(n_steps_out) you defined.
- After trained model, here I defined to calculate mse for each out steps, and obviously, the more out steps I want to predict ,the large mse it is.
split a multivariate sequence into samples
1 | def split_sequence(sequence, n_steps_in, n_steps_out): |
2 | X, y = list(), list() |
3 | |
4 | for i in range(len(sequence)): |
5 | |
6 | #find the end of this pattern |
7 | end_ix = i + n_steps_in |
8 | out_end_ix = end_ix + n_steps_out |
9 | |
10 | #checkif we are beyond the dataset |
11 | if out_end_ix > len(sequence): |
12 | break |
13 | |
14 | #gather input and output parts of the pattern |
15 | seq_x, seq_y = sequence[i:end_ix], sequence[end_ix:out_end_ix] |
16 | X.append(seq_x) |
17 | y.append(seq_y) |
18 | |
19 | return np.array(X), np.array(y) |
20 | |
21 | #convert into input/output |
Train and fit LSTM Model
1 | def trainModel(n_steps_in, n_steps_out,model_train_X, model_train_y,model_test_X, model_test_y): |
2 | |
3 | #define model |
4 | n_features = 1 |
5 | |
6 | model = Sequential() |
7 | model.add(LSTM(100, activation = 'relu', return_sequences = True, input_shape = (n_steps_in, n_features))) |
8 | model.add(LSTM(100, activation = 'relu')) |
9 | model.add(Dropout(0.2)) |
10 | model.add(Dense(n_steps_out)) |
11 | model.compile(optimizer = 'adam', loss = 'mse') |
12 | |
13 | # fit model |
14 | history = model.fit(model_train_X, model_train_y, epochs = 50, verbose = 1, validation_data = (model_test_X, model_test_y)) |
15 | |
16 | plt.plot(history.history['loss'], label = 'train loss') |
17 | plt.plot(history.history['val_loss'], label = 'test loss') |
18 | plt.legend() |
19 | plt.show() |
20 | |
21 | return model |
Calculate MSE for each time step
1 | def train_mse(model, model_train_X,model_train_y,n_steps_out): |
2 | |
3 | yhat_t = model.predict(model_train_X) |
4 | train_y_out = [[] for i in range(n_steps_out)] |
5 | yhat_t_out = [[] for i in range(n_steps_out)] |
6 | mse = [[] for i in range(n_steps_out)] |
7 | |
8 | #get the result seperately from each step out |
9 | |
10 | for i in range(len(yhat_t)): |
11 | for k in range(n_steps_out): |
12 | yhat_t_out[k].append(yhat_t[i][k]) #get each yhat result from each step out |
13 | train_y_out[k].append(model_train_y[i][k]) #get each model result from each step out |
14 | |
15 | |
16 | #mse from each time step |
17 | for i in range(n_steps_out): |
18 | mse[i] = ((np.array(yhat_t_out[i]) - np.array(train_y_out[i]))**2).mean() |
19 | |
20 | |
21 | #plot yhat vs true value on every predicted day |
22 | |
23 | plt.figure(figsize=(8,4)) |
24 | for i in range(n_steps_out): |
25 | plt.subplot(n_steps_out, 1, i +1) |
26 | |
27 | pd.Series(train_y_out[i]).plot() |
28 | pd.Series(yhat_t_out[i]).plot() |
29 | |
30 | print('train_mse: ', mse) |
31 | plt.show() |