How To Make A Chatbot In Python? A Step-by-Step Guide

What is Chatbot in Python?

A chatbot in Python is a piece of software that uses AI to talk to people in their own languages. Most of the time, these chatbots talk through sound or text, and they can easily imitate human languages to talk to people in a way that seems natural.

Rule-based training teaches a chatbot to answer questions based on a set of rules that were given to it at the beginning of its training.

These rules can be very simple or very hard to understand.

Rule-based chatbots are good at answering simple questions, but they usually can’t handle more complicated questions or requests.

Chatbot in Today’s Generation

Today, we have smart Chatbots that are powered by AI and use natural language processing (NLP) to understand text and voice commands from humans and learn from their past interactions.

Chatbots have become a standard way for companies and brands with an online presence to talk to their customers (website and social network platforms).

Python-based chatbots are a useful tool because they let the brand and the customer talk to each other right away. Think about Siri from Apple, Alexa from Amazon, and Cortana from Microsoft.

Chatbot Benefits For Business

When it comes to making good customer relationships, chatbots can be a very useful tool.

Your business can use it to build strong connections with website visitors by getting to know them and talking to them.

By using chatbots, you can not only reach your marketing goals but also make more sales and give better customer service.

There are many ways a chatbot can improve how you talk to customers and help your business grow:

  • Increase Customer Engagement
  • Improve Lead Generation
  • Reduce Customer Service Costs
  • Monitor Consumer Data to Gain Insights
  • Devise a Conversational Marketing Strategy
  • Balance Automation with Human Touch
  • Meet Customer Expectations
  • Achieve Scalability of Support
  • Streamline Your Customer Onboarding Process
  • Make the Customer Journey Smoother

How To Make A Chatbot In Python?

We will go through the process of building a Python chatbot step by step.

We’re going to use deep learning techniques to build a chatbot. The chatbot will learn from the dataset, which has categories (intended uses), patterns, and answers.

We use a special recurrent neural network (LSTM) to figure out which category the user’s message fits into, and then we pick a random response from the list of responses.

Now we’ll use Python to build the chatbot, but first, let’s look at how the files will be organized and what kinds of files we’ll be making:

  • Intents.json – The data file which has predefined patterns and responses.
  • train_chatbot.py – In this Python file, we wrote a script to build the model and train our chatbot.
  • Words.pkl – This is a pickle file in which we store the words Python object that contains a list of our vocabulary.
  • Classes.pkl – The classes pickle file contains the list of categories.
  • Chatbot_model.h5 – This is the trained model that contains information about the model and has the weights of the neurons.
  • Chatgui.py – This is the Python script in which we implemented GUI for our chatbot. Users can easily interact with the bot.

Chatbot Project in Python with Source Code

Here are The Steps To Create a Chatbot in Python From Scratch:

  1. Import and load the data file
  2. Preprocess data
  3. Create training and testing data
  4. Build the model
  5. Predict the response

1. Import and load the data file

First, you need to make a file called train_chatbot.py. We bring in the packages our chatbot needs and set up the variables we will use in our Python project.

The data file is in the JSON format, so we used the json package to read the JSON file into Python.

import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
import json
import pickle
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout
from keras.optimizers import SGD
from tensorflow.keras.optimizers import SGD
import random
words=[]
classes = []
documents = []
ignore_words = ['?', '!']
data_file = open('intents.json').read()
intents = json.loads(data_file)

2. Preprocess Data

Before we can make a machine learning or deep learning model from text data, we have to process the data in different ways. Depending on the needs, we have to use different operations to preprocess the data.

Tokenizing text data is the first and most basic thing you can do with it. Tokenizing is the process of breaking a text into small pieces, like words.

Here, we go through the patterns, use the nltk.word_tokenize() function to break the sentence into words and add each word to the word list. We also make a list of the classes our tags belong to.

for intent in intents['intents']:
    for pattern in intent['patterns']:
        #tokenize each word
        w = nltk.word_tokenize(pattern)
        words.extend(w)
        #add documents in the corpus
        documents.append((w, intent['tag']))
        # add to our classes list
        if intent['tag'] not in classes:
            classes.append(intent['tag'])

Now, we’ll figure out what each word means and get rid of any words that are already on the list.

Lemmatizing is the process of changing a word into its lemma form and then making a pickle file to store the Python objects we will use when predicting.

# lemmatize, lower each word and remove duplicates
words = [lemmatizer.lemmatize(w.lower()) for w in words if w not in ignore_words]
words = sorted(list(set(words)))
# sort classes
classes = sorted(list(set(classes)))
# documents = combination between patterns and intents
print (len(documents), "documents")
# classes = intents
print (len(classes), "classes", classes)
# words = all words, vocabulary
print (len(words), "unique lemmatized words", words)
pickle.dump(words,open('words.pkl','wb'))
pickle.dump(classes,open('classes.pkl','wb'))

3. Create Training and Testing Data

Now, we’ll make the training data, which will include both the inputs and outputs. The pattern will be our input, and the class that the pattern belongs to will be our output.

But the computer can’t read words, so we’ll turn the words into numbers.

# create our training data
training = []
# create an empty array for our output
output_empty = [0] * len(classes)
# training set, bag of words for each sentence
for doc in documents:
    # initialize our bag of words
    bag = []
    # list of tokenized words for the pattern
    pattern_words = doc[0]
    # lemmatize each word - create base word, in attempt to represent related words
    pattern_words = [lemmatizer.lemmatize(word.lower()) for word in pattern_words]
    # create our bag of words array with 1, if word match found in current pattern
    for w in words:
        bag.append(1) if w in pattern_words else bag.append(0)
    # output is a '0' for each tag and '1' for current tag (for each pattern)
    output_row = list(output_empty)
    output_row[classes.index(doc[1])] = 1
    training.append([bag, output_row])
# shuffle our features and turn into np.array
random.shuffle(training)
training = np.array(training)
# create train and test lists. X - patterns, Y - intents
train_x = list(training[:,0])
train_y = list(training[:,1])
print("Training data created")

4. Build The Model

Now that our training data is ready, we will build a 3-layer deep neural network. We do this with the Keras sequential API.

After training the model for 200 iterations, it was 100% accurate. Let’s name the file “chatbot model.h5” and save it.

# Create model - 3 layers. First layer 128 neurons, second layer 64 neurons and 3rd output layer contains number of neurons
# equal to number of intents to predict output intent with softmax
model = Sequential()
model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(len(train_y[0]), activation='softmax'))
# Compile model. Stochastic gradient descent with Nesterov accelerated gradient gives good results for this model
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
#fitting and saving the model
hist = model.fit(np.array(train_x), np.array(train_y), epochs=200, batch_size=5, verbose=1)
model.save('chatbot_model.h5', hist)
print("model created")

5. Predict the response (Graphical User Interface (GUI))

To predict the sentences and get a response from the user to let us create a new file named “chatapp.py.”

We will load the trained model and then use a graphical user interface to predict the bot’s response.

The model will only tell us what class it belongs to, so we will make some functions that will figure out the class and then pick a random response from the list of responses.

Again, we load the ‘words.pkl‘ and ‘classes.pkl‘ pickle files that we made when we trained our model:

import nltk
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
import pickle
import numpy as np
from keras.models import load_model
model = load_model('chatbot_model.h5')
import json
import random
intents = json.loads(open('intents.json').read())
words = pickle.load(open('words.pkl','rb'))
classes = pickle.load(open('classes.pkl','rb'))

To predict the class, we will have to give input the same way we did during training.

So, we’ll make some functions that will do preprocessing on the text and then guess the class.

def clean_up_sentence(sentence):
    # tokenize the pattern - split words into array
    sentence_words = nltk.word_tokenize(sentence)
    # stem each word - create short form for word
    sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
    return sentence_words
# return bag of words array: 0 or 1 for each word in the bag that exists in the sentence
def bow(sentence, words, show_details=True):
    # tokenize the pattern
    sentence_words = clean_up_sentence(sentence)
    # bag of words - matrix of N words, vocabulary matrix
    bag = [0]*len(words)
    for s in sentence_words:
        for i,w in enumerate(words):
            if w == s:
                # assign 1 if current word is in the vocabulary position
                bag[i] = 1
                if show_details:
                    print ("found in bag: %s" % w)
    return(np.array(bag))
def predict_class(sentence, model):
    # filter out predictions below a threshold
    p = bow(sentence, words,show_details=False)
    res = model.predict(np.array([p]))[0]
    ERROR_THRESHOLD = 0.25
    results = [[i,r] for i,r in enumerate(res) if r>ERROR_THRESHOLD]
    # sort by strength of probability
    results.sort(key=lambda x: x[1], reverse=True)
    return_list = []
    for r in results:
        return_list.append({"intent": classes[r[0]], "probability": str(r[1])})
    return return_list

After predicting the class, we’ll get a random response from the list of intents.

def getResponse(ints, intents_json):
    tag = ints[0]['intent']
    list_of_intents = intents_json['intents']
    for i in list_of_intents:
        if(i['tag']== tag):
            result = random.choice(i['responses'])
            break
    return result
def chatbot_response(text):
    ints = predict_class(text, model)
    res = getResponse(ints, intents)
    return res

Now, we’ll make a graphical user interface (GUI). Let’s use the Tkinter library, which comes with a lot of other useful GUI libraries.

We’ll take the user’s message and use the helper functions we’ve made to get the answer from the bot and show it on the GUI.

Here is the GUI’s full source code.

#Creating GUI with tkinter
import tkinter
from tkinter import *
def send():
    msg = EntryBox.get("1.0",'end-1c').strip()
    EntryBox.delete("0.0",END)
    if msg != '':
        ChatLog.config(state=NORMAL)
        ChatLog.insert(END, "You: " + msg + '\n\n')
        ChatLog.config(foreground="#442265", font=("Verdana", 12 ))
        res = chatbot_response(msg)
        ChatLog.insert(END, "Bot: " + res + '\n\n')
        ChatLog.config(state=DISABLED)
        ChatLog.yview(END)
base = Tk()
base.title("Hello")
base.geometry("400x500")
base.resizable(width=FALSE, height=FALSE)
#Create Chat window
ChatLog = Text(base, bd=0, bg="white", height="8", width="50", font="Arial",)
ChatLog.config(state=DISABLED)
#Bind scrollbar to Chat window
scrollbar = Scrollbar(base, command=ChatLog.yview, cursor="heart")
ChatLog['yscrollcommand'] = scrollbar.set
#Create Button to send message
SendButton = Button(base, font=("Verdana",12,'bold'), text="Send", width="12", height=5,
                    bd=0, bg="#32de97", activebackground="#3c9d9b",fg='#ffffff',
                    command= send )
#Create the box to enter message
EntryBox = Text(base, bd=0, bg="white",width="29", height="5", font="Arial")
#EntryBox.bind("<Return>", send)
#Place all components on the screen
scrollbar.place(x=376,y=6, height=386)
ChatLog.place(x=6,y=6, height=386, width=370)
EntryBox.place(x=128, y=401, height=90, width=265)
SendButton.place(x=6, y=401, height=90)
base.mainloop()

Run Python Chatbot

To run the chatbot, we have two main files; train_chatbot.py and chatapp.py.

First, we train the model using the command in the terminal:

python train_chatbot.py

If we don’t find any mistakes while training, the model was made well. Then we run the second file to start the app.

python chatgui.py

In a few seconds, the program will open a GUI window. With the GUI, it’s simple to talk to the bot.

DOWNLOAD COMPLETE SOURCE CODE!

Summary

In this article, we have discussed the step-by-step guide on How To Make A Chatbot in Python Project with Source Code.

I hope this article can help you a lot to enhance and develop your skills and logic ideas which is important in practicing Python programming language which is the most well-known and most usable programming language in many companies.

Inquiries

If you have any questions or suggestions about the Chatbot Project in Python with Source Code, please feel free to leave a comment below.

3 thoughts on “How To Make A Chatbot In Python? A Step-by-Step Guide”

  1. Hi Team,

    I have tried the above code for my school project and I was not able to get the text field where I can enter the command.

    I got the window anyways but an empty one. Any Idea why I did not get the text field?

    Thank you for the help.

Leave a Comment