-
Notifications
You must be signed in to change notification settings - Fork 0
/
dialogue_manager.py
96 lines (68 loc) · 3.93 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import os
from sklearn.metrics.pairwise import pairwise_distances_argmin
from chatterbot import ChatBot
from chatterbot.trainers import ChatterBotCorpusTrainer
from utils import *
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)
thread_ids = thread_ids.values
# HINT: you have already implemented a similar routine in the 3rd assignment.
question_vec = question_to_vec(question, self.word_embeddings, self.embeddings_dim) #### YOUR CODE HERE ####
best_thread = pairwise_distances_argmin(question_vec[np.newaxis, :], thread_embeddings, metric='cosine')[0]#### YOUR CODE HERE ####
print(best_thread)
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."""
# Hint: you might want to create and train chatterbot.ChatBot here.
# It could be done by creating ChatBot with the *trainer* parameter equals
# "chatterbot.trainers.ChatterBotCorpusTrainer"
# and then calling *train* function with "chatterbot.corpus.english" param
########################
#### YOUR CODE HERE ####
########################
chatbot = ChatBot('boring-chitchat-guy')
# Training the chit-chat guy.
trainer = ChatterBotCorpusTrainer(chatbot)
trainer.train('chatterbot.corpus.english')
self.chitchat_bot = chatbot
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)#### YOUR CODE HERE ####
features = self.tfidf_vectorizer.transform([prepared_question]) #### YOUR CODE HERE ####
intent = self.intent_recognizer.predict(features)[0]#### YOUR CODE HERE ####
# Chit-chat part:
if intent == 'dialogue':
# Pass question to chitchat_bot to generate a response.
response = self.chitchat_bot.get_response(question) #### YOUR CODE HERE ####
return response
# Goal-oriented part:
else:
# Pass features to tag_classifier to get predictions.
tag = self.tag_classifier.predict(features)[0]#### YOUR CODE HERE ####
# Pass prepared_question to thread_ranker to get predictions.
thread_id = self.thread_ranker.get_best_thread(question, tag) #### YOUR CODE HERE ####
return self.ANSWER_TEMPLATE % (tag, thread_id)