Вступление
Чат-боты чрезвычайно полезны для деловых организаций, а также клиентов. Большинство людей предпочитают общаться прямо из чата, а не звонить в сервисные центры. Facebook опубликовал данные, которые доказали ценность ботов. Ежемесячно между людьми и компаниями отправляется более 2 миллиардов сообщений. Исследование HubSpot говорит нам, что 71% людей хотят получить поддержку клиентов из приложений обмена сообщениями. Это быстрый способ решить их проблемы, поэтому у чат-ботов большое будущее в организациях.
Сегодня мы собираемся построить захватывающий проект на Chatbot. Мы внедрим чатбота с нуля, который сможет понять, о чем говорит пользователь, и дать соответствующий ответ.
Предпосылки
Для реализации чат-бота мы будем использовать Keras — библиотеку глубокого обучения, NLTK — набор инструментов для обработки естественного языка и некоторые полезные библиотеки. Запустите приведенную ниже команду, чтобы убедиться, что все библиотеки установлены:
pip install tensorflow keras pickle nltk
Если вы хотите изучать Python бесплатно, вот руководство для мастера изучения Python бесплатно .
Вам также может понравиться:
Создай сам: API Chatbot с моделью Keras / TensorFlow
Как работают чатботы?
Чат-боты — это не что иное, как интеллектуальный программный продукт, который может взаимодействовать и общаться с людьми так же, как люди. Интересно, не правда ли? Итак, теперь давайте посмотрим, как они на самом деле работают.
Все чат-боты подпадают под концепции НЛП (обработка естественного языка). НЛП состоит из двух вещей:
-
НЛУ (понимание естественного языка): способность машин понимать человеческий язык, такой как английский.
-
NLG (Natural Language Generation): способность машины генерировать текст, подобный написанным человеком предложениям.
Представьте себе пользователя, задающего вопрос чат-боту: «Эй, что в новостях сегодня?»
Чатбот разделит пользовательское предложение на две вещи: намерение и сущность. Намерением для этого предложения может быть get_news, поскольку оно относится к действию, которое пользователь хочет выполнить. Сущность сообщает конкретные подробности о намерении, поэтому «сегодня» будет сущность. Таким образом, модель машинного обучения используется для распознавания намерений и сущностей чата.
Структура файла проекта
После завершения проекта у вас останутся все эти файлы. Давайте быстро пройдемся по каждому из них. Это даст вам представление о том, как будет реализован проект.
-
Train_chatbot.py — В этом файле мы создадим и обучим модель глубокого обучения, которая может классифицировать и идентифицировать то, что пользователь запрашивает у бота.
-
Gui_Chatbot.py — В этом файле мы создадим графический интерфейс пользователя, чтобы общаться с нашим обученным чат-ботом.
-
Intents.json — файл интентов содержит все данные, которые мы будем использовать для обучения модели. Он содержит коллекцию тегов с соответствующими им шаблонами и ответами.
-
Chatbot_model.h5 — это файл иерархического формата данных, в котором мы сохранили веса и архитектуру нашей обученной модели.
-
Classes.pkl — файл pickle может использоваться для хранения всех имен тегов для классификации, когда мы прогнозируем сообщение.
-
Words.pkl — файл picks words.pkl содержит все уникальные слова, которые составляют словарь нашей модели.
Загрузите исходный код и набор данных: https://drive.google.com/drive/folders/1r6MrrdE8V0bWBxndGfJxJ4Om62dJ2OMP?usp=sharing
Как создать свой чатбот
Я упростил создание этого чатбота в 5 шагов:
Шаг 1. Импорт библиотек и загрузка данных
Создайте новый файл Python и назовите его train_chatbot, а затем мы импортируем все необходимые модули. После этого мы будем читать файл данных JSON в нашей программе Python.
питон
xxxxxxxxxx
1
import numpy as np
2
from keras.models import Sequential
3
from keras.layers import Dense, Activation, Dropout
4
from keras.optimizers import SGD
5
import random
6
import nltk
8
from nltk.stem import WordNetLemmatizer
9
lemmatizer = WordNetLemmatizer()
10
import json
11
import pickle
12
intents_file = open('intents.json').read()
14
intents = json.loads(intents_file)
Шаг 2. Предварительная обработка данных
Модель не может принимать необработанные данные. Чтобы машина могла легко понять, она должна пройти большую предварительную обработку. Для текстовых данных доступно много методов предварительной обработки. Первая техника - это токенизация, в которой мы разбиваем предложения на слова.
Наблюдая файл интентов, мы видим, что каждый тег содержит список шаблонов и ответов. Мы маркируем каждый шаблон и добавляем слова в список. Также мы создаем список классов и документов, чтобы добавить все намерения, связанные с шаблонами.
питон
xxxxxxxxxx
1
words=[]
2
classes = []
3
documents = []
4
ignore_letters = ['!', '?', ',', '.']
5
for intent in intents['intents']:
7
for pattern in intent['patterns']:
8
#tokenize each word
9
word = nltk.word_tokenize(pattern)
10
words.extend(word)
11
#add documents in the corpus
12
documents.append((word, intent['tag']))
13
# add to our classes list
14
if intent['tag'] not in classes:
15
classes.append(intent['tag'])
16
print(documents)
Другой метод - лемматизация. Мы можем преобразовать слова в форму леммы, чтобы уменьшить все канонические слова. Например, слова play, воспроизведения, воспроизведения, воспроизведения и т. Д. Будут заменены на play. Таким образом, мы можем уменьшить количество слов в нашем словаре. Итак, теперь мы лемматизируем каждое слово и удаляем дублирующиеся слова.
питон
xxxxxxxxxx
1
# lemmaztize and lower each word and remove duplicates
2
words = [lemmatizer.lemmatize(w.lower()) for w in words if w not in ignore_letters]
3
words = sorted(list(set(words)))
4
# sort classes
5
classes = sorted(list(set(classes)))
6
# documents = combination between patterns and intents
7
print (len(documents), "documents")
8
# classes = intents
9
print (len(classes), "classes", classes)
10
# words = all words, vocabulary
11
print (len(words), "unique lemmatized words", words)
12
pickle.dump(words,open('words.pkl','wb'))
14
pickle.dump(classes,open('classes.pkl','wb'))
В конце слова содержат словарный запас нашего проекта, а классы содержат общее количество сущностей для классификации. Чтобы сохранить объект python в файле, мы использовали метод pickle.dump (). Эти файлы будут полезны после завершения обучения, и мы предскажем чаты.
Шаг 3. Создание данных обучения и тестирования
Чтобы обучить модель, мы конвертируем каждый шаблон ввода в числа. Сначала мы будем лемматизировать каждое слово шаблона и создавать список нулей той же длины, что и общее количество слов. Мы установим значение 1 только для тех индексов, которые содержат слово в шаблонах. Таким же образом мы создадим вывод, установив 1 в качестве входного класса, которому принадлежит шаблон.
питон
xxxxxxxxxx
1
# create the training data
2
training = []
3
# create empty array for the output
4
output_empty = [0] * len(classes)
5
# training set, bag of words for every sentence
6
for doc in documents:
7
# initializing bag of words
8
bag = []
9
# list of tokenized words for the pattern
10
word_patterns = doc[0]
11
# lemmatize each word - create base word, in attempt to represent related words
12
word_patterns = [lemmatizer.lemmatize(word.lower()) for word in word_patterns]
13
# create the bag of words array with 1, if word is found in current pattern
14
for word in words:
15
bag.append(1) if word in word_patterns else bag.append(0)
16
17
# output is a '0' for each tag and '1' for current tag (for each pattern)
18
output_row = list(output_empty)
19
output_row[classes.index(doc[1])] = 1
20
training.append([bag, output_row])
21
# shuffle the features and make numpy array
22
random.shuffle(training)
23
training = np.array(training)
24
# create training and testing lists. X - patterns, Y - intents
25
train_x = list(training[:,0])
26
train_y = list(training[:,1])
27
print("Training data is created")
Шаг 4. Обучение модели
Архитектура нашей модели будет представлять собой нейронную сеть, состоящую из 3-х плотных слоев. Первый слой имеет 128 нейронов, второй - 64, и последний слой будет иметь те же нейроны, что и количество классов. Выпадающие слои введены для уменьшения переоснащения модели. Мы использовали оптимизатор SGD и подгоняли данные, чтобы начать обучение модели. После завершения обучения 200 эпох мы сохраняем обученную модель, используя функцию Keras model.save («chatbot_model.h5»).
питон
xxxxxxxxxx
1
# deep neural networds model
2
model = Sequential()
3
model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu'))
4
model.add(Dropout(0.5))
5
model.add(Dense(64, activation='relu'))
6
model.add(Dropout(0.5))
7
model.add(Dense(len(train_y[0]), activation='softmax'))
8
# Compiling model. SGD with Nesterov accelerated gradient gives good results for this model
10
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
11
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
12
#Training and saving the model
14
hist = model.fit(np.array(train_x), np.array(train_y), epochs=200, batch_size=5, verbose=1)
15
model.save('chatbot_model.h5', hist)
16
print("model is created")
Шаг 5. Взаимодействие с чатботом
Наша модель готова к чату, поэтому теперь давайте создадим красивый графический интерфейс для нашего чата в новом файле. Вы можете назвать файл как gui_chatbot.py
В нашем GUI-файле мы будем использовать модуль Tkinter для построения структуры настольного приложения, а затем запишем пользовательское сообщение и снова проведем некоторую предварительную обработку, прежде чем вводить сообщение в нашу обученную модель.
Затем модель будет предсказывать тег сообщения пользователя, и мы случайным образом выберем ответ из списка ответов в нашем файле намерений.
Вот полный исходный код для файла GUI.
питон
xxxxxxxxxx
1
import nltk
2
from nltk.stem import WordNetLemmatizer
3
lemmatizer = WordNetLemmatizer()
4
import pickle
5
import numpy as np
6
from keras.models import load_model
8
model = load_model('chatbot_model.h5')
9
import json
10
import random
11
intents = json.loads(open('intents.json').read())
12
words = pickle.load(open('words.pkl','rb'))
13
classes = pickle.load(open('classes.pkl','rb'))
14
def clean_up_sentence(sentence):
16
# tokenize the pattern - splitting words into array
17
sentence_words = nltk.word_tokenize(sentence)
18
# stemming every word - reducing to base form
19
sentence_words = [lemmatizer.lemmatize(word.lower()) for word in sentence_words]
20
return sentence_words
21
# return bag of words array: 0 or 1 for words that exist in sentence
22
def bag_of_words(sentence, words, show_details=True):
24
# tokenizing patterns
25
sentence_words = clean_up_sentence(sentence)
26
# bag of words - vocabulary matrix
27
bag = [0]*len(words)
28
for s in sentence_words:
29
for i,word in enumerate(words):
30
if word == s:
31
# assign 1 if current word is in the vocabulary position
32
bag[i] = 1
33
if show_details:
34
print ("found in bag: %s" % word)
35
return(np.array(bag))
36
def predict_class(sentence):
38
# filter below threshold predictions
39
p = bag_of_words(sentence, words,show_details=False)
40
res = model.predict(np.array([p]))[0]
41
ERROR_THRESHOLD = 0.25
42
results = [[i,r] for i,r in enumerate(res) if r>ERROR_THRESHOLD]
43
# sorting strength probability
44
results.sort(key=lambda x: x[1], reverse=True)
45
return_list = []
46
for r in results:
47
return_list.append({"intent": classes[r[0]], "probability": str(r[1])})
48
return return_list
49
def getResponse(ints, intents_json):
51
tag = ints[0]['intent']
52
list_of_intents = intents_json['intents']
53
for i in list_of_intents:
54
if(i['tag']== tag):
55
result = random.choice(i['responses'])
56
break
57
return result
58
#Creating tkinter GUI
60
import tkinter
61
from tkinter import *
62
def send():
64
msg = EntryBox.get("1.0",'end-1c').strip()
65
EntryBox.delete("0.0",END)
66
if msg != '':
68
ChatBox.config(state=NORMAL)
69
ChatBox.insert(END, "You: " + msg + '\n\n')
70
ChatBox.config(foreground="#446665", font=("Verdana", 12 ))
71
ints = predict_class(msg)
73
res = getResponse(ints, intents)
74
75
ChatBox.insert(END, "Bot: " + res + '\n\n')
76
ChatBox.config(state=DISABLED)
78
ChatBox.yview(END)
79
root = Tk()
81
root.title("Chatbot")
82
root.geometry("400x500")
83
root.resizable(width=FALSE, height=FALSE)
84
#Create Chat window
86
ChatBox = Text(root, bd=0, bg="white", height="8", width="50", font="Arial",)
87
ChatBox.config(state=DISABLED)
89
#Bind scrollbar to Chat window
91
scrollbar = Scrollbar(root, command=ChatBox.yview, cursor="heart")
92
ChatBox['yscrollcommand'] = scrollbar.set
93
#Create Button to send message
95
SendButton = Button(root, font=("Verdana",12,'bold'), text="Send", width="12", height=5,
96
bd=0, bg="#f9a602", activebackground="#3c9d9b",fg='#000000',
97
command= send )
98
#Create the box to enter message
100
EntryBox = Text(root, bd=0, bg="white",width="29", height="5", font="Arial")
101
#EntryBox.bind("<Return>", send)
102
#Place all components on the screen
104
scrollbar.place(x=376,y=6, height=386)
105
ChatBox.place(x=6,y=6, height=386, width=370)
106
EntryBox.place(x=128, y=401, height=90, width=265)
107
SendButton.place(x=6, y=401, height=90)
108
root.mainloop()
Узнайте больше о проектах Python с исходным кодом .
Запуск чатбота
Теперь у нас есть два отдельных файла, один из которых - train_chatbot.py, который мы сначала будем использовать для обучения модели.
python train_chatbot.py