|
|
|
|
|
|
|
|
import numpy as np |
|
|
import tensorflow.compat.v1 as tf |
|
|
tf.disable_v2_behavior() |
|
|
import tflearn |
|
|
import random |
|
|
|
|
|
|
|
|
import nltk |
|
|
|
|
|
|
|
|
nltk.download('punkt') |
|
|
|
|
|
from nltk.stem.lancaster import LancasterStemmer |
|
|
stemmer = LancasterStemmer() |
|
|
|
|
|
|
|
|
import json |
|
|
import pickle |
|
|
import warnings |
|
|
warnings.filterwarnings("ignore") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Processing the Intents.....") |
|
|
with open('intents.json') as json_data: |
|
|
intents = json.load(json_data) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
words = [] |
|
|
classes = [] |
|
|
documents = [] |
|
|
ignore_words = ['?'] |
|
|
print("Looping through the Intents to Convert them to words, classes, documents and ignore_words.......") |
|
|
for intent in intents['intents']: |
|
|
for pattern in intent['patterns']: |
|
|
|
|
|
w = nltk.word_tokenize(pattern) |
|
|
|
|
|
words.extend(w) |
|
|
|
|
|
documents.append((w, intent['tag'])) |
|
|
|
|
|
if intent['tag'] not in classes: |
|
|
classes.append(intent['tag']) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Stemming, Lowering and Removing Duplicates.......") |
|
|
words = [stemmer.stem(w.lower()) for w in words if w not in ignore_words] |
|
|
words = sorted(list(set(words))) |
|
|
|
|
|
|
|
|
classes = sorted(list(set(classes))) |
|
|
|
|
|
print (len(documents), "documents") |
|
|
print (len(classes), "classes", classes) |
|
|
print (len(words), "unique stemmed words", words) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Creating the Data for our Model.....") |
|
|
training = [] |
|
|
output = [] |
|
|
print("Creating an List (Empty) for Output.....") |
|
|
output_empty = [0] * len(classes) |
|
|
|
|
|
print("Creating Training Set, Bag of Words for our Model....") |
|
|
for doc in documents: |
|
|
|
|
|
bag = [] |
|
|
|
|
|
pattern_words = doc[0] |
|
|
|
|
|
pattern_words = [stemmer.stem(word.lower()) for word in pattern_words] |
|
|
|
|
|
|
|
|
for w in words: |
|
|
bag.append(1) if w in pattern_words else bag.append(0) |
|
|
|
|
|
|
|
|
output_row = list(output_empty) |
|
|
output_row[classes.index(doc[1])] = 1 |
|
|
|
|
|
|
|
|
training.append((bag, output_row)) |
|
|
|
|
|
print("Shuffling Randomly and Converting into Numpy Array for Faster Processing......") |
|
|
random.shuffle(training) |
|
|
|
|
|
|
|
|
train_x = np.array([x[0] for x in training]) |
|
|
train_y = np.array([x[1] for x in training]) |
|
|
|
|
|
print("Creating Train and Test Lists.....") |
|
|
|
|
|
print("Building Neural Network for Our Chatbot to be Contextual....") |
|
|
print("Resetting graph data....") |
|
|
tf.reset_default_graph() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
net = tflearn.input_data(shape=[None, len(train_x[0])]) |
|
|
net = tflearn.fully_connected(net, 8) |
|
|
net = tflearn.fully_connected(net, 8) |
|
|
net = tflearn.fully_connected(net, len(train_y[0]), activation='softmax') |
|
|
net = tflearn.regression(net) |
|
|
print("Training....") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
model = tflearn.DNN(net, tensorboard_dir='tflearn_logs') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Training the Model.......") |
|
|
model.fit(train_x, train_y, n_epoch=1000, batch_size=8, show_metric=True) |
|
|
print("Saving the Model.......") |
|
|
model.save('model.tflearn') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Pickle is also Saved..........") |
|
|
|
|
|
pickle.dump( {'words':words, 'classes':classes, 'train_x':train_x, 'train_y':train_y}, open( "training_data", "wb" ) ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Loading Pickle.....") |
|
|
data = pickle.load( open( "training_data", "rb" ) ) |
|
|
words = data['words'] |
|
|
classes = data['classes'] |
|
|
train_x = data['train_x'] |
|
|
train_y = data['train_y'] |
|
|
|
|
|
|
|
|
with open('intents.json') as json_data: |
|
|
intents = json.load(json_data) |
|
|
|
|
|
print("Loading the Model......") |
|
|
|
|
|
model.load('./model.tflearn') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def clean_up_sentence(sentence): |
|
|
|
|
|
sentence_words = nltk.word_tokenize(sentence) |
|
|
|
|
|
sentence_words = [stemmer.stem(word.lower()) for word in sentence_words] |
|
|
return sentence_words |
|
|
|
|
|
|
|
|
def bow(sentence, words, show_details=False): |
|
|
sentence_words = clean_up_sentence(sentence) |
|
|
bag = [0]*len(words) |
|
|
for s in sentence_words: |
|
|
for i,w in enumerate(words): |
|
|
if w == s: |
|
|
bag[i] = 1 |
|
|
if show_details: |
|
|
print ("found in bag: %s" % w) |
|
|
return(np.array(bag)) |
|
|
|
|
|
ERROR_THRESHOLD = 0.25 |
|
|
print("ERROR_THRESHOLD = 0.25") |
|
|
|
|
|
def classify(sentence): |
|
|
|
|
|
results = model.predict([bow(sentence, words)])[0] |
|
|
|
|
|
results = [[i,r] for i,r in enumerate(results) if r>ERROR_THRESHOLD] |
|
|
|
|
|
results.sort(key=lambda x: x[1], reverse=True) |
|
|
return_list = [] |
|
|
for r in results: |
|
|
return_list.append((classes[r[0]], r[1])) |
|
|
return return_list |
|
|
|
|
|
def response(sentence, userID='123', show_details=False): |
|
|
results = classify(sentence) |
|
|
if results: |
|
|
while results: |
|
|
for i in intents['intents']: |
|
|
if i['tag'] == results[0][0]: |
|
|
|
|
|
return random.choice(i['responses']) |
|
|
results.pop(0) |
|
|
|
|
|
return "Sorry, I didn't understand that." |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def chatbot_response(message, chat_history=[]): |
|
|
|
|
|
response_text = f"Chatbot: {response(message)}" |
|
|
chat_history.append((input_text, response_text)) |
|
|
return response_text, chat_history |
|
|
|
|
|
|
|
|
interface = gr.Interface( |
|
|
fn=chatbot_response, |
|
|
inputs=[ |
|
|
gr.Textbox(lines=1, label="You"), |
|
|
gr.Chatbot(label="Chat History") |
|
|
], |
|
|
outputs=[ |
|
|
gr.Chatbot(label="Chat History") |
|
|
], |
|
|
title="Chatbot with History", |
|
|
) |
|
|
|
|
|
|
|
|
interface.launch() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|