It’s a Time-Series Story (CNN application)



Original Source Here

Practical Example

The dataset used is based on the occupancy of a room in a hotel. In this examples different sensors are used to detect if the guests are in the room or not. The purpose is to know wether someone is still in its room after checkout.

Data Preparation

First, we need to pre-process the data, it is very important to have our dataset as numpy arrays, therefore the following code is used

#####TRAIN
in_seq1_train = np.array(dataset_train[['Temperature']])
in_seq2_train = np.array(dataset_train[['Humidity']])
in_seq3_train = np.array(dataset_train[['Light']])
in_seq4_train = np.array(dataset_train[['CO2']])
in_seq5_train = np.array(dataset_train[['HumidityRatio']])
out_seq_train = np.array(dataset_train[['Occupancy']])
#Convert to [rows, columns] structure
in_seq1_train = in_seq1_train.reshape((len(in_seq1_train), 1))
in_seq2_train = in_seq2_train.reshape((len(in_seq2_train), 1))
in_seq3_train = in_seq3_train.reshape((len(in_seq3_train), 1))
in_seq4_train = in_seq4_train.reshape((len(in_seq4_train), 1))
in_seq5_train = in_seq5_train.reshape((len(in_seq5_train), 1))
out_seq_train = out_seq_train.reshape((len(out_seq_train), 1))

#####TEST
in_seq1_test = np.array(dataset_test[['Temperature']])
in_seq2_test = np.array(dataset_test[['Humidity']])
in_seq3_test = np.array(dataset_test[['Light']])
in_seq4_test = np.array(dataset_test[['CO2']])
in_seq5_test = np.array(dataset_test[['HumidityRatio']])
out_seq_test = np.array(dataset_test[['Occupancy']])
#Convert to [rows, columns] structure
in_seq1_test = in_seq1_test.reshape((len(in_seq1_test), 1))
in_seq2_test = in_seq2_test.reshape((len(in_seq2_test), 1))
in_seq3_test = in_seq3_test.reshape((len(in_seq3_test), 1))
in_seq4_test = in_seq4_test.reshape((len(in_seq4_test), 1))
in_seq5_test = in_seq5_test.reshape((len(in_seq5_test), 1))
out_seq_test = out_seq_test.reshape((len(out_seq_test), 1))

Join data arrays and stack them horizontally.

#Horizontally stack columns
#Dataframe*****
dataset_train = hstack((in_seq1_train, in_seq2_train, in_seq3_train, in_seq4_train, in_seq5_train, out_seq_train))
dataset_test = hstack((in_seq1_test, in_seq2_test, in_seq3_test, in_seq4_test, in_seq5_test, out_seq_test))

Next, we need to give shape to our data, CNNs model need a specific input shape so it analizes our data. Failing to give the right shape the model will not work. Moreover, the next code defines a function that receives the number of time steps as an input, with this we give the following shape to our data: #Shape = (8139,5,5)(8139,)
#(Rows, timestamps, features)(rows)

*In this example we choose 5 as the number of time steps to be considered. However, this number can be changed depending on the users’ needs.

################# Data Shaping#Choose a number of time steps (timestamps)
#this gives shape to the matrix that will be analized
#Defines number of rows
n_steps = 5
#Split into samples
#This split helps in dividing the X and y in the matrix that will be put in
#the CNN
def split_sequences(sequences, n_steps):
X, y = list(), list()
for i in range(len(sequences)):
# find the end of this pattern
end_ix = i + n_steps
# check if we are beyond the dataset
if end_ix > len(sequences):
break
# gather input and output parts of the pattern
seq_x, seq_y = sequences[i:end_ix, :-1], sequences[end_ix-1, -1]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)

Now, we apply the function to our train and test sets:

# Retrieves train and test sets AND gives the optimal shape for the 1D CNN
X_train, y_train = split_sequences(dataset_train, n_steps)
X_test, y_test = split_sequences(dataset_test, n_steps)
# Retrieve the number of columns that equals the number of features
#(predictors)
n_features = X_train.shape[1]
print(n_features)
#5
print(X_train.shape, y_train.shape)
#Shape = (8139,5,5)(8139,)
#(Rows, timestamps, features)(rows)

Model Build-Up

Now we define our CNN architecture. This model is a classification model that aims to predict if a room is empty (0) or vacant (1), to achieve this we use an activation function: sigmoid in our last layer to define our binary classification.

################### CNN Modelling#Define model
cnn = tf.keras.models.Sequential()
#Input and hidden layers
#In this layer we create feature maps that detect the most relevant data
#Input_shape: Usually in CNN this parameter is used to define the shape of
#the images to be analized in our case this is the size of our dataframes
cnn.add(tf.keras.layers.Conv1D(filters=64,
kernel_size=2,
activation='relu',
input_shape=(n_steps, n_features)))
#Max pooling layer heps the model to try to not to overfit the data
#We use a pool_size = 2
cnn.add(tf.keras.layers.MaxPooling1D(pool_size=2))
#This layer converts the matrix into a array
cnn.add(tf.keras.layers.Flatten())
#Hidden Layer
cnn.add(tf.keras.layers.Dense(units=3, activation='relu'))
#Output layer
#This layer determines the probability of a room being occupied or not.
#We use one unit (node) because we have a binary variable
#We use sigmoid function to determine the probability of binary variables
cnn.add(tf.keras.layers.Dense(units=1, activation='sigmoid'))
#Compile Model
#We use the binary crossentropy as we have a binary classification
cnn.compile(optimizer = 'adam',
loss = 'binary_crossentropy',
metrics = ['accuracy'])

Next, we need to train and predict the results of our model.

################# Training#Training the model 
start = timeit.default_timer()
cnn.fit(X_train, y_train, epochs=100)
stop = timeit.default_timer()
print('Time: ', stop - start)

################# Prediction
#Here we predict the probabilities with the whole X_test
y_pred = cnn.predict(X_test)
y_pred_trans=np.round(y_pred,0)

Finally, we measure the accuracy of our model by using an accuracy score and a confusion matrix.

#Accuracy calculation
#Finally, we determine the accuracy of our model with a confusion matrix, accuracy, recall and precision score
from sklearn.metrics import confusion_matrix, accuracy_score, recall_score, precision_score
cm = confusion_matrix(y_test, y_pred_trans)
print("Confusion matrix: ")
print(cm)
print("Accuracy: ",round(accuracy_score(y_test, y_pred_trans), 3))
print("Precision: ",round(precision_score(y_test, y_pred_trans), 3))
print("Recall: ",round(recall_score(y_test, y_pred_trans),3))

Conclusion

Our model scores a 0.97 accuracy with a precision of 0.94 and a recall of 0.99, with the following confusion matrix.

[[1639   54]
[ 6 962]]

We can conclude out of this example that CNN can be useful to solve other type of problems and not just image recognition. Although RNNs are more commonly used for this type of problems, CNNs offer a different approach of solving problems.

AI/ML

Trending AI/ML Article Identified & Digested via Granola by Ramsey Elbasheer; a Machine-Driven RSS Bot

%d bloggers like this: