Trong kỷ nguyên số, chatbot trả lời tự động trở thành một phần không thể thiếu trong chăm sóc khách hàng, hỗ trợ kỹ thuật và thương mại điện tử. Những hệ thống này giúp doanh nghiệp tương tác với khách hàng 24/7, giảm tải công việc cho nhân viên và mang đến trải nghiệm người dùng tốt hơn.
Bài viết này sẽ hướng dẫn bạn từng bước xây dựng một chatbot trả lời tự động đơn giản bằng Python. Chúng ta sẽ sử dụng dữ liệu có sẵn để huấn luyện chatbot và triển khai nó chạy trên terminal. Đây là một dự án lý tưởng cho người mới học xử lý ngôn ngữ tự nhiên (NLP) và muốn hiểu cách một chatbot hoạt động.
Chuẩn bị dữ liệu huấn luyện cho chatbot
Chatbot cần một nguồn dữ liệu để học cách trả lời các câu hỏi. Bộ dữ liệu thường ở dạng các cặp câu hỏi-trả lời (intents). Trong bài này, chúng ta sẽ sử dụng bộ dữ liệu JSON có cấu trúc gồm các intent, mỗi intent chứa nhiều patterns (câu hỏi) và responses (câu trả lời). Bạn có thể tự tạo file câu hỏi và trả lời theo cấu trúc sau:
Ví dụ dữ liệu intents.json:
{
"intents": [
{
"tag": "greeting",
"patterns": ["Hi", "Hello", "Is anyone there?", "Good day"],
"responses": ["Hello!", "Hi there!", "Greetings!"]
},
{
"tag": "goodbye",
"patterns": ["Bye", "See you later", "Goodbye"],
"responses": ["Goodbye!", "See you later!", "Take care!"]
},
{
"tag": "thanks",
"patterns": ["Thanks", "Thank you", "That's helpful"],
"responses": ["You're welcome!", "No problem!", "Glad to help!"]
}
]
}
Tiền xử lý dữ liệu cho chatbot
Xử lý dữ liệu văn bản là một bước quan trọng để chuẩn bị cho mô hình học máy. Đối với chatbot trả lời tự động, dữ liệu phải được làm sạch, token hóa và vector hóa để mô hình hiểu và học mối quan hệ giữa câu hỏi và câu trả lời.
Chúng ta sử dụng nltk để lemmatize và chuẩn hóa các câu hỏi, đồng thời tạo danh sách các từ và nhãn (tags):
import nltk
from nltk.stem import WordNetLemmatizer
import json
import pickle
nltk.download('punkt')
nltk.download('wordnet')
lemmatizer = WordNetLemmatizer()
# Tải dữ liệu
with open('intents.json') as file:
data = json.load(file)
words = []
classes = []
documents = []
ignore_letters = ['?', '!', '.', ',']
for intent in data['intents']:
for pattern in intent['patterns']:
word_list = nltk.word_tokenize(pattern)
words.extend(word_list)
documents.append((word_list, intent['tag']))
if intent['tag'] not in classes:
classes.append(intent['tag'])
words = [lemmatizer.lemmatize(w.lower()) for w in words if w not in ignore_letters]
words = sorted(set(words))
classes = sorted(set(classes))
Xây dựng mô hình học máy cho chatbot
Chatbot trả lời tự động cần một mô hình để phân loại câu hỏi vào đúng nhóm intent. Một mạng nơ-ron đơn giản với Keras có thể thực hiện nhiệm vụ này bằng cách học mối quan hệ giữa câu hỏi đã vector hóa và nhãn tương ứng.
Chuyển dữ liệu thành vector Bag of Words và one-hot encode nhãn:
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.optimizers import SGD
from sklearn.preprocessing import LabelEncoder
training = []
output_empty = [0] * len(classes)
for doc in documents:
bag = []
pattern_words = [lemmatizer.lemmatize(word.lower()) for word in doc[0]]
for w in words:
bag.append(1) if w in pattern_words else bag.append(0)
output_row = list(output_empty)
output_row[classes.index(doc[1])] = 1
training.append([bag, output_row])
random.shuffle(training)
training = np.array(training, dtype=object)
train_x = np.array(list(training[:, 0]))
train_y = np.array(list(training[:, 1]))
# Xây dựng mô hình
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'))
# Biên dịch mô hình
sgd = SGD(learning_rate=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
# Huấn luyện mô hình
model.fit(train_x, train_y, epochs=200, batch_size=5, verbose=1)
model.save('chatbot_model.h5')
Tạo hàm dự đoán và phản hồi của chatbot
Để chatbot trả lời tự động, chúng ta cần một hàm nhận câu hỏi từ người dùng, xử lý văn bản, dự đoán intent và trả về câu trả lời phù hợp từ dữ liệu.
Viết hàm chatbot_response:
import random
from tensorflow.keras.models import load_model
model = load_model('chatbot_model.h5')
def clean_up_sentence(sentence):
sentence_words = nltk.word_tokenize(sentence)
sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
return sentence_words
def bag_of_words(sentence, words):
sentence_words = clean_up_sentence(sentence)
bag = [0]*len(words)
for s in sentence_words:
for i, w in enumerate(words):
if w == s:
bag[i] = 1
return np.array(bag)
def chatbot_response(text):
bow = bag_of_words(text, words)
res = model.predict(np.array([bow]))[0]
ERROR_THRESHOLD = 0.25
results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD]
results.sort(key=lambda x: x[1], reverse=True)
if results:
tag = classes[results[0][0]]
for intent in data['intents']:
if intent['tag'] == tag:
return random.choice(intent['responses'])
else:
return "Xin lỗi, tôi chưa hiểu câu hỏi của bạn."
Triển khai chatbot trên terminal
Viết một vòng lặp để chatbot tương tác trực tiếp với người dùng trên terminal:
print("Chatbot: Xin chào! Gõ 'quit' để thoát.")
while True:
message = input("Bạn: ")
if message.lower() == "quit":
break
response = chatbot_response(message)
print("Chatbot:", response)
Kết luận
Bạn vừa xây dựng thành công một chatbot trả lời tự động đơn giản bằng Python. Chatbot này sử dụng mô hình học máy để phân loại câu hỏi và trả lời dựa trên dữ liệu có sẵn. Dù còn cơ bản, đây là nền tảng để phát triển các chatbot thông minh hơn với mô hình NLP tiên tiến như BERT hoặc GPT.
Tiếp theo, bạn có thể triển khai chatbot này thành API bằng FastAPI (Chuyển mô hình học máy sang ứng dụng thực tế bằng FastAPI) hoặc tích hợp vào giao diện web để phục vụ người dùng.

