If you have ever wanted to build a computer program that can talk to people, you are in the right place. Chatbots are everywhere these days – on customer support websites, messaging apps, and even voice assistants. The good news is that you do not need to be an expert in artificial intelligence to create a simple but working chatbot. With Python and some basic concepts from natural language processing (NLP), you can build your own conversational program in a few hours.
In this article, I will walk you through the entire process step by step. We will start from scratch, install the necessary tools, learn the core ideas behind NLP, and then write actual Python code that understands and responds to human language. By the end, you will have a functional chatbot that you can show to your friends. Let’s get started.
What is a Chatbot and Why Do We Need NLP?
A chatbot is a software application that simulates human conversation. It can be as simple as a program that answers “hello” when you type “hi”, or as complex as a system that books flights and makes restaurant reservations. The secret sauce that makes chatbots smart is natural language processing – a branch of artificial intelligence that helps computers understand, interpret, and generate human language.
Without NLP, a chatbot would only understand exact, rigid commands. For example, you would have to type “weather London” every time, and the chatbot would fail if you wrote “What is the weather like in London?” NLP bridges this gap. It allows the chatbot to recognise the intention behind different wordings and to extract useful information from what you say.
For beginners, building a full-fledged AI chatbot from scratch sounds intimidating. But we will take a practical approach. We will first build a simple pattern‑based chatbot, then upgrade it to one that can classify user intents using basic machine learning. Both versions will use Python and a few free libraries.
Setting Up Your Python Environment
Before we write a single line of code, make sure you have Python installed on your computer. I recommend Python 3.7 or newer. You can download it from python.org. Once Python is installed, we need to install several libraries that will do the heavy lifting for us.
Open your terminal (Command Prompt on Windows, Terminal on Mac or Linux) and run the following commands:
textCopyDownload
pip install nltk pip install scikit-learn pip install numpy pip install pandas pip install requests
nltk is the Natural Language Toolkit – a wonderful library for all kinds of text processing. scikit-learn gives us machine learning tools like vectorizers and classifiers. numpy and pandas help with data handling. requests is only needed if you later want to connect your chatbot to an external API.
After installing, we need to download some data files that NLTK uses. Start a Python interactive session by typing python in your terminal, then run these two lines:
pythonCopyDownload
import nltk
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
The punkt resource is for tokenising sentences and words. stopwords gives us a list of common words like “the”, “and”, “is” that we often ignore. wordnet is a lexical database used for lemmatisation, which we will explain soon.
Now you are ready to build your first chatbot.
Basic NLP Concepts You Must Know
Over the next few sections, we will use a handful of NLP techniques. Let me explain each one simply, so you are not lost when you see them in the code.
Tokenisation
Tokenisation means splitting a piece of text into smaller units – tokens. Tokens are usually words or sentences. For example, the sentence “I love ice cream” becomes three word tokens: ["I", "love", "ice", "cream"]. Sentence tokenisation would split a paragraph into separate sentences.
Stop Word Removal
Stop words are very common words that carry little meaning on their own. Examples: “a”, “an”, “the”, “and”, “of”, “to”. Removing them helps the chatbot focus on the content words that really matter, like “love”, “ice”, “cream”.
Stemming and Lemmatisation
Both techniques reduce words to their base or root form. Stemming crudely chops off word endings. For example, “running”, “runs”, “ran” might all become “run”. Lemmatisation is more sophisticated – it uses a dictionary to return the true base form (lemma). “Better” becomes “good”, and “went” becomes “go”. For a beginner chatbot, stemming is faster and easier to implement, but lemmatisation gives better results. We will use lemmatisation.
Bag of Words and TF‑IDF
These are ways to convert text into numbers so that machine learning models can process them. Bag of words simply counts how many times each word appears in a message. TF‑IDF (Term Frequency–Inverse Document Frequency) improves on this by giving less weight to words that appear in many different messages (like stop words) and more weight to words that are specific to a few messages. We will use a vectorizer from scikit‑learn to do this automatically.
Version 1: A Simple Pattern‑Matching Chatbot
Let’s begin with the simplest possible chatbot. It will look for certain keywords or patterns in the user’s input and return a predefined response. This style is often called a rule‑based or retrieval‑based chatbot. It does not learn from data, but it is perfectly fine for a small, predictable domain.
We will use Python’s re module (regular expressions) to match patterns. Save the following code in a file named simple_chatbot.py.
pythonCopyDownload
import re
import random
# Define a list of pattern-response pairs
patterns = [
(r"hi|hello|hey", ["Hello!", "Hi there!", "Hey! How can I help you?"]),
(r"how are you", ["I'm doing well, thank you!", "All good, thanks for asking."]),
(r"your name", ["I'm a simple chatbot. You can call me PyBot."]),
(r"what is (.*)", ["Let me think about that... Can you be more specific?"]),
(r"bye|goodbye", ["Goodbye!", "See you later!", "Bye! Come back soon."]),
]
def respond(message):
message = message.lower()
for pattern, responses in patterns:
if re.search(pattern, message):
return random.choice(responses)
return "I'm sorry, I don't understand that yet."
print("Simple Chatbot: Type 'bye' to exit")
while True:
user_input = input("You: ")
if user_input.lower() in ["bye", "goodbye", "exit"]:
print("PyBot: Goodbye!")
break
response = respond(user_input)
print(f"PyBot: {response}")
Run this script. You will see that the chatbot can greet you, answer a simple “how are you”, and say goodbye. If you type “what is Python”, it triggers the pattern what is (.*) and gives a generic answer.
This approach works acceptably for a few dozen patterns. But it has obvious limits. The chatbot does not truly understand language. For example, if you type “hey there, how are you doing today?” it works because “how are you” is matched. But if you type “are you feeling well?” it fails because no pattern matches. To build a more robust chatbot, we need to move beyond simple pattern matching.
Version 2: An Intent‑Based Chatbot with a Classifier
A better way is to classify the user’s message into “intents”. An intent is the goal or purpose behind the message. For example, a user might have a greeting intent, a goodbye intent, a ask_weather intent, or a get_product_info intent. For each intent, we have several response templates. The chatbot analyses the words, decides the most likely intent, and then picks a random response from that intent’s template list.
We will build a small training dataset. Each training example is a user message labelled with an intent. We then use a machine learning classifier (Multinomial Naive Bayes, which is simple and works well with text) to predict the intent of any new message.
Step 1: Create a training dataset
We will store our data in a Python list of dictionaries. In a real project you would load this from a JSON or CSV file.
pythonCopyDownload
training_data = [
("hi", "greeting"),
("hello there", "greeting"),
("hey", "greeting"),
("good morning", "greeting"),
("bye", "goodbye"),
("see you later", "goodbye"),
("i have to go", "goodbye"),
("what is your name", "bot_info"),
("who are you", "bot_info"),
("tell me about yourself", "bot_info"),
("what time is it", "time"),
("tell me the time", "time"),
("current time", "time"),
("how are you", "how_are_you"),
("how do you feel", "how_are_you"),
("thanks", "thanks"),
("thank you", "thanks"),
("that helps", "thanks"),
]
Of course, this is a tiny dataset. In a real application you would have hundreds of examples per intent. The classifier learns from these examples, so more data means better accuracy.
Step 2: Preprocess the text
We will write a function that cleans and normalises a message. It will:
- Convert to lowercase
- Tokenise into words
- Remove stop words
- Lemmatise each word
Then it returns a string of clean, meaningful words.
pythonCopyDownload
import nltk
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from nltk.tokenize import word_tokenize
lemmatizer = WordNetLemmatizer()
stop_words = set(stopwords.words("english"))
def preprocess(text):
# lower case
text = text.lower()
# tokenise
tokens = word_tokenize(text)
# remove stop words and lemmatise
clean_tokens = [lemmatizer.lemmatize(token) for token in tokens if token.isalpha() and token not in stop_words]
return " ".join(clean_tokens)
The token.isalpha() check removes punctuation and numbers.
Step 3: Transform text into numbers
We need to convert our collection of messages into a matrix of numbers. scikit‑learn provides CountVectorizer (bag of words) and TfidfVectorizer. We will use TF‑IDF because it often gives slightly better results.
pythonCopyDownload
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import make_pipeline # Prepare the data messages = [item[0] for item in training_data] intents = [item[1] for item in training_data] # Preprocess all messages clean_messages = [preprocess(msg) for msg in messages] # Create a pipeline that first vectorizes the text then applies Naive Bayes model = make_pipeline(TfidfVectorizer(), MultinomialNB()) model.fit(clean_messages, intents)
That’s it. The pipeline will automatically vectorize the text and train the classifier. We can now use this model to predict the intent of any new user input.
Step 4: Define responses for each intent
We need a mapping from intent names to a list of possible responses.
pythonCopyDownload
responses = {
"greeting": ["Hello!", "Hi there!", "Hey! How can I help you?"],
"goodbye": ["Goodbye!", "See you later!", "Bye! Have a great day."],
"bot_info": ["I'm a simple NLP chatbot written in Python.", "My name is PyBot. I understand basic commands."],
"time": ["I'm sorry, I cannot tell the time. My clock is broken."],
"how_are_you": ["I'm doing fantastic, thank you!", "All systems operational. How are you?"],
"thanks": ["You're welcome!", "Happy to help!", "Anytime!"],
}
For the “time” intent, we gave a dummy answer. Later you could integrate the datetime module or an API to provide the real time.
Step 5: The chat loop
Now we combine everything. The chatbot will preprocess user input, predict its intent using our trained model, and then select a random response from the matching category. If the predicted intent is not in our responses dictionary, we fall back to a default message.
pythonCopyDownload
import random
def chatbot_response(user_input):
clean_input = preprocess(user_input)
intent = model.predict([clean_input])[0]
if intent in responses:
return random.choice(responses[intent])
else:
return "I'm not sure how to answer that."
print("NLP Chatbot ready! Type 'bye' to exit.")
while True:
user_input = input("You: ")
if user_input.lower() in ["bye", "goodbye", "exit"]:
print("PyBot: Goodbye!")
break
reply = chatbot_response(user_input)
print(f"PyBot: {reply}")
Run this script. Experiment with different wordings. Try “hey there”, “good morning”, “so long”, “what time is it now?”. The classifier will generalise reasonably well even though it has never seen those exact phrases. That is the power of machine learning.
Improving the Chatbot – Adding More Intents and Context
Our chatbot is functional but still very limited. Here are a few simple improvements you can implement on your own.
Add a “joke” intent
Collect some training sentences like “tell me a joke”, “make me laugh”, “say something funny”. Label them “joke”. Add a few jokes in the responses dictionary.
Remember context (very basic memory)
A chatbot that never remembers what you just said feels shallow. You can add a simple variable last_intent that stores the previous intent. For example, if the user asks “what is the weather?” and then “what about tomorrow?”, the chatbot should know the second question is still about weather. You could implement this by checking if the current intent confidence is low but the previous intent exists, and then reusing the previous intent. For a beginner, a simpler way is to store the last question or last intent and include it as an extra hint to the classifier – but that gets advanced quickly.
Connect to an external API
Instead of giving a dummy answer for the time, you can get the real time using Python’s datetime module. For weather, you can call a free API like OpenWeatherMap. The requests library makes this easy.
Example for getting the current time inside the chatbot_response function:
pythonCopyDownload
import datetime
if intent == "time":
now = datetime.datetime.now()
time_str = now.strftime("%H:%M")
return f"The current time is {time_str}."
Handle misspellings
Our preprocessing only lemmatises. It does not correct typos. A small improvement: use the textblob library to correct spelling before processing. Install it with pip install textblob and then use from textblob import TextBlob; corrected = str(TextBlob(user_input).correct()). Be careful – correction is not perfect and may change the meaning of short inputs.
Understanding the Limitations
Before you get too excited, you should know what this chatbot cannot do.
- It does not understand multi‑turn conversations. It treats every user message as independent. There is no memory of previous messages (except if you add the simple context trick).
- It cannot generate novel sentences. It only picks from a fixed set of responses. That is why it is called a retrieval‑based chatbot.
- The performance depends entirely on your training data. If a user asks something your classifier has never seen anything similar to, it will guess randomly or choose an intent with low confidence.
- It does not handle out‑of‑vocabulary words or long, complex sentences well.
For a production chatbot that can hold a real conversation, you would need to move to more advanced techniques like recurrent neural networks (RNNs) or transformers (the technology behind ChatGPT). But building a simple intent classifier is an excellent first step, and many industry chatbots still use exactly this approach for narrow domains like banking or troubleshooting.
Full Code Listing
Here is the complete code for our final intent‑based chatbot in one block. You can copy and paste it into a Python file and run it.
pythonCopyDownload
import nltk
import random
import re
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from nltk.tokenize import word_tokenize
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
# Download NLTK resources (only once)
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
# Preprocessing
lemmatizer = WordNetLemmatizer()
stop_words = set(stopwords.words("english"))
def preprocess(text):
text = text.lower()
tokens = word_tokenize(text)
clean_tokens = [lemmatizer.lemmatize(token) for token in tokens if token.isalpha() and token not in stop_words]
return " ".join(clean_tokens)
# Training data
training_data = [
("hi", "greeting"),
("hello there", "greeting"),
("hey", "greeting"),
("good morning", "greeting"),
("bye", "goodbye"),
("see you later", "goodbye"),
("i have to go", "goodbye"),
("what is your name", "bot_info"),
("who are you", "bot_info"),
("tell me about yourself", "bot_info"),
("what time is it", "time"),
("tell me the time", "time"),
("current time", "time"),
("how are you", "how_are_you"),
("how do you feel", "how_are_you"),
("thanks", "thanks"),
("thank you", "thanks"),
("that helps", "thanks"),
("tell me a joke", "joke"),
("make me laugh", "joke"),
]
# Preprocess all training messages
clean_messages = [preprocess(msg) for msg, _ in training_data]
intents = [intent for _, intent in training_data]
# Train the classifier
model = make_pipeline(TfidfVectorizer(), MultinomialNB())
model.fit(clean_messages, intents)
# Response dictionary
responses = {
"greeting": ["Hello!", "Hi there!", "Hey! How can I help you?"],
"goodbye": ["Goodbye!", "See you later!", "Bye! Have a great day."],
"bot_info": ["I'm a simple NLP chatbot written in Python.", "My name is PyBot. I understand basic commands."],
"time": ["I'm sorry, I cannot tell the time. My clock is broken."],
"how_are_you": ["I'm doing fantastic, thank you!", "All systems operational. How are you?"],
"thanks": ["You're welcome!", "Happy to help!", "Anytime!"],
"joke": ["Why don't scientists trust atoms? Because they make up everything.",
"What do you call a fake noodle? An impasta!"],
}
def chatbot_response(user_input):
clean_input = preprocess(user_input)
intent = model.predict([clean_input])[0]
if intent in responses:
return random.choice(responses[intent])
else:
return "I'm not sure how to answer that."
# Chat loop
print("NLP Chatbot ready! Type 'bye' to exit.")
while True:
user_input = input("You: ")
if user_input.lower() in ["bye", "goodbye", "exit"]:
print("PyBot: Goodbye!")
break
reply = chatbot_response(user_input)
print(f"PyBot: {reply}")
Next Steps – What to Learn Next
You have built a working chatbot from scratch. That is a big achievement. Now you can expand your skills in several directions.
- Learn about speech recognition and text‑to‑speech to make a voice chatbot. The
speech_recognitionandpyttsx3libraries are good starting points. - Explore deep learning for chatbots. Libraries like
transformers(Hugging Face) andtorchlet you use pre‑trained models like DialoGPT or smaller versions of ChatGPT. - Integrate your chatbot into a web application using Flask or Django. You could create a simple website with a chat window and have Python serve the responses.
- Build a context‑aware chatbot by storing the conversation history and feeding it to a recurrent neural network or a transformer. This is the path to a truly conversational AI.
Do not feel overwhelmed. Every expert started exactly where you are now – writing a few lines of Python, training a small classifier, and watching it say “Hello” back. Keep experimenting, keep adding new intents, and soon you will have a chatbot that surprises you with its cleverness.
Happy coding, and enjoy your new talking companion.