示例#1
0
 def __init__(self):
     '''
     Creates a new partitionDistribution object, using the classes in this
     module.
     '''
     self.config = GetConfig()
     self.appLogger = logging.getLogger('Learning')
     self.db = GetDB()
         
     #self.fields = self.db.GetFields()
     self.fields = ['route','departure_place','arrival_place','travel_time']
     def PartitionSeed():
         return [ Partition() ]
     def HistorySeed(partition):
         return [ History() ]
     if (self.config.getboolean(MY_ID,'useHistory')):
         self.partitionDistribution = PartitionDistribution(PartitionSeed,HistorySeed)
     else:
         self.partitionDistribution = PartitionDistribution(PartitionSeed,None)
示例#2
0
class BeliefState(object):
    '''
    Belief state over listings.

    This class wraps PartitionDistribution, using the name dialing classes
    Partition and History in this module.

    Typical usage:

      from BeliefState import BeliefState
      beliefState = BeliefState()

      # Call at the beginning of each dialog
      beliefState.Init()

      # system takes action sysAction, gets asrResult
      # Update belief state to account for this information
      beliefState.Update(asrResult,sysAction)

      # print out the belief state
      print '%s' % (beliefState)

    '''
    def __init__(self):
        '''
        Creates a new partitionDistribution object, using the classes in this
        module.
        '''
        self.config = GetConfig()
        self.appLogger = logging.getLogger('Learning')
        self.db = GetDB()
            
        #self.fields = self.db.GetFields()
        self.fields = ['route','departure_place','arrival_place','travel_time']
        def PartitionSeed():
            return [ Partition() ]
        def HistorySeed(partition):
            return [ History() ]
        if (self.config.getboolean(MY_ID,'useHistory')):
            self.partitionDistribution = PartitionDistribution(PartitionSeed,HistorySeed)
        else:
            self.partitionDistribution = PartitionDistribution(PartitionSeed,None)

    def Init(self):
        '''
        Calls partitionDistribution.Init() method.  Call this at the beginning of
        each dialog.
        '''
        self.partitionDistribution.Init()
        self.marginals = None

    def Update(self,asrResult,sysAction):
        '''
        Calls partitionDistribution.Update(asrResult,sysAction).  Call this after each
        asrResult is received.
        '''
        marginals = self.GetMarginals()
        if sysAction.type == 'ask' and sysAction.force == 'request' and sysAction.content == 'departure_place' and\
        asrResult.userActions[0].type == 'ig' and 'departure_place' in asrResult.userActions[0].content:
#        asrResult.userActions[0].type == 'ig' and 'departure_place' in asrResult.userActions[0].content and \
#        len(marginals['departure_place']) > 0 and marginals['departure_place'][-1]['belief'] > 0.0 and \
#        marginals['departure_place'][-1]['equals'] == asrResult.userActions[0].content['departure_place']:
            for marginal in marginals['arrival_place']:
                if marginal['equals'] == asrResult.userActions[0].content['departure_place']:
                    self.appLogger.info('Remove the same value in arrival place')
                    self.partitionDistribution.KillFieldBelief('arrival_place',asrResult.userActions[0].content['departure_place'])
                    break
        elif sysAction.type == 'ask' and sysAction.force == 'confirm' and 'departure_place' in sysAction.content and\
        asrResult.userActions[0].type == 'ig' and 'confirm' in asrResult.userActions[0].content and \
        asrResult.userActions[0].content['confirm'] == 'YES':
#        len(marginals['departure_place']) > 0 and marginals['departure_place'][-1]['belief'] > 0.0 and \
#        marginals['departure_place'][-1]['equals'] == sysAction.content['departure_place']:
            for marginal in marginals['arrival_place']:
                if marginal['equals'] == sysAction.content['departure_place']:
                    self.appLogger.info('Remove the same value in arrival place')
                    self.partitionDistribution.KillFieldBelief('arrival_place',sysAction.content['departure_place'])
                    break
        elif sysAction.type == 'ask' and sysAction.force == 'confirm' and 'departure_place' in sysAction.content and\
        asrResult.userActions[0].type == 'ig' and 'departure_place' in asrResult.userActions[0].content:
#        asrResult.userActions[0].type == 'ig' and 'departure_place' in asrResult.userActions[0].content and \
#        len(marginals['departure_place']) > 0 and marginals['departure_place'][-1]['belief'] > 0.0 and \
#        marginals['departure_place'][-1]['equals'] == asrResult.userActions[0].content['departure_place']:
            for marginal in marginals['arrival_place']:
                if marginal['equals'] == asrResult.userActions[0].content['departure_place']:
                    self.appLogger.info('Remove the same value in arrival place')
                    self.partitionDistribution.KillFieldBelief('arrival_place',asrResult.userActions[0].content['departure_place'])
                    break
        elif sysAction.type == 'ask' and sysAction.force == 'request' and sysAction.content == 'arrival_place' and\
        asrResult.userActions[0].type == 'ig' and 'arrival_place' in asrResult.userActions[0].content:
#        asrResult.userActions[0].type == 'ig' and 'arrival_place' in asrResult.userActions[0].content and \
#        len(marginals['arrival_place']) > 0 and marginals['arrival_place'][-1]['belief'] > 0.0 and \
#        marginals['arrival_place'][-1]['equals'] == asrResult.userActions[0].content['arrival_place']:
            for marginal in marginals['departure_place']:
                if marginal['equals'] == asrResult.userActions[0].content['arrival_place']:
                    self.appLogger.info('Remove the same value in departure place')
                    self.partitionDistribution.KillFieldBelief('departure_place',asrResult.userActions[0].content['arrival_place'])
                    break
        elif sysAction.type == 'ask' and sysAction.force == 'confirm' and 'arrival_place' in sysAction.content and\
        asrResult.userActions[0].type == 'ig' and 'confirm' in asrResult.userActions[0].content and \
        asrResult.userActions[0].content['confirm'] == 'YES':
#        len(marginals['arrival_place']) > 0 and marginals['arrival_place'][-1]['belief'] > 0.0 and \
#        marginals['arrival_place'][-1]['equals'] == sysAction.content['arrival_place']:
            for marginal in marginals['departure_place']:
                if marginal['equals'] == sysAction.content['arrival_place']:
                    self.appLogger.info('Remove the same value in departure place')
                    self.partitionDistribution.KillFieldBelief('departure_place',sysAction.content['arrival_place'])
                    break
        elif sysAction.type == 'ask' and sysAction.force == 'confirm' and 'arrival_place' in sysAction.content and\
        asrResult.userActions[0].type == 'ig' and 'arrival_place' in asrResult.userActions[0].content:
#        asrResult.userActions[0].type == 'ig' and 'arrival_place' in asrResult.userActions[0].content and \
#        len(marginals['arrival_place']) > 0 and marginals['arrival_place'][-1]['belief'] > 0.0 and \
#        marginals['arrival_place'][-1]['equals'] == asrResult.userActions[0].content['arrival_place']:
            for marginal in marginals['departure_place']:
                if marginal['equals'] == asrResult.userActions[0].content['arrival_place']:
                    self.appLogger.info('Remove the same value in departure place')
                    self.partitionDistribution.KillFieldBelief('departure_place',asrResult.userActions[0].content['arrival_place'])
                    break

        self.partitionDistribution.Update(asrResult,sysAction)
        self.marginals = None
        
    def GetTopUserGoalBelief(self):
        return self.partitionDistribution.partitionEntryList[-1].belief

    def GetTopUserGoal(self):
        return self.partitionDistribution.partitionEntryList[-1].partition.fields

    def GetTopUniqueMandatoryUserGoal(self):
        partitionEntry = self.partitionDistribution.partitionEntryList[-1]
        if (partitionEntry.partition.fields['departure_place'].type == 'equals' and \
            partitionEntry.partition.fields['arrival_place'].type == 'equals' and \
            partitionEntry.partition.fields['travel_time'].type == 'equals'):
            return partitionEntry.belief
        else:
            return 0.0


    def GetTopUniqueUserGoal(self):
        '''
        Returns (callee,belief) for the top unique user goal (i.e., goal with
        count == 1), or (None,None) if one doesnt exist.
        '''
        spec = None
        belief = None
        for partitionEntry in reversed(self.partitionDistribution.partitionEntryList):
#            if (partitionEntry.partition.count == 1):
                #dbReturn = self.db.GetListingsByQuery(partitionEntry.partition.fields)
            if (partitionEntry.partition.fields['departure_place'].type == 'equals' and \
                partitionEntry.partition.fields['arrival_place'].type == 'equals' and \
                partitionEntry.partition.fields['travel_time'].type == 'equals'):
                spec = {'departure_place':partitionEntry.partition.fields['departure_place'].equals,\
                        'arrival_place':partitionEntry.partition.fields['arrival_place'].equals,\
                        'travel_time':partitionEntry.partition.fields['travel_time'].equals,\
                        'route':partitionEntry.partition.fields['route'].equals \
                        if partitionEntry.partition.fields['route'].type == 'equals'\
                        else ''}
                belief = partitionEntry.belief
                break
        return (spec,belief)

    def GetTopFullyInstantiatedUserGoal(self):
        '''
        Returns (callee,belief) for the top user goal for which all fields are
        instantiated (i.e., equals to something, rather than excluding something)
        or (None,None) if none exists.
        '''
        callee = {}
        for partitionEntry in reversed(self.partitionDistribution.partitionEntryList):
            allEquals = True # tentative
            for field in partitionEntry.partition.fields:
                if (not partitionEntry.partition.fields[field].type == 'equals'):
                    allEquals = False
                    break
                callee[field] = partitionEntry.partition.fields[field].equals
            if (allEquals == True):
                return (callee,partitionEntry.belief)
        return (None,None)

    def GetMarginals(self):
        '''
        Returns a dict with marginals over each field; example:

        {
          'first' : [
            { 'equals' : 'JASON', 'belief': 0.6 },
            { 'equals' : 'JOHN', 'belief': 0.3 }
          ],
          'last' : [
            { 'equals' : 'WILLIAMS', 'belief': 0.9 }
          ],
          'city' : [],
          'state' : []
        }

        '''
#        if (self.marginals == None):
            # Not computed yet; compute them now
        self.marginals = {}
        for field in self.fields:
            self.marginals[field] = []
        for field in self.fields:
            marginalTotals = {}
            for partitionEntry in self.partitionDistribution.partitionEntryList:
                if (partitionEntry.partition.fields[field].type == 'equals'):
                    val = partitionEntry.partition.fields[field].equals
                    if (val not in marginalTotals):
                        marginalTotals[val] = partitionEntry.belief
                    else:
                        marginalTotals[val] += partitionEntry.belief
            for val in marginalTotals:
                self.marginals[field].append({'equals': val, 'belief': marginalTotals[val]})
            self.marginals[field].sort(lambda x, y: cmp(x['belief'], y['belief']))
        return deepcopy(self.marginals)

    def __str__(self):
        '''
        Returns self.partitionDistribution.__str__()

        Example:

        ( id,pid) belief  logBel  [logPri ] description
        (   ,  -) 0.00009  -9.295 [ -0.004] city x();state x();last x();first x(JASON);count=99613
                  0.00009  -9.295           -
        (  1,  0) 0.99991  -0.000 [ -5.555] city x();state x();last x();first=JASON;count=387
                  0.99991  -0.000           -
        '''
        return self.partitionDistribution.__str__()