1
+ #!/usr/bin/env python
2
+
3
+ import matplotlib .pyplot as plt
4
+ import pandas as pd
5
+ from dataset import load_date_series , timeseries_to_supervised , difference , inverse_difference , scale , invert_scale
6
+ from keras .models import Sequential
7
+ from keras .layers import Dense
8
+ from keras .layers import LSTM
9
+ from math import sqrt
10
+ from sklearn .metrics import mean_squared_error as mse
11
+
12
+ # fit an LSTM network to training data
13
+ def fit_lstm (train , batch_size , nb_epoch , neurons ):
14
+ X , y = train [:, 0 :- 1 ], train [:, - 1 ]
15
+ X = X .reshape (X .shape [0 ], 1 , X .shape [1 ])
16
+ model = Sequential ()
17
+ model .add (LSTM (neurons , batch_input_shape = (batch_size , X .shape [1 ], X .shape [2 ]), stateful = True ))
18
+ model .add (Dense (1 ))
19
+ model .compile (loss = 'mean_squared_error' , optimizer = 'adam' )
20
+ for i in range (nb_epoch ):
21
+ model .fit (X , y , epochs = 1 , batch_size = batch_size , verbose = 0 , shuffle = False )
22
+ model .reset_states ()
23
+ return model
24
+
25
+ # make a one-step forecast
26
+ def forecast_lstm (model , batch_size , X ):
27
+ X = X .reshape (1 , 1 , len (X ))
28
+ yhat = model .predict (X , batch_size = batch_size )
29
+ return yhat [0 ,0 ]
30
+
31
+ def prepare_model ():
32
+ # Convert series into supervised learning problem
33
+ series = load_date_series ()
34
+ X = series .values
35
+ supervised = timeseries_to_supervised (X , 1 )
36
+ print ("*** Supervised Learning ***" )
37
+ print (supervised .head ())
38
+
39
+ # Convert time series to stationary
40
+ differenced = difference (series , 1 )
41
+ print ("*** Stationary Data Set ***" )
42
+ print (differenced .head ())
43
+ # invert transform
44
+ inverted = list ()
45
+ for i in range (len (differenced )):
46
+ value = inverse_difference (series , differenced [i ], len (series )- i )
47
+ inverted .append (value )
48
+ inverted = pd .Series (inverted )
49
+ print (inverted .head ())
50
+
51
+ # Scale time series
52
+ scaler , scaled_X = scale (series )
53
+ scaled_series = pd .Series (scaled_X [:, 0 ])
54
+ print ("*** Scaled Time Series ***" )
55
+ print (scaled_series .head ())
56
+ # invert transform
57
+ inverted_X = scaler .inverse_transform (scaled_X )
58
+ inverted_series = pd .Series (inverted_X [:, 0 ])
59
+ print (inverted_series .head ())
60
+
61
+ def model (series ):
62
+ # transform data to be stationary
63
+ raw_values = series .values
64
+ diff_values = difference (raw_values , 1 )
65
+
66
+ # transform data to be supervised learning
67
+ supervised = timeseries_to_supervised (diff_values , 1 )
68
+ supervised_values = supervised .values
69
+
70
+ # split data into train and test-sets
71
+ train , test = supervised_values [0 :- 12 ], supervised_values [- 12 :]
72
+
73
+ # transform the scale of the data
74
+ scaler , train_scaled , test_scaled = scale (train , test )
75
+
76
+ # fit the model
77
+ lstm_model = fit_lstm (train_scaled , 1 , 3000 , 4 )
78
+ # forecast the entire training dataset to build up state for forecasting
79
+ train_reshaped = train_scaled [:, 0 ].reshape (len (train_scaled ), 1 , 1 )
80
+ lstm_model .predict (train_reshaped , batch_size = 1 )
81
+
82
+ # walk-forward validation on the test data
83
+ predictions = list ()
84
+ for i in range (len (test_scaled )):
85
+ # make one-step forecast
86
+ X , y = test_scaled [i , 0 :- 1 ], test_scaled [i , - 1 ]
87
+ yhat = forecast_lstm (lstm_model , 1 , X )
88
+ # invert scaling
89
+ yhat = invert_scale (scaler , X , yhat )
90
+ # invert differencing
91
+ yhat = inverse_difference (raw_values , yhat , len (test_scaled )+ 1 - i )
92
+ # store forecast
93
+ predictions .append (yhat )
94
+ expected = raw_values [len (train ) + i + 1 ]
95
+ print ('Month=%d, Predicted=%f, Expected=%f' % (i + 1 , yhat , expected ))
96
+
97
+ # report performance
98
+ rmse = sqrt (mse (raw_values [- 12 :], predictions ))
99
+ print ('Test RMSE: %.3f' % rmse )
100
+ # line plot of observed vs predicted
101
+ plt .plot (raw_values [- 12 :])
102
+ plt .plot (predictions )
103
+ plt .show ()
104
+
105
+ series = load_date_series ()
106
+ model (series )
0 commit comments