Building a ChatBot in Python Using the spaCy NLP Library

Creating Chatbot

Hello Readers! Welcome to the tutorial where we will build a weather bot in python which will interact with users in Natural Language. Without any further due let’s get started.

Must Read: An Introduction to NLP

What are chatbots?

You all must have visited a website where a message says “Hi! how can I help you” and we click on it and start chatting with it. Have you ever wondered who interacts with us? Well, it is intelligent software that interacts with us and responds to our queries.

Let’s take another real-life example of various assistants like Siri(by Apple), Alexa(by Amazon), Google Assistant, and many more. Whenever we say “Alexa, play my music playlist on Spotify, ” your music playlist starts playing. These are the intelligent assistants which use Artificial Intelligence, Machine Learning and are trained for various kinds of inputs that the user gives to them.

Chatbots can perform various tasks like booking a railway ticket, providing information about a particular topic, finding restaurants near you, etc. Chatbots are created to accomplish these tasks for users providing them relief from searching for these pieces of information themselves.

In this tutorial, you will create a chatbot using the spacy NLP Library that tells the user about the current weather in the city and is also capable enough to converse with the user in natural language. This chatbot will use OpenWeather API to tell the user about the current weather in any city in the world.

Recommended Reading: Top 5 Python libraries for Natural language processing

Pre-Requisites for creating a chatbot in Python

  • The latest version of Python can be downloaded from https://www.python.org/downloads/
  • In this tutorial, we will use an API key for OpenWeather. To get your API key visit OpenWeather and create an account. Make sure you confirm your E-Mail address. After registering successfully, visit the API Keys section to view the API key generated for your account. This API key is an alphanumeric sequence of characters.

With the above requirements satisfied we are good to go to the next step.

Installing the Library

In this tutorial, we will require two libraries spacy and requests. The spacy library will help your chatbot understand the user’s sentences and the requests library will allow the chatbot to make HTTP requests.

Install spacy:

pip install -U spacy

Next, we will download spacy’s English Language Model:

python -m spacy download en_core_web_md

If the following error arises, then you need to install wheel:

Output
ERROR: Failed building wheel for en-core-web-md

Install wheel:

pip install -U wheel

Then, download the English Language Model again.

To confirm that spacy is installed properly, open the Python Interpreter by executing the following command in the terminal:

python

Now, import spacy and load the English-Language Model:

>>> import spacy
>>> nlp = spacy.load("en_core_web_md")

If the two statements execute without errors then spacy is successfully installed. You can close the python Interpreter:

>>> exit()

The requests library comes pre-installed with Python. If you get an error message while importing the requests module, you need to install the library:

pip install requests

Creating the Chatbot

Ok with the above libraries installed we are good to go with the coding part.

Step 1 – Creating the weather function

Here, we will create a function that the bot will use to acquire the current weather in a city.

Open your favorite IDE and add the following code to your python file:

import requests

api_key = "your_api_key"

def get_weather(city_name):
    api_url = "http://api.openweathermap.org/data/2.5/weather?q={}&appid={}".format(city_name, api_key)

    response = requests.get(api_url)
    response_dict = response.json()

    weather = response_dict["weather"][0]["description"]

    if response.status_code == 200:
        return weather
    else:
        print('[!] HTTP {0} calling [{1}]'.format(response.status_code, api_url))
        return None

Let’s understand the code!

Firstly, we import the requests library so that we can make the HTTP requests and work with them. In the next line, you must replace the your_api_key with the API key generated for your account.

Next, we define a function get_weather() which takes the name of the city as an argument. Inside the function, we construct the URL for the OpenWeather API. We will make the get request through this URL. The URL returns the weather information of the city in JSON format. After this, we make a GET request using requests.get() function to the API endpoint and we store the result in the response variable. After this, the result of the GET request is converted to a Python dictionary using response.json(). We have done this for easier access.

Next, we extract the weather conditions into a weather variable.

Next, we handle some conditions. In the if block we ensure the status code of the API response is 200 (which means that we successfully fetched the weather information) and return the weather description.

If there was an issue with the request then the error code is printed out to the console and None is returned.

That’s all about the get_weather() function. Now, let’s test the function with some inputs. Paste the code in your IDE and replace your_api_key with the API key generated for your account.

Code Snippet

import requests

def get_weather(city_name):
    api_url = "http://api.openweathermap.org/data/2.5/weather?q={}&appid={}".format(city_name, api_key)

    response = requests.get(api_url)
    response_dict = response.json()

    weather = response_dict["weather"][0]["description"]

    if response.status_code == 200:
        return weather
    else:
        print('[!] HTTP {0} calling [{1}]'.format(response.status_code, api_url))
        return None

weather = get_weather("Patna")
print(weather)

Output

mist

How amazing is that! We have a function which is capable of fetching the weather conditions of any city in the world.

Step 2 – Creating the chatbot function

Here, we will create a functioning chatbot that uses the get_weather() function to fetch the weather conditions of a city and the spacy NLP library to interact with the users in natural language. Add the following code snippets to the previous code. You need not create a new file for this.

First, we will import the spacy library and load the English Language model:

import spacy

nlp = spacy.load("en_core_web_md")

After, the get_weather() add the following code:

weather = nlp("Weather Conditions in a city")
def chatbot(statement):
  statement = nlp(statement)

In the above code snippet, the variables weather and statement are tokenized which is necessary for the spaCy to compute the semantic similarity between the user input which is statement and the weather. The chatbot function takes statement as an argument that will be compared with the sentence stored in the variable weather.

Next, we will use the similarity() function of the spaCy library. The similarity() method computes the semantic similarity of the two statements and gives a value between 0 and 1 where a higher number means a greater similarity. This function is used to make the chatbot intelligent so that it can compare the sentence given by the user with the base sentence and give the desired output. It will become more clear when we will test the chatbot 🙂

But, we have to set a minimum value for the similarity to make the chatbot decide that the user wants to know about the temperature of the city through the input statement. So, let’s set the minimum value as 0.75. You can definitely change the value according to your project needs.

Till now our code looks like this:

import spacy

nlp = spacy.load("en_core_web_md")

weather = nlp("Weather Conditions in a city")

def chatbot(statement):
  statement = nlp(statement)
  min_similarity = 0.75

Now comes the final and most interesting part of this tutorial. We will compare the user input with the base sentence stored in the variable weather and we will also extract the city name from the sentence given by the user.

Add the following code:

if weather.similarity(statement) >= min_similarity:
    
    for ent in statement.ents:
      if ent.label_ == "GPE": # GeoPolitical Entity
        city = ent.text
        
        city_weather = get_weather(city)
        if city_weather is not None:
          return "In " + city +", the current weather is: " + city_weather
        else:
          return "Something went wrong."
      else:
        return "You need to tell me a city to check."
      
else:
    return "Sorry I don't understand that. Please rephrase your statement."

To extract the named entities we use spaCy’s named entity recognition feature. To extract the name of the city a loop is used to traverse all the entities that spaCy has extracted from the user input and check whether the entity label is “GPE” (Geo-Political Entity). If it is then we store the name of the entity in the variable city. Once the name of the city is extracted the get_weather() function is called and the city is passed as an argument and the return value is stored in the variable city_weather.

Now, if the get_weather() function successfully fetches the weather then it is communicated to the user otherwise if some error occurred a message is shown to the user.

With that, you have finally created a chatbot using the spaCy library which can understand the user input in Natural Language and give the desired results.

Full Chatbot Program Code

import spacy
import requests

nlp = spacy.load("en_core_web_md")


api_key = "019947b686adde825c5c6104b3e13d7e"

def get_weather(city_name):
    api_url = "http://api.openweathermap.org/data/2.5/weather?q={}&appid={}".format(city_name, api_key)

    response = requests.get(api_url)
    response_dict = response.json()

    weather = response_dict["weather"][0]["description"]

    if response.status_code == 200:
        return weather
    else:
        print('[!] HTTP {0} calling [{1}]'.format(response.status_code, api_url))
        return None

weather = nlp("Weather Conditions in a city")
def chatbot(statement):
  statement = nlp(statement)
  min_similarity = 0.75

  if weather.similarity(statement) >= min_similarity:
    
    for ent in statement.ents:
      if ent.label_ == "GPE": # GeoPolitical Entity
        city = ent.text
        
        city_weather = get_weather(city)
        if city_weather is not None:
          return "In " + city +", the current weather is: " + city_weather
        else:
          return "Something went wrong."
      else:
        return "You need to tell me a city to check."
      
  else:
    return "Sorry I don't understand that. Please rephrase your statement."

print("Hi! I am Windy a weather bot.........")
statement = input("How can I help you ?\n")

response = chatbot(statement)
print(response)

We have asked the chatbot to provide the weather conditions in Bihar and let us see what output we get:

Hi! I am Windy a weather bot.........
How can I help you ?
How is the weather in Bihar
In Bihar, the current weather is: broken clouds

Summary

It’s really interesting to see our chatbot giving us weather conditions. Notice that I have asked the chatbot in natural language and the chatbot is able to understand it and compute the output.

Finally, you have created a chatbot and there are a lot of features you can add to it.

References

spaCy