def filter(self, in_da): """Go through the input dialogue acts and pick only the ones that we can understand and that have good enough confidence.""" new_nblist = DialogueActNBList() # for each dialogue act item check if it is of known type # and if it has good probability for item in in_da: da = item[1] new_da = DialogueAct() for dai in da: if dai.dat in ["inform", "request"]: if dai.value is not None and not dai.value in self.policy.values: continue if dai.dat in ["inform", "request", "confirm"]: if not dai.name in self.policy.slots: continue # check if the value is in our ontology #if type(dai.value) is str and \ # self.ontology_unknown_re.match(dai.value): # continue if dai.dat in ["inform", "request", "other", "confirm", "reqalts", "bye", "restart"]: new_da.append(dai) if item[0] >= 0.3: # do not consider things bellow 0.3 if len(new_da) > 0: new_nblist.add(item[0], new_da) return new_nblist
def _zero_act_return(self): da = DialogueAct() fixed_slots_values = self.metadata['goals'][self.goal_id]['fixed_slots'] for s, v in fixed_slots_values: da.append(DialogueActItem('inform', s, v)) if self.slot_level_used == 0: self.slot_level_used = 1 return [da]
def _get_answer_da(self, da_in): '''Answer a sytem dialogue act.''' da_out = DialogueAct() out_of_patience=False reply_sys_acts = self.metadata['reply_system_acts'] da_metadata = self._get_dialogue_act_metadata(da_in) for act_in in da_metadata.keys(): #debug_print('------Handling the sys_act' + act_in) #print '------Handling the sys_act', act_in reply = reply_sys_acts[act_in] if isinstance(reply, dict):#this action has different definition for different goal reply = reply[self.goal_id] answer = self._sample_element_from_list_dict(reply) if 'ordered_return_acts' in answer:#process list of answer in order, and stop for first appliable for solution in answer['ordered_return_acts']: case = self._sample_element_from_list_dict(solution) da_items = self._build_one_answer(da_metadata[act_in], case, True) if len(da_items)>0: answer = case# for filtering acts with add_to_da_prob propertiy break else: da_items = self._build_one_answer(da_metadata[act_in], answer) for item in da_items:#process action can be whether add to da_out or not like impl_confirmi act_out_des = self._get_act_out_description(item.dat, answer) if 'add_to_da_prob' in act_out_des.keys(): if sample_a_prob(act_out_des['add_to_da_prob']) and item not in da_out: da_out.append(item) else: if item not in da_out: da_out.append(item) #-------update patience history if item.name is not None:#have slot, the sys act ask repeated the sema slot anserd, ignore the case of over answer if act_in not in self.patience_history.keys(): self.patience_history[act_in] = {} if item.name not in self.patience_history[act_in]: self.patience_history[act_in][item.name]=1 else: self.patience_history[act_in][item.name]+=1 if self.patience_level>=1 and self.patience_history[act_in][item.name]>self.patience_level: out_of_patience = True break#only break the inner loop #da_out.extend(da_items) if out_of_patience: if random.random()>0.5: da_out = DialogueAct(self.config['out_of_patience_act']) print '!!!!ANGRY...' else: print '!!Almost ANGRY...' return da_out
def _build_da_nbest_list(self, i, da, prob): if i<len(self._sampled_da_items): da_items, probs = self._sampled_da_items[i] for dai_index in range(len(da_items)): if da is None: da_new = DialogueAct() da_new.append(da_items[dai_index]) self._build_da_nbest_list(i+1, da_new, probs[dai_index]) else: da_new = DialogueAct() da_new.extend(da) da_new.append(da_items[dai_index]) self._build_da_nbest_list(i+1, da_new, prob*probs[dai_index])#TODO check the equation and fix it when we there is more types of confusion else: self._nbest_list.add(da, prob)
def _build_da_nbest_list(self, i, da, prob): '''Build all combination for the DialogueActItem and probs saved in self._sampled_da_item. Currently, not being used. ''' if i<len(self._sampled_da_items): da_items, probs = self._sampled_da_items[i] for dai_index in range(len(da_items)): if da is None: da_new = DialogueAct() da_new.append(da_items[dai_index]) self._build_da_nbest_list(i+1, da_new, probs[dai_index]) else: da_new = DialogueAct() da_new.extend(da) da_new.append(da_items[dai_index]) self._build_da_nbest_list(i+1, da_new, prob*probs[dai_index])#TODO check the equation and fix it when we there is more types of confusion else: self._nbest_list.add(da, prob)
def test_random_dialogues(user): metadata = get_metadata() for i in range(100): print '=======================Dialogue %i============================'%(i+1) user.new_dialogue() print 'Goal:', user.goal print '-'*60 goal_des = metadata['goals'][user.goal['task']] ordered_acts = goal_des['acts'] slots = goal_des['slots'] for acts in ordered_acts: da = DialogueAct() for act in acts.split('&'): act_des = metadata['act_definitions'][act] slot = None if act_des['slot_included']: slot = sample_from_list(slots) value = None if act_des['value_included']: if slot not in user.goal.keys(): for s in get_equivalent_slots(goal_des, slot): if s in user.goal.keys(): slot = s break if slot in user.goal.keys(): if sample_a_prob(0.5): value = user.goal[slot] else: value = 'lct' else: value = 'lct' item = DialogueActItem(act, slot, value) da.append(item) print 'sys_da:\t\t', da user.da_in(da) da = user.da_out() print 'user_da:\t', da[0] if len(da[0])==0: raise RuntimeError('User simulator doesnt reply anything!!') pdb.set_trace()
def test_reply(user): user.new_dialogue() print 'GOAL', user.goal act_type = 'implconfirm' slots = ['from_stop', 'from_street', 'from_city'] act_slot = None act_value = None for slot in slots: if slot in user.goal.keys(): act_slot = slot act_value = user.goal[slot] break act_value='abc' da = DialogueAct() item = DialogueActItem(act_type, act_slot, act_value) da.append(item) item = DialogueActItem('request', 'to_stop') da.append(item) print 'sys_da:', da user.da_in(da) dao = user.da_out() print 'user_da:', dao[0]
def compose_utterance_single(self, da): """\ Compose an utterance from templates for single dialogue act items. Returns the composed utterance. """ composed_utt = [] # try to find a template for each single dialogue act item for dai in da: try: # look for an exact match dai_utt = self.random_select(self.templates[unicode(dai)]) except KeyError: # try to find a relaxed match dax = DialogueAct() dax.append(dai) svsx = dax.get_slots_and_values() try: dai_utt = self.match_and_fill_generic(dax, svsx) except TemplateNLGException: dai_utt = unicode(dai) composed_utt.append(dai_utt) return ' '.join(composed_utt)
def generate_task(): task = [] da = DialogueAct() # indicate that we're looking for connection da.append(DialogueActItem('inform', 'task', 'find_connection')) # get two distinct stops from_stop = random.choice(STOPS) to_stop = from_stop while to_stop == from_stop: to_stop = random.choice(STOPS) da.append(DialogueActItem('inform', 'from_stop', from_stop)) da.append(DialogueActItem('inform', 'to_stop', to_stop)) task.append(da) # generate random subsequent questions questions = random.sample(range(6), random.randint(5, 6) - len(task)) query_change = False da = DialogueAct() for question in sorted(questions): dais = QUESTIONS[question] if dais[0].name in ['alternative', 'vehicle', 'time', 'to_stop' ] and not query_change: query_change = True task.append(da) da = DialogueAct() if dais[0].name == 'to_stop': new_to_stop = random.choice(STOPS) while new_to_stop == from_stop or new_to_stop == to_stop: new_to_stop = random.choice(STOPS) dais[0].value = new_to_stop da.extend(dais) task.append(da) return task
def generate_task(): task = [] da = DialogueAct() # indicate that we're looking for connection da.append(DialogueActItem('inform', 'task', 'find_connection')) # get two distinct stops from_stop = random.choice(STOPS) to_stop = from_stop while to_stop == from_stop: to_stop = random.choice(STOPS) da.append(DialogueActItem('inform', 'from_stop', from_stop)) da.append(DialogueActItem('inform', 'to_stop', to_stop)) task.append(da) # generate random subsequent questions questions = random.sample(range(6), random.randint(5, 6) - len(task)) query_change = False da = DialogueAct() for question in sorted(questions): dais = QUESTIONS[question] if dais[0].name in ['alternative', 'vehicle', 'time', 'to_stop'] and not query_change: query_change = True task.append(da) da = DialogueAct() if dais[0].name == 'to_stop': new_to_stop = random.choice(STOPS) while new_to_stop == from_stop or new_to_stop == to_stop: new_to_stop = random.choice(STOPS) dais[0].value = new_to_stop da.extend(dais) task.append(da) return task
class DummyDialoguePolicy(DialoguePolicy): """ This is a trivial policy just to demonstrate basic functionality of a proper DM. """ def __init__(self, cfg, ontology): super(DummyDialoguePolicy, self).__init__(cfg, ontology) self.das = [] self.last_system_dialogue_act = None def get_da(self, dialogue_state): # all slots being requested by the user requested_slots = dialogue_state.get_slots_being_requested() # all slots being confirmed by the user confirmed_slots = dialogue_state.get_slots_being_confirmed() # all slots which had been supplied by the user but have not been # implicitly confirmed non_informed_slots = dialogue_state.get_slots_being_noninformed() if len(self.das) == 0: # NLG("Thank you for calling. How may I help you?") self.last_system_dialogue_act = DialogueAct("hello()&thankyou()") dialogue_state.slots["ludait"] = "none" elif dialogue_state.slots["ludait"] == "bye": # NLG("Goodbye.") self.last_system_dialogue_act = DialogueAct("bye()") dialogue_state.slots["ludait"] = "none" elif dialogue_state.slots["ludait"] == "restart": # NLG("Let's start again from scratch. How may I help you?") dialogue_state.restart() self.last_system_dialogue_act = DialogueAct("restart()&hello()") dialogue_state.slots["ludait"] = "none" elif dialogue_state.slots["ludait"] == "repeat": # NLG - use the last dialogue act dialogue_state.slots["ludait"] = "none" elif dialogue_state.slots["ludait"] == "reqalts": # NLG("There is nothing else in the database.") self.last_system_dialogue_act = DialogueAct( "deny(alternatives=true") dialogue_state.slots["ludait"] = "none" elif requested_slots: # inform about all requested slots self.last_system_dialogue_act = DialogueAct() for slot in requested_slots: dai = DialogueActItem("inform", slot, requested_slots[slot]) self.last_system_dialogue_act.append(dai) dialogue_state.slots["rh_" + slot] = "none" elif confirmed_slots: # inform about all slots being confirmed by the user self.last_system_dialogue_act = DialogueAct() for slot in confirmed_slots: if confirmed_slots[slot] == dialogue_state.slots[slot]: # it is as user expected self.last_system_dialogue_act.append( DialogueActItem("affirm")) dai = DialogueActItem("inform", slot, dialogue_state.slots[slot]) self.last_system_dialogue_act.append(dai) else: # it is something else to what user expected self.last_system_dialogue_act.append( DialogueActItem("negate")) dai = DialogueActItem("deny", slot, dialogue_state.slots["ch_" + slot]) self.last_system_dialogue_act.append(dai) dai = DialogueActItem("inform", slot, dialogue_state.slots[slot]) self.last_system_dialogue_act.append(dai) dialogue_state.slots["ch_" + slot] = "none" elif non_informed_slots: # implicitly confirm all slots provided but not yet implicitly # confirmed self.last_system_dialogue_act = DialogueAct() self.last_system_dialogue_act.append(DialogueActItem("affirm")) for slot in non_informed_slots: dai = DialogueActItem("inform", slot, non_informed_slots[slot]) self.last_system_dialogue_act.append(dai) else: # NLG("Can I help you with anything else?") self.last_system_dialogue_act = DialogueAct("reqmore()") dialogue_state.slots["ludait"] = "none" # record the system dialogue acts self.das.append(self.last_system_dialogue_act) return self.last_system_dialogue_act