Cainvas

Intent ClassificationĀ¶

Credit: AITS Cainvas Community

Photo by Jakub Jezovic šŸ¦” on Dribbble

InĀ [1]:
# get the data file
!wget -N https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/train.csv
--2021-07-14 15:08:10--  https://cainvas-static.s3.amazonaws.com/media/user_data/cainvas-admin/train.csv
Resolving cainvas-static.s3.amazonaws.com (cainvas-static.s3.amazonaws.com)... 52.219.160.59
Connecting to cainvas-static.s3.amazonaws.com (cainvas-static.s3.amazonaws.com)|52.219.160.59|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 441947 (432K) [text/csv]
Saving to: ā€˜train.csvā€™

train.csv           100%[===================>] 431.59K  --.-KB/s    in 0.005s  

2021-07-14 15:08:10 (88.6 MB/s) - ā€˜train.csvā€™ saved [441947/441947]

InĀ [2]:
# import the required libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import LSTM, Dense, Bidirectional, Dropout, Dense, Activation, Flatten, Embedding
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing import sequence
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential,Model,load_model
from tensorflow.keras.optimizers import SGD
InĀ [3]:
# read into csv file
df = pd.read_csv('train.csv')
df.head()
Out[3]:
sentence BookRestaurant GetWeather PlayMusic RateBook
0 book The Middle East restaurant in IN for noon 1 0 0 0
1 Book a table at T-Rex distant from Halsey St. 1 0 0 0
2 I'd like to eat at a taverna that serves chili... 1 0 0 0
3 I have a party of four in Japan and need a res... 1 0 0 0
4 Please make a restaurant reservation for somew... 1 0 0 0
InĀ [4]:
# shuffle data
df = shuffle(df)
df.head()
Out[4]:
sentence BookRestaurant GetWeather PlayMusic RateBook
6013 Rate the current series a one 0 0 0 1
4709 Play the playlist Grime Shutdown 0 0 1 0
5976 rate The Ape-Man Within 4 0 0 0 1
6814 rate the current essay three of 6\n points 0 0 0 1
6146 give Portions from a Wine-stained Notebook: Sh... 0 0 0 1
InĀ [5]:
X_train = df["sentence"].fillna("fillna").values
y_train = df[["BookRestaurant", "GetWeather", "PlayMusic", "RateBook"]].values
InĀ [6]:
X_train.shape, y_train.shape
Out[6]:
((7929,), (7929, 4))
InĀ [7]:
X_train[1], y_train[1] 
Out[7]:
('Play the playlist Grime Shutdown', array([0, 0, 1, 0]))

PreprocessingĀ¶

InĀ [8]:
text = X_train
InĀ [9]:
Tokenizer = Tokenizer()
InĀ [10]:
# text preprocessing
Tokenizer.fit_on_texts(text) 
Tokenizer_vocab_size = len(Tokenizer.word_index) + 1
Tokenizer_vocab_size
Out[10]:
7522
InĀ [11]:
X_train.shape, y_train.shape
Out[11]:
((7929,), (7929, 4))
InĀ [12]:
samples = 2500

X_train = X_train[samples:] 
y_train = y_train[samples:] 

X_val = X_train[:samples] 
y_val = y_train[:samples] 
InĀ [13]:
X_train.shape, y_train.shape
Out[13]:
((5429,), (5429, 4))
InĀ [14]:
X_train_encoded_words = Tokenizer.texts_to_sequences(X_train)
X_val_encoded_words = Tokenizer.texts_to_sequences(X_val)
InĀ [15]:
X_train_encoded_padded_words = sequence.pad_sequences(X_train_encoded_words, maxlen = 100)
X_val_encoded_padded_words = sequence.pad_sequences(X_val_encoded_words, maxlen = 100)

X_train_encoded_padded_words.shape, X_val_encoded_padded_words.shape
Out[15]:
((5429, 100), (2500, 100))
InĀ [16]:
X_val_encoded_padded_words, X_train_encoded_padded_words
Out[16]:
(array([[   0,    0,    0, ...,   94,   36,   32],
        [   0,    0,    0, ...,    3,    1,  304],
        [   0,    0,    0, ...,   23,    5,   11],
        ...,
        [   0,    0,    0, ...,    8,  239, 5753],
        [   0,    0,    0, ...,    3, 5754,  419],
        [   0,    0,    0, ...,   29,    4,   70]], dtype=int32),
 array([[  0,   0,   0, ...,  94,  36,  32],
        [  0,   0,   0, ...,   3,   1, 304],
        [  0,   0,   0, ...,  23,   5,  11],
        ...,
        [  0,   0,   0, ...,  23,   5,  11],
        [  0,   0,   0, ...,   5,  11,  32],
        [  0,   0,   0, ...,  78,   8, 466]], dtype=int32))
InĀ [17]:
y_train.shape, y_val.shape
Out[17]:
((5429, 4), (2500, 4))

Build and Train the ModelĀ¶

InĀ [18]:
model = Sequential()

model.add(Embedding(Tokenizer_vocab_size, 32, input_length = 100)) 

model.add(LSTM(10))
model.add(Dropout(0.5))
model.add(Dense(400, activation='relu'))
model.add(Dropout(0.5))
#model.add(Dense(200, activation='relu'))
#model.add(Dropout(0.5))
model.add(Dense(4, activation='softmax'))

model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, 100, 32)           240704    
_________________________________________________________________
lstm (LSTM)                  (None, 10)                1720      
_________________________________________________________________
dropout (Dropout)            (None, 10)                0         
_________________________________________________________________
dense (Dense)                (None, 400)               4400      
_________________________________________________________________
dropout_1 (Dropout)          (None, 400)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 4)                 1604      
=================================================================
Total params: 248,428
Trainable params: 248,428
Non-trainable params: 0
_________________________________________________________________
InĀ [19]:
Nadam = tf.keras.optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)
model.compile(loss='categorical_crossentropy', optimizer=Nadam, metrics=['accuracy'])
InĀ [20]:
history  = model.fit(X_train_encoded_padded_words,y_train, epochs = 3, batch_size=32, verbose=1, validation_data=(X_val_encoded_padded_words, y_val))
Epoch 1/3
170/170 [==============================] - 2s 10ms/step - loss: 0.4124 - accuracy: 0.8598 - val_loss: 0.0185 - val_accuracy: 0.9964
Epoch 2/3
170/170 [==============================] - 1s 7ms/step - loss: 0.0807 - accuracy: 0.9711 - val_loss: 0.0101 - val_accuracy: 0.9980
Epoch 3/3
170/170 [==============================] - 1s 7ms/step - loss: 0.0580 - accuracy: 0.9801 - val_loss: 0.0042 - val_accuracy: 0.9992
InĀ [21]:
# save the model
model.save("Intent_Classification.h5")

PlotsĀ¶

InĀ [22]:
#loss
from matplotlib import pyplot as plt
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.show()
InĀ [23]:
#accuracy
from matplotlib import pyplot as plt
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')
plt.show()

Loss and AccuracyĀ¶

InĀ [24]:
model.evaluate(X_val_encoded_padded_words, y_val)
79/79 [==============================] - 0s 2ms/step - loss: 0.0042 - accuracy: 0.9992
Out[24]:
[0.004162235651165247, 0.9991999864578247]

PredictionsĀ¶

InĀ [25]:
def predict(text):
    sentence = text
    tokens = Tokenizer.texts_to_sequences([text])
    tokens = pad_sequences(tokens, maxlen = 100)
    prediction = model.predict(np.array(tokens))
    pred = np.argmax(prediction)
    classes = ['BookRestaurant','GetWeather','PlayMusic','RateBook']
    result = classes[pred]
    return result
InĀ [26]:
predict("is it raining ?")
Out[26]:
'GetWeather'
InĀ [27]:
predict("i would like to book a table at hotel Orion for 29th june")
Out[27]:
'BookRestaurant'
InĀ [28]:
predict("An Artist released a new music album ")
Out[28]:
'PlayMusic'
InĀ [29]:
predict("this novel deserves a rating of 10")
Out[29]:
'RateBook'