Time Series Forecasting using TensorFlow
By: Aryan Pegwar
Tags: Time Series Forecasting, AI, Deep Learning, TensorFlow, Machine Learning

Time Series represents the variation of an entity with respect to time. For example, you’ve probably heard of weather forecasting where we try to predict what will be weather conditions in future at a particular time, may on a day or a particular hour of the day. Other examples of a time series are the daily closing price of company stock, monthly rainfall data, and yearly sales figures etc.

I am providing the link for GitHub repository of the code used in this tutorial. https://github.com/aryan109/Sunspot_Prediction

Components of a Time Series

Trend

The trend shows the general tendency of the data to increase or decrease during a long period of time.

Periodic Fluctuations

There are some components in a time series which tend to repeat themselves over a certain period of time. They act in a regular spasmodic manner. these variations are of two types:-

a) Seasonal Variations: These are the rhythmic forces which operate in a regular and periodic manner over a span of less than a year.

b) Cyclic Variations: The variations in a time series which operate themselves over a span of more than one year are the cyclic variations.

periodic fluctuations with an uptrend

Random or Irregular Movements(Noise)

these are random or irregular variations that are unforeseen, uncontrollable, unpredictable, and erratic.

waveform of noise

Generally real word time series can have both trend and seasonality along with some white noise.

In this tutorial, we are going to do the sunspot prediction.

you are probably thinking “ What! sun also got spots???”

image showing a real sunspot.

Sunspots are areas that appear dark on the surface of the Sun. They appear dark because they are cooler than other parts of the Sun’s surface. The temperature of a sunspot is still very hot though — around 6,500 degrees Fahrenheit!

Sunspots are used to keep track of the solar cycle. The solar cycle is the cycle that the Sun’s magnetic field goes through approximately every 11 years.

Let’s Begin

Photo by Max Duzij on Unsplash

first, we need to download our time series data. here is the code to download the data in CSV format.

the downloaded CSV file will look something like this:

sunspot.csv

as you can see this file contain a total 3 columns, we will extract 1st and 3rd column into a NumPy array. we have chosen index column it will be easy to make predictions as we just need to give the index.

import csv

time_step = []

sunspots = [] with open(‘/tmp/sunspots.csv’) as csvfile:

reader = csv.reader(csvfile, delimiter=’,’)

next(reader)

for row in reader:

sunspots.append(float(row[2]))

time_step.append(int(row[0])) series = np.array(sunspots)

time = np.array(time_step)

print(‘series: {}’.format(series[:5]))

print(‘time: {}’.format(time[:5]))

let’s plot the series and see what it holds.

plt.figure(figsize=(10, 6))

plot_series(time, series)

Preparing Dataset

we have to split our time series into training and validation period.

split_time = 3000

time_train = time[:split_time]

x_train = series[:split_time]

time_valid = time[split_time:]

x_valid = series[split_time:]

the split time is 3000 means from 0 to 3000 will be for training and 3000 till the end is for validation.

now we will define a function to create a windowed dataset. In a window dataset, the previous n values could be seen as the input features. And the current value with any timestamp is the output label. window dataset consconsistsfixed window size.

def windowed_dataset(series, window_size, batch_size, shuffle_buffer):

series = tf.expand_dims(series, axis=-1)

ds = tf.data.Dataset.from_tensor_slices(series)

ds = ds.window(window_size + 1, shift=1, drop_remainder=True)

ds = ds.flat_map(lambda w: w.batch(window_size + 1))

ds = ds.shuffle(shuffle_buffer)

ds = ds.map(lambda w: (w[:-1], w[1:]))

return ds.batch(batch_size).prefetch(1)

now let’s create training dataset using windowed_dataset function

tf.keras.backend.clear_session()

tf.random.set_seed(51)

np.random.seed(51)

shuffle_buffer_size = 1000

window_size = 64

batch_size = 256

train_set = windowed_dataset(x_train, window_size, batch_size, shuffle_buffer_size)

print(x_train.shape)

Creating Model

tf.keras.backend.clear_session()

model = tf.keras.models.Sequential([

tf.keras.layers.Conv1D(filters=60, kernel_size=5,

strides=1, padding=”causal”,

activation=”relu”,

input_shape=[None, 1]),

tf.keras.layers.LSTM(60, return_sequences=True),

tf.keras.layers.LSTM(60, return_sequences=True),

tf.keras.layers.Dense(30, activation=”relu”),

tf.keras.layers.Dense(10, activation=”relu”),

tf.keras.layers.Dense(1),

tf.keras.layers.Lambda(lambda x: x * 400)

])

model.summary()

the summary of the model will look like this:

as you can see this model consist of Convolution layer, LSTM layer and Dense Layer. If you don’t know what these layers exactly do, don’t worry very soon I will create a separate article describing the functions of all different types of layers.

Now let’s compile and train the model

Photo by Roozbeh Eslami on Unsplash

optimizer = tf.keras.optimizers.SGD(lr=1e-5, momentum=0.9)

model.compile(loss=tf.keras.losses.Huber(),

optimizer=optimizer,

metrics=[“mae”])

history = model.fit(train_set,epochs=500)

and the training begins…..

the training will takes time so sit back and relax.

Evaluating the model

now we will see how good is our model by seeing the training loss

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

# Retrieve a list of list results on training and test data

# sets for each training epoch

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -

loss=history.history[‘loss’]

epochs=range(len(loss)) # Get number of epochs

# — — — — — — — — — — — — — — — — — — — — — — — —

# Plot training and validation loss per epoch

# — — — — — — — — — — — — — — — — — — — — — — — —

plt.plot(epochs, loss, ‘r’)

plt.title(‘Training loss’)

plt.xlabel(“Epochs”)

plt.ylabel(“Loss”)

plt.legend([“Loss”])

plt.figure() zoomed_loss = loss[200:]

zoomed_epochs = range(200,500)

# — — — — — — — — — — — — — — — — — — — — — — — —

# Plot training and validation loss per epoch

# — — — — — — — — — — — — — — — — — — — — — — — —

plt.plot(zoomed_epochs, zoomed_loss, ‘r’)

plt.title(‘Training loss’)

plt.xlabel(“Epochs”)

plt.ylabel(“Loss”)

plt.legend([“Loss”]) plt.figure()

the graphs should something similar to this.

The second plot is just zoomed last part of the first plot. Through this, we can get a clear status of training in last 300 epochs.

Let’s predict

now as your model is trained, be ready to see the future.

Photo by Elena Koycheva on Unsplash

we will create a function which will help us to do the prediction.

def model_forecast(model, series, window_size):

ds = tf.data.Dataset.from_tensor_slices(series)

ds = ds.window(window_size, shift=1, drop_remainder=True)

ds = ds.flat_map(lambda w: w.batch(window_size))

ds = ds.batch(32).prefetch(1)

forecast = model.predict(ds)

return forecast

now we will use this function to do forecast.

rnn_forecast = model_forecast(model, series[…, np.newaxis], window_size)

rnn_forecast = rnn_forecast[split_time — window_size:-1, -1, 0]

plt.figure(figsize=(10, 6))

plot_series(time_valid, x_valid)

plot_series(time_valid, rnn_forecast)

Blue is the original series and orange is predicted series, results are looking pretty good😃.

I hope you understand how to do Time Series Forecasting using TensorFlow.

please give your feedback or suggestions. Thank You🙂