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)
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__()