Python Chatbot Poster

Python Chatbot: Build You Own Simple but Useful Chatbot with Python

Introduction

A chatbot is a program which is able to engage in conversation with a human in a seamless and  a natural way. Technically this conversation can be by text or by computer speech. A general purpose Chatbot is some ways off in the future so Chatbots that exist today are are often designed for a single purpose. Today Chatbots are typically used to answer questions and provide information for various practical purposes. These include customer service or information requests. See some examples here.

Some chatbots made today use cutting edge advancements and the most sophisticated natural language processing algorithms to appear as human-like as possible. This is fine for general purpose systems but dedicated systems can use a simpler approach. Practical chatbots can read user input and compare it to statements in a database of possible queries to find the closest match, or a match with similar wording. In this tutorial we will build one of the latter using Python. This will be our python chatbot.

Our Approach

The general idea is that we will have a specific set of commands that our python chatbot can respond to. It is expected that each command can take different forms but are asking for the same thing. For example “tell me the time” and “what is the time now” are both asking for the current time. It is expected that the user may type the commands in more varied ways so we will have to be able to handle this. The way we’ll do this is to have a collection of the possible ways that the question can be asked. We will then compare what was asked with the stored variations in this collection.

Chatbot Algorithm and Math

The comparison will be done by computing what is called the Hamming distance between what was asked and the variations in the collection database. This method will give us a measure of similarity between the phrases and can therefore work with phrases that are not exact but close in wording.

The Hamming distance calculation requires that the statements have the same number of characters (letters, numbers, spaces etc). To ensure this we will pad both statements with spaces as necessary. We will also divide the Hamming distance by the number of characters to normalize the value. This means that the final value will range from 0 to 1, with 1 meaning that there is an exact match and a zero meaning no similarity at all was detected. Similar wording statements will have a value in between.

Also we can expect different user commands to have a value between 0 and 1 for more than one command. For example “what time is it” and “what day is it” are very similar statements but are asking for two different things. Humans have no issue making the distinction but we will have to handle this in our code. The way we’ll do this is to match the user command to the collection command to which it is most similar, that is the one with a normalized Hamming distance closest to 1.

Python Chatbot Code

For our example our bot will be able to tell the user either the current time or the day of the week. These will be two separate commands, they are simple but will serve our purposes​ in demonstrating the principle.

Normalized Hamming Distance

This is implemented as a python function because we will need to reuse it for comparing the user command to each collection command. The code is:

def redHammingMod(s1, s2):
    s1 = s1 + ' ' * (len(s2) - len(s1))
    s2 = s2 + ' ' * (len(s1) - len(s2))
    distance = sum(i == j for i, j in zip(s1, s2))
    norm_distance = distance / float(len(s1))
    return norm_distance

The two commands to be compared are represented by s1 and s2. These are modified to be the same length by padding them with spaces. The Hamming distance is then calculated and normalized before being returned.

Building the Command Variation Collection

For our example the command collection is represented as python lists. These are just a way to represent an array of items in python. We will have two commands, one to get the current time and the other to get the current weekday. The variations we have are:

timeCmds = ["what time is it", "what is the time", "time"]
dayCmds = ["what day is it", "what day is today", "day", "what day is today", "today"]

These can easily be expanded to include more possible variations, but they should be fine as is.

User Interaction

To interact with the user, our python chatbot will simply introduce itself and ask how it can help. To demonstrate the use of different greetings to reduce the monotony of using or chatbot we have added code to vary a part of the greeting. The principle is to have a set of different greetings and randomly select one each time the chatbot greets the user. This principle can be applied to all out chatbot responses. The user interaction python code is:

print "hello, welcome to my world. I am super chatbot :) "
promptMsg = ["Enter your request ","How can I help ", "what do you want to know "]
dispMsg = promptMsg[random.randint(1,3)-1]
user_cmd = raw_input(dispMsg)
evaluateCommand(user_cmd)

The user command is sent to the evaluateCommand function to match it to a collection command. The evaluateCommand function is explained next.

Evaluating and Matching the User Command

As stated earlier we will match the user command to the collection command by calculating the normalized Hamming distance as shown above and selecting the most similar collection command.

Each set of collection  commands is assigned an integer value that we will use to say which collection command was matched. For our example the time command is a 1 and the day command is 2.

If the user command was matched to the time collection the selected command (cmdSel in the code) is set to 1. The value of 1 causes a set of code to be executed to get the current time and display it to the user.

If the user command was matched to the day collection, the selected command (cmdSel in the code) is set to 2. This value causes another set of code to be executed to get the current weekday and display it to the user.

This concept can be extended to any number of required commands.

The code is:

def evaluateCommand(uc):
    maxX = 0
    x = 0
    cmdSel = 0

    for cmd in timeCmds:
       x = redHammingMod(cmd, uc)
       if maxX < x:
          maxX = x
          cmdSel = 1

    for cmd in dayCmds:
       x = redHammingMod(cmd, uc)
       if maxX < x:
          maxX = x
          cmdSel = 2

    print maxX
    print cmdSel

    if cmdSel == 1:
       print "the current time is: "
       print datetime.datetime.now().time()

    if cmdSel == 2:
       print "today is: "
       weekday = datetime.datetime.now().weekday()
       print calendar.day_name[0]

Full Python Chatbot Code

So with all the components explained, let’s put it all together. The full code is:

import random, datetime, calendar

def redHammingMod(s1, s2):
    s1 = s1 + ' ' * (len(s2) - len(s1))
    s2 = s2 + ' ' * (len(s1) - len(s2))
    distance = sum(i == j for i, j in zip(s1, s2))
    norm_distance = distance / float(len(s1))
    return norm_distance

def evaluateCommand(uc):
    maxX = 0
    x = 0
    cmdSel = 0

    for cmd in timeCmds:
       x = redHammingMod(cmd, uc)
       if maxX < x:
          maxX = x
          cmdSel = 1

    for cmd in dayCmds:
       x = redHammingMod(cmd, uc)
       if maxX < x:
          maxX = x
          cmdSel = 2

    print maxX
    print cmdSel

    if cmdSel == 1:
       print "the current time is: "
       print datetime.datetime.now().time()

    if cmdSel == 2:
       print "today is: "
       weekday = datetime.datetime.now().weekday()
       print calendar.day_name[0]

timeCmds = ["what time is it", "what is the time", "time"]
dayCmds = ["what day is it", "what day is today", "day", "what day is today", "today"]

print "hello, welcome to my world. I am super chatbot :) "
promptMsg = ["Enter your request ","How can I help ", "what do you want to know "]
dispMsg = promptMsg[random.randint(1,3)-1]
user_cmd = raw_input(dispMsg)
evaluateCommand(user_cmd)

Conclusion

A simple but very useful python chatbot was presented in very few lines of code, less than 50 actually 🙂 . It serves to demonstrate the basic principles that can be used to build a more complex chatbot.

Chatbots can improve our lives by providing information and answering questions that do not need a human. This will significantly decrease your wait time if you are a customer and improve experiences for your customers if you are a service provider. They are here and they are the future so start building and understanding them.

You can check my GitHub for updates and more chatbot code.

Please feel free to test, modify and improve this chatbot and if you found it helpful please share this article with interested friends and colleagues.