<jupyter_start><jupyter_text>Importing libraries and downloading packages<jupyter_code>import nltk
import numpy as np
# downloading model to tokenize message
nltk.download('punkt')
# downloading stopwords
nltk.download('stopwords')
# downloading wordnet, which contains all lemmas of english language
nltk.download('wordnet')
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
stop_words = stopwords.words('english')

from nltk.stem import WordNetLemmatizer
stop_words<jupyter_output><empty_output><jupyter_text>Function to clean text<jupyter_code>def clean_corpus(corpus):
  # lowering every word in text
  corpus = [ doc.lower() for doc in corpus]
  cleaned_corpus = []
  
  stop_words = stopwords.words('english')
  wordnet_lemmatizer = WordNetLemmatizer()

  # iterating over every text
  for doc in corpus:
    # tokenizing text
    tokens = word_tokenize(doc)
    cleaned_sentence = [] 
    for token in tokens: 
      # removing stopwords, and punctuation
      if token not in stop_words and token.isalpha(): 
        # applying lemmatization
        cleaned_sentence.append(wordnet_lemmatizer.lemmatize(token)) 
    cleaned_corpus.append(' '.join(cleaned_sentence))
  return cleaned_corpus<jupyter_output><empty_output><jupyter_text>Loading and cleaning intents<jupyter_code>import json
with open('intents.json') as file:
    intents = json.load(file)
corpus = []
tags = []
for intent in intents['intents']:
    # taking all patterns in intents to train a neural network
    for pattern in intent['patterns']:
        corpus.append(pattern)
        tags.append(intent['tag'])
cleaned_corpus = clean_corpus(corpus)
cleaned_corpus<jupyter_output><empty_output><jupyter_text>Vectorizing intents<jupyter_code>from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(cleaned_corpus)
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()
y = encoder.fit_transform(np.array(tags).reshape(-1,1))<jupyter_output><empty_output><jupyter_text>Training neural network<jupyter_code>from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense, Dropout

model = Sequential([
                    Dense(128, input_shape=(X.shape[1],), activation='relu'),
                    Dropout(0.2),
                    Dense(64, activation='relu'),
                    Dropout(0.2),
                    Dense(y.shape[1], activation='softmax')
])

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.summary()
history = model.fit(X.toarray(), y.toarray(), epochs=20, batch_size=1)<jupyter_output>Epoch 1/20
41/41 [==============================] - 1s 1ms/step - loss: 2.0674 - accuracy: 0.1463
Epoch 2/20
41/41 [==============================] - 0s 1ms/step - loss: 1.9691 - accuracy: 0.3171
Epoch 3/20
41/41 [==============================] - 0s 2ms/step - loss: 1.8552 - accuracy: 0.3902
Epoch 4/20
41/41 [==============================] - 0s 2ms/step - loss: 1.6917 - accuracy: 0.6098
Epoch 5/20
41/41 [==============================] - 0s 2ms/step - loss: 1.5040 - accuracy: 0.6585
Epoch 6/20
41/41 [==============================] - 0s 1ms/step - loss: 1.3098 - accuracy: 0.8537
Epoch 7/20
41/41 [==============================] - 0s 2ms/step - loss: 1.1402 - accuracy: 0.8537
Epoch 8/20
41/41 [==============================] - 0s 2ms/step - loss: 0.8784 - accuracy: 0.9024
Epoch 9/20
41/41 [==============================] - 0s 2ms/step - loss: 0.7643 - accuracy: 0.9024
Epoch 10/20
41/41 [==============================] - 0s 2ms/step - loss: 0.5881 - accuracy: 0.9268
Epoch 11/20
41/41 [[...]<jupyter_text>Classifying messages to intent<jupyter_code># if prediction for every tag is low, then we want to classify that message as noanswer
INTENT_NOT_FOUND_THRESHOLD = 0.40

def predict_intent_tag(message):
  message = clean_corpus([message])
  X_test = vectorizer.transform(message)
  y = model.predict(X_test.toarray())
  # if probability of all intent is low, classify it as noanswer
  if y.max() < INTENT_NOT_FOUND_THRESHOLD:
    return 'noanswer'
  
  prediction = np.zeros_like(y[0])
  prediction[y.argmax()] = 1
  tag = encoder.inverse_transform([prediction])[0][0]
  return tag

print(predict_intent_tag('How you could help me?'))
print(predict_intent_tag('swiggy chat bot'))
print(predict_intent_tag('Where\'s my order'))

import random
import time 
def get_intent(tag):
  # to return complete intent from intent tag
  for intent in intents['intents']:
    if intent['tag'] == tag:
      return intent
def perform_action(action_code, intent):
  # funition to perform an action which is required by intent
  
  if action_code == 'CHECK_ORDER_STATUS':
    print('\n Checking database \n')
    time.sleep(2)
    order_status = ['in kitchen', 'with delivery executive']
    delivery_time = []
    return {'intent-tag':intent['next-intent-tag'][0],
            'order_status': random.choice(order_status),
            'delivery_time': random.randint(10, 30)}
  
  elif action_code == 'ORDER_CANCEL_CONFIRMATION':
    ch = input('BOT: Do you want to continue (Y/n) ?')
    if ch == 'y' or ch == 'Y':
      choice = 0
    else:
      choice = 1
    return {'intent-tag':intent['next-intent-tag'][choice]}
  
  elif action_code == 'ADD_DELIVERY_INSTRUCTIONS':
    instructions = input('Your Instructions: ')
    return {'intent-tag':intent['next-intent-tag'][0]}<jupyter_output><empty_output><jupyter_text>Complete chat bot<jupyter_code>while True:
  # get message from user
  message = input('You: ')
  # predict intent tag using trained neural network
  tag = predict_intent_tag(message)
  # get complete intent from intent tag
  intent = get_intent(tag)
  # generate random response from intent
  response = random.choice(intent['responses'])
  print('Bot: ', response)

  # check if there's a need to perform some action
  if 'action' in intent.keys():
    action_code = intent['action']
    # perform action
    data = perform_action(action_code, intent)
    # get follow up intent after performing action
    followup_intent = get_intent(data['intent-tag'])
    # generate random response from follow up intent
    response = random.choice(followup_intent['responses'])

    # print randomly selected response
    if len(data.keys()) > 1:
      print('Bot: ', response.format(**data))
    else:
      print('Bot: ', response)

  # break loop if intent was goodbye
  if tag == 'goodbye':
    break<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15824345146379046, 'fraction_numerical': 0.035747303543913714, 'mean_word_length': 4.303104575163399, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 7, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '176388', 'license': 'MIT', 'n_tokens_mistral': 2257, 'n_tokens_neox': 2069, 'n_words': 521, 'path': 'bot.ipynb', 'repo_name': 'rajat-saxena14/Swiggy-Chatbot', 'size': '6490'}