How to make your first chat bot in 50 lines of code — theory and practice
Published: 2020-04-19 18:15:13

### How to make your first **chat bot** in 50 lines of code — theory and practice

### 1. How chat bots work?

Most of modern chat bot platforms consist of 3 main
things — **intent recognition** ,**slot filling** and **dialog graph.**

**1.1 Intent recognition**

Intent recognition is a **text** **classification task** which goal is to
capture specific intent behind a user query. This is motivated by the fact that
users tend to formulate their request in a lot of different ways so we need to
have a system that is able to tell if those messages relate to the same thing or
not. Let’s illustrate this with an example of a bank chat bot, where users can
ask the bot to withdraw money:

![](https://cdn-images-1.medium.com/max/800/1*XoYTzJpDtyQPyDbeeA5xsg.png)
<span class="figcaption_hack">Visualization of intent detection system</span>

You can see that although the requests are formulated in a lot of different ways
and in different styles they all mean basically the same thing and chat bot
should react in the same way. Therefore we need **text classification **model
that captures the semantics behind user sentences and assigns them to the
specific predefined class.

**1.2 Slot filling**

Once we know what action the user wants to take we need to capture specific
parameters of those actions. For example, if you want Alexa to play your
favorite song, you want her to play this specific song not just any song, so
besides detecting intent [chat bots](https://chatbotslife.com/) also need to
perform a task that is called slot-filling.

![](https://cdn-images-1.medium.com/max/800/1*FvVQRyzpXnL05sDEzCAbCw.png)

**1.3 Dialog graph**

![Visualization of dialog graph](https://cdn-images-1.medium.com/max/800/1*oSwU5XlxuzRsZLt-zVeAbg.png)

Another requirement for chat bot functionality is dialog graph. It’s goal is to steer conversation in the right direction. For example when you say “Check the weather” the chat bot could then ask “What day should I check the weather for?” and next it will be looking for intents like ‘tomorrow’ or ‘today’. The important part here is, there would be no point in asking the second question without the first one, so there is a need for a system that stores the information of the point in the conversation where we are and what are the possible next states.

**1.4 Our chat bot**

In this tutorial our goal is to create a simple chat bot, so we are going to focus only on intent detection task and simple dialog graph model. This is enough to make a chat bot that is able to answer FAQ and conduct as simple conversation.

### 2. Word and sentence embedding

Our goal in designing an intent detection is to create a system that, given a few examples for intent, can detect that a sentence given by the user is similar to these examples and therefore should have the same intent.

The problem behind this system is that we have to design a system for checking if 2 sentences are similar. This could be achieved by eg. counting how many overlapping words are in the new sentence and the sentences in training dataset. This is however a naive approach because a user can use a word that has similar meaning, but is different from the ones in the train examples.

**2.1 Word embedding**

A solution here is to use word embedding.

![](https://cdn-images-1.medium.com/max/800/0*Ac7LP7t66teJc7be.png)
Word vectors ref : https://ruder.io/word-embeddings-1/](https://ruder.io/word-embeddings-1/

Word embeddings are mathematical representations of words encoded as vectors in n-dimentional space. Similar (used in the same context) words are close to each other in this space. This means that we can compare 2 or more words to each other not by e.g. the number of overlapping characters but by how close they are to each other in they embedded form.

**2.2 Sentence embeddings**

From word embeddings we can construct embeddings for the whole sentence. This can be done in a variety of ways, we can simply take the average of the word vectors, use weighted average to check how important the words are by e.g [tf-idf](https://towardsdatascience.com/tf-idf-for-document-ranking-from-scratch-in-python-on-real-world-dataset-796d339a4089)
coefficient or even use more advanced methods like [transformer neural
networks](https://towardsdatascience.com/transformers-141e32e69591).

**2.3 Similarity**

Once we have prepared embeddings for the sentences we have to design a way for comparing them. A simple widely used method here is cosine similarity that measures similarity between two vectors as the angle between them.

![](https://cdn-images-1.medium.com/max/800/1*z2dZYCgqQVpQM_Hbo9KUjw.png)
<span class="figcaption_hack">Cosine similarity ref: [https://bit.ly/2X5470I](https://bit.ly/2X5470I)</span>

### 3.Building the chat bot

![](https://cdn-images-1.medium.com/max/800/0*sprA7uJnsFTHk9vg.png)

To create the sentence embedding we are going to use flair library. This library is based not only on static word embeddings but also analyses the words character by character which helps in dealing with out-of-vocabulary words.

In our model we are going to embed the examples for each intent and then, while processing the users message, find the most similar one. This approach is mainly taken as fast and simple one, illustrating how embedding work. Most of modern systems use neural networks (link to related articles can be found at the end),however this approach can still be used if you want to design a system that is fast and and doesn’t use a lot of resources.

We begin our program with creating the outline of the model.

<span class="figcaption_hack">outline of the program</span>
{% gist https://gist.github.com/AleksanderObuchowski/7131fa312439ac896a9a8760fe15ca0a %}
**Description**

**1–9**: importing necessary libraries 
**11** : initialization of the flair model for creating embeddings of sentences. We are using English word embeddings and mean polling method for creating sentence embeddings from word embeddings. 
**13–20** : chatbot class, this class has two static methods one for creating embeddings and one for processing user message and answering it.

**3.1 Preparing embeddings**

Firstly we need to prepare a file containing our intents and their examples.This is a json dictionary that uses intents as keys and tables of examples as values.

intents.json:
{% gist https://gist.github.com/AleksanderObuchowski/b15f989b3f27c2304913e9cbfa0a943d %}

Next we need to to create a function that constructs embeddings for the
examples.

{% gist https://gist.github.com/AleksanderObuchowski/59d82f71832e789aa7985e05e816a55d %}

**Description:**

**4** : Creating new python dictionary for the embeddings
**5–6**: Opening the input file and loading it to python dictionary **7–8** : For each intent we create a table in the embeddings dictionary
**9–12** For each example in the intent, we create a Flair sentence object that we can later embed using the model specified earlier. Finally we add the embedded sentence to the table
**13–14**: If the file doesn’t exist, we create it
**15**: We save the embedded dict. We use pickle instead of json to store the numpy arrays

**3.2 Answering the message**
answers.json:
{% gist https://gist.github.com/AleksanderObuchowski/4143aeb90aecd06788e0984393213ba8 %}

{% gist https://gist.github.com/AleksanderObuchowski/75debe815e92defc2f836de79713abf5 %}

**Description**

**3**: We use the embeddings model
**4 -5** : We load load the embeddings file created earlier 
**6–8** : Embedding of user message
**9–10** :Initializing best intent and best sore variables
**11–16** For each intent we loop through it’s embedded examples and check the cosine similarity between users message and those examples. We chose the intent, which example has the highest similarity with the new message
**17–18** : Loading the answers dict
**19**: Checking if intent chosen by the system is in the answers dict 
**20** : Return random answer from the ones assigned to the chosen
intent

### **Whole code**
{% gist https://gist.github.com/AleksanderObuchowski/35e9278ea6409793244cc05025d738eb %}
### 4. Possible improvements

In this format the chat bot has to choose one of
the intents provided. This means we have no way of detecting if user said
something that doesn't belong to any of the intents. A possible solution is to check the numerical values of the cosine similarity and based on those observation assign a threshold value below which the bot will classify the message as the one it doesn’t know how to answer.