-
Notifications
You must be signed in to change notification settings - Fork 0
/
dialogue_manager.py
79 lines (58 loc) · 3.12 KB
/
dialogue_manager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import os
from sklearn.metrics.pairwise import pairwise_distances_argmin
from chatterbot import ChatBot
from chatterbot.trainers import ChatterBotCorpusTrainer
from utils import *
from sklearn.metrics.pairwise import cosine_similarity
class ThreadRanker(object):
def __init__(self, paths):
self.word_embeddings, self.embeddings_dim = load_embeddings(paths['WORD_EMBEDDINGS'])
self.thread_embeddings_folder = paths['THREAD_EMBEDDINGS_FOLDER']
def __load_embeddings_by_tag(self, tag_name):
embeddings_path = os.path.join(self.thread_embeddings_folder, tag_name + ".pkl")
thread_ids, thread_embeddings = unpickle_file(embeddings_path)
return thread_ids, thread_embeddings
def get_best_thread(self, question, tag_name):
""" Returns id of the most similar thread for the question.
The search is performed across the threads with a given tag.
"""
thread_ids, thread_embeddings = self.__load_embeddings_by_tag(tag_name)
question_vec = question_to_vec(question, self.word_embeddings, self.embeddings_dim)[np.newaxis, :]
best_thread = pairwise_distances_argmin(question_vec, thread_embeddings, metric='cosine')[0]
return thread_ids[best_thread]
class DialogueManager(object):
def __init__(self, paths):
print("Loading resources...")
# Intent recognition:
self.intent_recognizer = unpickle_file(paths['INTENT_RECOGNIZER'])
self.tfidf_vectorizer = unpickle_file(paths['TFIDF_VECTORIZER'])
self.ANSWER_TEMPLATE = 'I think its about %s\nThis thread might help you: https://stackoverflow.com/questions/%s'
# Goal-oriented part:
self.tag_classifier = unpickle_file(paths['TAG_CLASSIFIER'])
self.thread_ranker = ThreadRanker(paths)
self.create_chitchat_bot()
def create_chitchat_bot(self):
"""Initializes self.chitchat_bot with some conversational model."""
bot = ChatBot('chatter_bot')
bot.set_trainer(ChatterBotCorpusTrainer)
bot.train("chatterbot.corpus.english")
self.chitchat_bot = bot
def generate_answer(self, question):
"""Combines stackoverflow and chitchat parts using intent recognition."""
# Recognize intent of the question using `intent_recognizer`.
# Don't forget to prepare question and calculate features for the question.
prepared_question = text_prepare(question)
features = self.tfidf_vectorizer.transform([prepared_question])
intent = self.intent_recognizer.predict(features)[0]
# Chit-chat part:
if intent == 'dialogue':
# Pass question to chitchat_bot to generate a response.
response = self.chitchat_bot.get_response(question)
return response
# Goal-oriented part:
else:
# Pass features to tag_classifier to get predictions.
tag = self.tag_classifier.predict(features)[0]
# Pass prepared_question to thread_ranker to get predictions.
thread_id = self.thread_ranker.get_best_thread(prepared_question, tag)
return self.ANSWER_TEMPLATE % (tag, thread_id)