Applied Data Science Notebook in Python for Beginners to Professionals

Data Science Project – A Guide to Deep Learning (LSTM) Hyperparameters tuning with Keras for Time Series Forecasting in Python

Machine Learning for Beginners - A Guide to Deep Learning (LSTM) Hyperparameters tuning with Keras for Time Series Forecasting in Python

For more projects visit: https://setscholars.net

  • There are 5000+ free end-to-end applied machine learning and data science projects available to download at SETSscholar. SETScholars is a Science, Engineering and Technology Scholars community.
In [15]:
# Suppress warnings in Jupyter Notebooks
import warnings
warnings.filterwarnings("ignore")

import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

In this notebook, we will learn how to do Deep Learning (LSTM) Hyperparameters tuning with Keras for Time Series Forecasting in Python.

Python Codes

Load the dataset

In [16]:
from pandas import read_csv
from matplotlib import pyplot

series = read_csv('shampoo.csv', header=0, index_col=0)

print(series.head())

series.plot(figsize = (15,8))
pyplot.show()
       Sales
Month       
1-01   266.0
1-02   145.9
1-03   183.1
1-04   119.3
1-05   180.3
In [ ]:
 

Deep Learning (LSTM) model hyperparameters tuning with Keras for Time Series Forecasting in Python

In [17]:
from pandas import DataFrame
from pandas import Series
from pandas import concat
from pandas import read_csv
from pandas import datetime
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from math import sqrt
import matplotlib
# be able to save images on server
matplotlib.use('Agg')
from matplotlib import pyplot
import numpy
In [18]:
# date-time parsing function for loading the dataset
def parser(x):
    return datetime.strptime('190'+x, '%Y-%m')
In [19]:
# frame a sequence as a supervised learning problem
def timeseries_to_supervised(data, lag=1):
    df = DataFrame(data)
    columns = [df.shift(i) for i in range(1, lag+1)]
    columns.append(df)
    df = concat(columns, axis=1)
    df = df.drop(0)
    
    return df
In [20]:
# create a differenced series
def difference(dataset, interval=1):
    diff = list()
    for i in range(interval, len(dataset)):
        value = dataset[i] - dataset[i - interval]
        diff.append(value)
    
    return Series(diff)
In [21]:
# invert differenced value
def inverse_difference(history, yhat, interval=1):
    return yhat + history[-interval]
In [22]:
# scale train and test data to [-1, 1]
def scale(train, test):
    # fit scaler
    scaler = MinMaxScaler(feature_range=(-1, 1))
    scaler = scaler.fit(train)
    
    # transform train
    train = train.reshape(train.shape[0], train.shape[1])
    train_scaled = scaler.transform(train)
    
    # transform test
    test = test.reshape(test.shape[0], test.shape[1])
    test_scaled = scaler.transform(test)
    
    return scaler, train_scaled, test_scaled
In [23]:
# inverse scaling for a forecasted value
def invert_scale(scaler, X, yhat):
    new_row = [x for x in X] + [yhat]
    array = numpy.array(new_row)
    array = array.reshape(1, len(array))
    inverted = scaler.inverse_transform(array)
    
    return inverted[0, -1]
In [24]:
# fit an LSTM network to training data
def fit_lstm(train, batch_size, nb_epoch, neurons):
    X, y = train[:, 0:-1], train[:, -1]
    X = X.reshape(X.shape[0], 1, X.shape[1])
    
    model = Sequential()
    model.add(LSTM(neurons, batch_input_shape=(batch_size, X.shape[1], X.shape[2]), stateful=True))
    model.add(Dense(1))
    model.compile(loss='mean_squared_error', optimizer='adam')
    
    for i in range(nb_epoch):
        model.fit(X, y, epochs=1, batch_size=batch_size, verbose=0, shuffle=False)
        model.reset_states()
    
    return model
In [29]:
# run a repeated experiment
def experiment(repeats, series, epochs):
    
    # transform data to be stationary
    raw_values = series.values
    diff_values = difference(raw_values, 1)
    
    # transform data to be supervised learning
    supervised = timeseries_to_supervised(diff_values, 1)
    supervised_values = supervised.values
    
    # split data into train and test-sets
    train, test = supervised_values[0:-12], supervised_values[-12:]
    
    # transform the scale of the data
    scaler, train_scaled, test_scaled = scale(train, test)
    
    # run experiment
    error_scores = list()
    
    print(); print("Number of epochs used as hyperparameters: ", epochs)
    for r in range(repeats):
        # fit the model
        batch_size = 4
        train_trimmed = train_scaled[2:, :]
        lstm_model = fit_lstm(train_trimmed, batch_size, epochs, 1)
        
        # forecast the entire training dataset to build up state for forecasting
        train_reshaped = train_trimmed[:, 0].reshape(len(train_trimmed), 1, 1)
        lstm_model.predict(train_reshaped, batch_size=batch_size)
        
        # forecast test dataset
        test_reshaped = test_scaled[:,0:-1]
        test_reshaped = test_reshaped.reshape(len(test_reshaped), 1, 1)
        output = lstm_model.predict(test_reshaped, batch_size=batch_size)
        predictions = list()
        
        for i in range(len(output)):
            yhat = output[i,0]
            X = test_scaled[i, 0:-1]
            
            # invert scaling
            yhat = invert_scale(scaler, X, yhat)
            
            # invert differencing
            yhat = inverse_difference(raw_values, yhat, len(test_scaled)+1-i)
            
            # store forecast
            predictions.append(yhat)
        
        # report performance
        rmse = sqrt(mean_squared_error(raw_values[-12:], predictions))
        
        print('%d) Test RMSE: %.3f' % (r+1, rmse))
        error_scores.append(rmse)
    
    return error_scores
In [30]:
# load dataset
series = read_csv('shampoo.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)

# experiment
repeats = 30
results = DataFrame()

# vary training epochs
epochs = [500, 1000, 2000, 4000, 6000]
for e in epochs:
    results[str(e)] = experiment(repeats, series, e)
    
# summarize results
print(results.describe())

# save boxplot
results.boxplot(figsize=(14,10))
pyplot.show()
Number of epochs used as hyperparameters:  500
1) Test RMSE: 102.435
2) Test RMSE: 127.627
3) Test RMSE: 92.849
4) Test RMSE: 96.495
5) Test RMSE: 121.269
6) Test RMSE: 133.893
7) Test RMSE: 95.117
8) Test RMSE: 86.962
9) Test RMSE: 98.888
10) Test RMSE: 102.110
11) Test RMSE: 118.674
12) Test RMSE: 104.430
13) Test RMSE: 124.448
14) Test RMSE: 115.920
15) Test RMSE: 92.247
16) Test RMSE: 101.109
17) Test RMSE: 98.735
18) Test RMSE: 105.164
19) Test RMSE: 101.581
20) Test RMSE: 123.006
21) Test RMSE: 117.663
22) Test RMSE: 95.668
23) Test RMSE: 118.840
24) Test RMSE: 127.439
25) Test RMSE: 101.509
26) Test RMSE: 126.339
27) Test RMSE: 115.297
28) Test RMSE: 127.782
29) Test RMSE: 115.706
30) Test RMSE: 119.673

Number of epochs used as hyperparameters:  1000
1) Test RMSE: 87.741
2) Test RMSE: 113.043
3) Test RMSE: 102.278
4) Test RMSE: 121.797
5) Test RMSE: 136.487
6) Test RMSE: 94.739
7) Test RMSE: 100.180
8) Test RMSE: 88.272
9) Test RMSE: 93.618
10) Test RMSE: 102.604
11) Test RMSE: 98.242
12) Test RMSE: 101.630
13) Test RMSE: 87.115
14) Test RMSE: 93.884
15) Test RMSE: 118.861
16) Test RMSE: 105.387
17) Test RMSE: 103.130
18) Test RMSE: 130.410
19) Test RMSE: 122.610
20) Test RMSE: 95.165
21) Test RMSE: 91.327
22) Test RMSE: 98.315
23) Test RMSE: 91.839
24) Test RMSE: 115.392
25) Test RMSE: 104.198
26) Test RMSE: 90.129
27) Test RMSE: 97.035
28) Test RMSE: 91.076
29) Test RMSE: 96.046
30) Test RMSE: 95.705

Number of epochs used as hyperparameters:  2000
1) Test RMSE: 87.165
2) Test RMSE: 94.528
3) Test RMSE: 110.591
4) Test RMSE: 104.685
5) Test RMSE: 92.742
6) Test RMSE: 84.711
7) Test RMSE: 87.209
8) Test RMSE: 120.801
9) Test RMSE: 120.452
10) Test RMSE: 99.372
11) Test RMSE: 84.289
12) Test RMSE: 96.528
13) Test RMSE: 123.765
14) Test RMSE: 98.392
15) Test RMSE: 90.195
16) Test RMSE: 90.820
17) Test RMSE: 101.258
18) Test RMSE: 87.904
19) Test RMSE: 94.431
20) Test RMSE: 119.550
21) Test RMSE: 93.740
22) Test RMSE: 129.588
23) Test RMSE: 95.825
24) Test RMSE: 94.428
25) Test RMSE: 96.136
26) Test RMSE: 96.298
27) Test RMSE: 90.718
28) Test RMSE: 92.928
29) Test RMSE: 134.982
30) Test RMSE: 92.795

Number of epochs used as hyperparameters:  4000
1) Test RMSE: 89.875
2) Test RMSE: 93.229
3) Test RMSE: 81.937
4) Test RMSE: 92.090
5) Test RMSE: 103.688
6) Test RMSE: 120.320
7) Test RMSE: 146.295
8) Test RMSE: 93.223
9) Test RMSE: 91.529
10) Test RMSE: 124.117
11) Test RMSE: 85.691
12) Test RMSE: 93.889
13) Test RMSE: 91.956
14) Test RMSE: 94.002
15) Test RMSE: 118.075
16) Test RMSE: 129.375
17) Test RMSE: 93.829
18) Test RMSE: 139.493
19) Test RMSE: 81.839
20) Test RMSE: 82.815
21) Test RMSE: 132.761
22) Test RMSE: 81.559
23) Test RMSE: 89.983
24) Test RMSE: 82.104
25) Test RMSE: 93.409
26) Test RMSE: 92.759
27) Test RMSE: 93.126
28) Test RMSE: 129.220
29) Test RMSE: 93.916
30) Test RMSE: 92.920

Number of epochs used as hyperparameters:  6000
1) Test RMSE: 91.797
2) Test RMSE: 80.447
3) Test RMSE: 79.585
4) Test RMSE: 93.215
5) Test RMSE: 92.466
6) Test RMSE: 94.197
7) Test RMSE: 76.771
8) Test RMSE: 91.647
9) Test RMSE: 78.316
10) Test RMSE: 133.182
11) Test RMSE: 95.090
12) Test RMSE: 92.028
13) Test RMSE: 94.289
14) Test RMSE: 141.924
15) Test RMSE: 80.690
16) Test RMSE: 145.293
17) Test RMSE: 138.915
18) Test RMSE: 91.202
19) Test RMSE: 93.000
20) Test RMSE: 92.414
21) Test RMSE: 79.631
22) Test RMSE: 94.143
23) Test RMSE: 88.429
24) Test RMSE: 133.633
25) Test RMSE: 78.836
26) Test RMSE: 93.707
27) Test RMSE: 92.402
28) Test RMSE: 91.435
29) Test RMSE: 89.922
30) Test RMSE: 90.844
              500        1000        2000        4000        6000
count   30.000000   30.000000   30.000000   30.000000   30.000000
mean   110.295872  102.275111  100.227508  100.967468   96.981623
std     13.219774   12.961160   13.896108   18.984205   19.852007
min     86.962367   87.115153   84.289141   81.558674   76.770615
25%     99.443008   93.684430   91.300198   90.369684   88.802444
50%    110.230705   98.278486   95.176389   93.225918   92.214862
75%    120.869897  105.089551  103.827999  114.477983   94.183174
max    133.892907  136.486808  134.981664  146.295414  145.292796
In [ ]:
 

Summary

In this coding recipe, we discussed how to do Deep Learning (LSTM) Hyperparameters tuning with Keras for Time Series Forecasting in Python

Specifically, we have learned the followings:

  • How to do Deep Learning (LSTM) Hyperparameters tuning with Keras for Time Series Forecasting in Python.
In [ ]: