Esempio n. 1
0
    def _get_random_goal(self):
        '''Sample a final goal of user.

        Returns:
            A dict represent slots and their values sampled.
        '''
        self.goal_id = sample_from_dict(self._goal_dist)
        goal_des = self.metadata['goals'][self.goal_id]
        goal = {}
        self.goal = goal
        sampled_slots = []

        for s, v in goal_des['fixed_slots']:#fixed slots
            goal[s] = v
            sampled_slots.append(s)

        for key in goal_des['same_table_slot_keys']:#same table slots NOTE same_table_slot was coded without testing since data hadn't faked yet
            slots_values = self._get_random_same_table_slots_values(key)
            for slot in slots_values.keys():
                if slot in goal_des['changeable_slots']:
                    sampled_slots.append(slot)
                    goal[slot] = slots_values[slot]

        for one_set in goal_des['one_of_slot_set']:#get value for  one slot set and ignore other slots
            slot_set = sample_from_dict(one_set)
            for slot in slot_set:
                goal[slot] = self._get_random_slot_value(slot)
            for key in one_set.keys():
                sampled_slots.extend(key)

        sampled_slots.extend(goal_des['sys_unaskable_slots'])
        remain_slots = matlab.subtract(goal_des['changeable_slots'], sampled_slots)
        for slot in remain_slots:#changeable slots
            goal[slot] = self._get_random_slot_value(slot)

        '''Don't fill default slots, only return when system ask
        for slot, value in goal_des['default_slots_values']:#fill the default slot which was not being filled
            if slot not in goal.keys():
                goal[slot] = value
        '''
    
        fun = get_dict_value(goal_des,'goal_post_process_fun')
        if fun is not None:
            #goal = fun(self, goal)
            goal = fun(goal)

        #for debug:
        #self.goal_id = 0
        #goal = {'to_city': u'Allerton', 'task': 'find_connection', 'from_city': u'North Massapequa',}
        return goal
Esempio n. 2
0
 def _get_random_row(self, table):
     '''Get a random row for the given table.'''
     if table in self.metadata['data_observation_probability'].keys():
         data_dist = self._get_data_distribution(table)
         return sample_from_dict(data_dist)
     else:
         return self.db.get_random_row(table)
Esempio n. 3
0
    def simulate_one_da_item(self, da_item):
        #TODO: The current way of sample prob is not really fit with action and slot confusion, just for value confusion
        print '--Simulate da_item:', da_item
        original_da_type = da_item.dat
        original_slot = da_item.name
        original_value = da_item.value

        #get the da_types/acts will be confused
        da_types, da_types_probs = self._get_confused_acts(original_da_type)
        print zip(da_types, da_types_probs)
        #print '------FInish test, da confused: '
        #print da_types, '|||',  da_types_probs
        #pdb.set_trace()

        #Confusing things
        da_items = []#all item confused for this da_item
        da_items_probs = []
        #Each confused action have a prob of 1 for its all confused elements and will be combined/recalculate later
        for index, da_type in enumerate(da_types):#for every dalougue act (type) which  will be considerd or confused, such as inform, affirm 
            #get the act_out definitions and check is this actionneed slot
            #print 'build ', da_type
            act_out_des = self.domain['dialogue_act_definitions'][da_type]
            if 'act_without_slot' in act_out_des.keys() and act_out_des['act_without_slot']:
                da_item = DialogueActItem(da_type)
                da_items.append(da_item)
                da_items_probs.append(self.prob_combine_fun(1.0, da_types_probs[index]))
                continue
            #get slots will be confused
            slot_confusion = self.config['slot_confusion']
            slots = original_slot
            if original_slot in slot_confusion.keys():
                slots = sample_from_dict(slot_confusion[original_slot])
            if not isinstance(slots, list):#only one slot
                slots = [slots]
            #print 'check confused slots'
            #pdb.set_trace() 
            for slot in slots:#for every slot
                if act_out_des['value_included']==False:
                    da_items.append(DialogueActItem(da_type, slot))
                    da_items_probs.append(self.prob_combine_fun(1.0,da_types_probs[index]))
                    continue
                    
                confusion_des = self._get_confusion_description(slot, da_type)
                items, probs = self._get_confused_slot_values(confusion_des, slot, original_value)
                for item, prob in zip(items, probs):
                    da_items.append(DialogueActItem(da_type, slot, item))
                    da_items_probs.append(self.prob_combine_fun(prob,da_types_probs[index]))
                             
        #print 'Get final resul for a dialogue_item:', da_items
        print '***sampled dialogue acts:'
        for dai, prob in zip(da_items, da_items_probs):
            print dai, '\t', prob
            
        return da_items, da_items_probs
Esempio n. 4
0
    def _sample_element_from_list_dict(self, lst_dict):#should be static or class function, but this way potential for future speeup with caching
        '''Sample an element in a list based on its active probability.

        Args:
            lst_dict: A list of dict, in which each dict contains the key, active_prob,  presenting the observation probably.

        Returns:
            A dict from the given list.
        '''
        dist = self._get_dict_distribution(lst_dict)
        index = sample_from_dict(dist)
        return lst_dict[index]
Esempio n. 5
0
    def new_dialogue(self):
        '''Start a new dialogue.

        Sample a new user goal and reset everything for simulating a new dialogue.
        '''
        self.goal = self._get_random_goal()
        self.slot_level = self._build_slot_level()
        #self.dialog_turns = [] make the full history in somewhere else, not the task of user simulator
        self.unprocessed_da_queue = []
        self.act_used_slots = {}
        self.slot_level_used = 0
        self.turns = []
        self.patience_history= {}

        self.system_logger.info("SimpleUserSimulator: GOAL: %s"%self.goal)
 
        #Sample patience level, since different user will have a different level
        if 'patience_levels' in self.config.keys():
            self.patience_level = sample_from_dict(self.config['patience_levels'])
            print '---Patience - level: ', self.patience_level

        self.last_user_da = None
Esempio n. 6
0
    def _build_one_answer(self, da_metadata, answer, follow_order=False):
        '''Build a full answer to a system act.

        Args:
            da_metadata: a dict contains only description of system act such as slots-values.
            answer: a dic full description of answer act.
            follow_order: a boolean specifying the first return act need to be satisfied or cancel completely the answer.

        Returns:
            A list of DialogueActItem object.
        '''
        #print answer
        da_items = []
        new_items = []
        first_act = True
        for act_out in answer['return_acts']:#for reply without ordered answer
            #New for repeat
            if act_out == 'repeat':
                da_items.extend(self.last_user_da)#add previous act, may add more if we use inform in return_acts
                continue
            
            answer_types = get_dict_value(answer, act_out + '_answer_types')
            answer_type = None
            if answer_types is not None:
                answer_type = sample_from_dict(answer_types)
            overridden_properties = get_dict_value(answer, act_out + '_overridden_properties')
            #da_items.extend(self._build_dialogue_act_items(da_metadata, act_out, answer_type, overridden_properties))
            new_items = self._build_dialogue_act_items(da_metadata, act_out, answer_type, overridden_properties)
            da_items.extend(new_items)

            if follow_order and 'all_act_valid' in answer.keys() and answer['all_act_valid']==True:#this case of this answer requires all acts must appliabl
                if len(new_items)==0:
                    da_items = []#cancel all other da item already build, that will move to next case of anser
                    break 
            if first_act and follow_order:#if the first action in a return actions which follows the order not successful, that case not satisfy, give up
                first_act=False
                if len(da_items)==0:
                    break
        return da_items
Esempio n. 7
0
 def _sample_confusion_type(self, confusion_des):
     '''Sample confusion type.'''
     return sample_from_dict(confusion_des['confusion_types'])
Esempio n. 8
0
    def simulate_one_da_item(self, da_item):
        # TODO: The current way of sample prob is not really fit with action and slot confusion, just for value confusion
        print "--Simulate da_item:", da_item
        original_da_type = da_item.dat
        original_slot = da_item.name
        original_value = da_item.value

        # get the da_types/acts will be confused
        act_confusion = self.config["act_confusion"]
        da_types = original_da_type
        if original_da_type in act_confusion.keys():
            da_types = sample_from_dict(act_confusion[original_da_type])
        if isinstance(da_types, str):  # only one datype will be generate
            da_types = [da_types]

        # Confusing things
        da_items = []  # all item confused for this da_item
        da_items_probs = []
        # Each confused action have a prob of 1 for its all confused elements and will be combined/recalculate later
        for (
            da_type
        ) in da_types:  # for every dalougue act (type) which  will be considerd or confused, such as inform, affirm
            # get the act_out definitions and check is this actionneed slot
            act_out_des = self.domain["dialogue_act_definitions"][da_type]
            if "act_without_slot" in act_out_des.keys() and act_out_des["act_without_slot"]:
                da_item = DialogueActItem(da_type)
                da_items.append(da_item)
                da_items_probs.append(1.0)
                continue

            # get slots will be confused
            slot_confusion = self.config["slot_confusion"]
            slots = original_slot
            if original_slot in slot_confusion.keys():
                slots = sample_from_dict(slot_confusion[original_slot])
            if isinstance(slots, str):  # only one slot
                slots = [slots]

            for slot in slots:  # for every slot
                confusion_des = self._get_confusion_description(slot, da_type)
                confusion_type = self._sample_confusion_type(confusion_des["confusion_types"])
                correct_position = 0
                print "---", da_type, slot, confusion_type
                if confusion_type == "silence":  # can be never used since it is similar to the act confusion
                    da_item = DialogueActItem("silence")
                    da_items.append(da_item)
                else:
                    length = confusion_des["max_length"]
                    length = random.randint(1, length)

                    correct_position = 0  # this postion for the confusion type = correct
                    if confusion_type == "correct":
                        correct_position = 0
                    elif confusion_type == "offlist":
                        correct_position = -1
                    elif confusion_type == "onlist":
                        correct_position = self._sample_onlist_position(confusion_des, length)  # sample
                    else:
                        raise NotImplementedError("confusion_type=%s was not implemented." % confusion_type)
                    # print da_type, slot, confusion_type, correct_position
                    items, probs = self._sample_nbest_list_hypotheses(
                        da_type, slot, original_value, correct_position, length, confusion_des, confusion_type
                    )
                    da_items.extend(items)
                    da_items_probs.extend(probs)

        # print 'Get final resul for a dialogue_item:', da_items
        return da_items, da_items_probs
Esempio n. 9
0
 def _sample_confusion_type(self, confusion_des):
     return sample_from_dict(confusion_des)