Beispiel #1
0
class UserSimulation(object):
    def __init__(self):
        self.config = GetConfig()
        assert (not self.config==None), 'Config file required'
        assert (self.config.has_option('LGus','LOGIN_PAGE')),'LGus section missing field LOGIN_PAGE'
        self.login_page = self.config.get('LGus','LOGIN_PAGE')
        assert (self.config.has_option('LGus','URL')),'LGus section missing field URL'
        self.url = self.config.get('LGus','URL')
        assert (self.config.has_option('LGus','ID')),'LGus section missing field ID'
        self.id = {'username':self.config.get('LGus','ID')}
        assert (self.config.has_option('LGus','PASSWD')),'LGus section missing field PASSWD'
        self.id['password'] = self.config.get('LGus','PASSWD')
        try:
            data = urllib.urlencode(self.id)
            req = urllib2.Request(self.login_page, data)
            cj = cookielib.CookieJar()
            self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
            response = self.opener.open(req)
            the_page = response.read()
#            print the_page
        except Exception, detail:
            print "Err ", detail
Beispiel #2
0
class tokenizer(object):
	MY_ID = 'TOKENIZER'
	def __init__(self,mode=None):
		self.config = GetConfig()
		if mode:
			self.mode = mode
		else:
			if self.config.has_option(self.MY_ID,'mode'):
				self.mode = self.config.get(self.MY_ID,'mode')
			else:
				self.mode = 'NLTK'
		if self.mode == 'STANFORD':
			from nltk.tokenize.stanford import StanfordTokenizer as Tokenizer
			self.tokenizer = Tokenizer()
		elif self.mode == 'NLTK':
			pass
		elif self.mode == 'MINE':
			self.spacePunct = re.compile(ur'[`~!@#\$%\^&\*\(\)\[\]{}_\+\-=\|\\:;\"\'<>,\?/]')
			self.removePunct = re.compile(ur'\.')
		else:
			raise Exception('Error: tokenizer, Unknown mode %s!' %(self.mode))

	def tokenize(self, sent):
		if sent.endswith('-') or sent.endswith('~'):
			sent += ' '
		sent = sent.replace('~ ', ' ~ ')
		sent = sent.replace('- ', ' - ')
		if self.mode == 'STANFORD':
			tokens = self.tokenizer.tokenize(sent.strip())
		elif self.mode == 'NLTK':
			tokens = nltk.word_tokenize(sent.strip())
		elif self.mode == 'MINE':
			new_sent = sent.strip()
			new_sent = self.spacePunct.sub(' ', new_sent)
			new_sent = self.removePunct.sub('', new_sent)
			tokens = new_sent.split()
		p_sent = ' '.join(tokens)
		p_sent = p_sent.replace('% ', '%')
		p_sent = p_sent.replace('``', '\"')
		p_sent = p_sent.replace('\'\'', '\"')
		p_tokens = p_sent.split(' ')
		return p_tokens
Beispiel #3
0
class Partition(object):
    '''
    Tracks a partition of listings.

    This class tracks a partition of listings.
    '''
    def __init__(self,existingPartition=None,fieldToSplit=None,value=None):
        '''
        Constructor, and copy constructor.

        If called as Partition(), returns a new root partition.

        If called as Partition(existingPartition,fieldToSplit,value), this creates
        a new child partition of existingPartition, split on fieldToSplit=value.  Does
        not modify existingPartition.

        This constructor is not meant to be called directly by application code.
        Application code should use the BeliefState wrapper.
        '''
        self.appLogger = logging.getLogger('Learning')
#        self.appLogger.info('Partition init')
        self.config = GetConfig()
        self.useLearnedUserModel = self.config.getboolean(MY_ID,'useLearnedUserModel')
        self.confirmUnlikelyDiscountFactor = self.config.getfloat(MY_ID,'confirmUnlikelyDiscountFactor')
        self.ignoreNonunderstandingFactor = self.config.getboolean(MY_ID,'ignoreNonunderstandingFactor')
        self.num_route = self.config.getint(MY_ID,'numberOfRoute')
        self.num_place = self.config.getint(MY_ID,'numberOfPlace')
        self.num_time = self.config.getint(MY_ID,'numberOfTime')
        self.offListBeliefUpdateMethod = self.config.get('PartitionDistribution','offListBeliefUpdateMethod')
        
        db = GetDB()
#        self.appLogger.info('Partition 1')
        if (existingPartition == None):
            #self.fieldList = db.GetFields()
            self.fieldList = ['route','departure_place','arrival_place','travel_time']
            self.fieldCount = len(self.fieldList)
            #self.totalCount = db.GetListingCount({})
            self.totalCount = self.num_route * self.num_place * self.num_place * self.num_time
            self.fields = {}
#            self.appLogger.info('Partition 2')
            for field in self.fieldList:
                self.fields[field] = _FieldEntry()
            self.count = self.totalCount
            self.prior = 1.0
            self.priorOfField = {'route':1.0,'departure_place':1.0,'arrival_place':1.0,'travel_time':1.0}
            self.countOfField = {'route':self.num_route,'departure_place':self.num_place,'arrival_place':self.num_place,'travel_time':self.num_time}
            
#            self.appLogger.info('Partition 3')
            if not self.useLearnedUserModel:
                umFields = ['request_nonUnderstandingProb',
                            'request_directAnswerProb',
                            'request_allOverCompleteProb',
                            'request_oogProb',
                            'request_irrelevantAnswerProb',
                            'confirm_directAnswerProb',
                            'confirm_nonUnderstandingProb',
                            'confirm_oogProb']
                assert (not self.config == None), 'Config file required (UserModel parameters)'
                self.umParams = {}
                for key in umFields:
                    assert (self.config.has_option('UserModel', key)),'UserModel section missing field %s' % (key)
                    self.umParams[key] = self.config.getfloat('UserModel',key)
                overCompleteActionCount = 0
                for i in range(1,self.fieldCount):
                    overCompleteActionCount += Combination(self.fieldCount-1,i)
                self.appLogger.info('fieldCount = %d; overCompleteActionCount = %d' % (self.fieldCount,overCompleteActionCount))
                self.umParams['request_overCompleteProb'] = \
                  1.0 * self.umParams['request_allOverCompleteProb'] / overCompleteActionCount
                self.umParams['open_answerProb'] = \
                  (1.0 - self.umParams['request_nonUnderstandingProb'] - self.umParams['request_oogProb']) / \
                  overCompleteActionCount
            else:
                modelPath = self.config.get('Global','modelPath')
#                self.appLogger.info('Partition 4')
                self.userModelPath = self.config.get(MY_ID,'userModelPath')
#                self.appLogger.info('Partition 5')
                self.userModel = pickle.load(open(os.path.join(modelPath,self.userModelPath),'rb'))
#                self.appLogger.info('Partition 6')
                if self.offListBeliefUpdateMethod == 'heuristicUsingPrior':
                    self.irrelevantUserActProb = self.config.getfloat(MY_ID,'irrelevantUserActProb_HeuristicUsingPrior')
                    self.minRelevantUserActProb = self.config.getfloat(MY_ID,'minRelevantUserActProb_HeuristicUsingPrior')
                elif self.offListBeliefUpdateMethod in ['plain','heuristicPossibleActions']:
                    self.irrelevantUserActProb = self.config.getfloat(MY_ID,'irrelevantUserActProb')
                    self.minRelevantUserActProb = self.config.getfloat(MY_ID,'minRelevantUserActProb')
                else:
                    raise RuntimeError,'Unknown offListBeliefUpdateMethod = %s'%self.offListBeliefUpdateMethod
#                self.appLogger.info('Partition 7')
        else:
            assert not fieldToSplit == None,'arg not defined'
            assert not value == None,'arg not defined'
            self.fieldList = existingPartition.fieldList
            self.fieldCount = existingPartition.fieldCount
            if not self.useLearnedUserModel:
                self.umParams = existingPartition.umParams
            else:
                self.userModel = existingPartition.userModel
                self.irrelevantUserActProb = existingPartition.irrelevantUserActProb
                self.minRelevantUserActProb = existingPartition.minRelevantUserActProb
            self.totalCount = existingPartition.totalCount
            self.countOfField = existingPartition.countOfField
            self.priorOfField = {}
            self.fields = {}
            self.count = 1
            for field in self.fieldList:
                if (field == fieldToSplit):
                    self.fields[field] = _FieldEntry(type='equals', equals=value)
                else:
                    self.fields[field] = existingPartition.fields[field].Copy()
                    
                if self.fields[field].type == 'equals':
                    self.count *= 1
                    self.priorOfField[field] = 1.0/self.countOfField[field]
#                elif field == 'route':
#                    self.count *= (self.num_route - len(self.fields[field].excludes.keys()))
#                elif field in ['departure_place','arrival_place']:
#                    self.count *= (self.num_place - len(self.fields[field].excludes.keys()))
#                elif field == 'travel_time':
#                    self.count *= (self.num_time - len(self.fields[field].excludes.keys()))
#                else:
#                    raise RuntimeError,'Invalid field %s'%field
                else:
                    self.count *= (self.countOfField[field] - len(self.fields[field].excludes.keys()))
                    self.priorOfField[field] = 1.0 - 1.0 * len(self.fields[field].excludes.keys())/self.countOfField[field]

            #self.count = db.GetListingCount(self.fields)
            self.prior = 1.0 * self.count / self.totalCount

    def Split(self,userAction):
        '''
        Attempts to split the partition on userAction.  Returns a list of zero
        or more child partitions, modifying this partition as appropriate.
        '''
        newPartitions = []
        if (userAction.type == 'non-understanding'):
                # silent doesn't split
            pass
        else:
            for field in userAction.content.keys():
                if (field == 'confirm'):
                    continue
                val = userAction.content[field]
                if (self.fields[field].type == 'equals'):
                    # Cant split this partition -- field already equals something
                    pass
                elif (val in self.fields[field].excludes):
                    # Cant split this partition -- field exludes this value already
                    pass
                else:
                    newPartition = Partition(existingPartition=self,fieldToSplit=field,value=val)
                    if (newPartition.count > 0):
                        self.fields[field].excludes[val] = True
                        self.count -= newPartition.count
                        self.prior = 1.0 * self.count / self.totalCount
                        self.priorOfField[field] = 1.0 - 1.0 * len(self.fields[field].excludes.keys())/self.countOfField[field]
                        newPartitions.append(newPartition)
        return newPartitions

    # This will only be called on a child with no children
    def Recombine(self,child):
        '''
        Attempts to recombine child partition with this (parent) partition.  If
        possible, does the recombination and returns True.  If not possible,
        makes no changes and returns False.
        '''
        fieldsToRecombine = []
        for field in self.fields:
            if (self.fields[field].type == 'excludes'):
                if (child.fields[field].type == 'equals'):
                # parent excludes, child equals
                    value = child.fields[field].equals
                    if (value in self.fields[field].excludes):
                        fieldsToRecombine.append((field,value))
                    else:
                        raise RuntimeError, 'Error: field %s: child equals %s but parent doesnt exclude it' % (field,value)
                else:
                    # parent excludes, child excludes
                    # ensure they exclude the same things
                    if (not len(self.fields[field].excludes) == len(child.fields[field].excludes)):
                        return False
                    for val in self.fields[field].excludes:
                        if (val not in child.fields[field].excludes):
                            return False
                    pass
            else:
                if (child.fields[field].type == 'equals'):
                    # parent equals, child equals (must be equal)
                    pass
                else:
                    raise RuntimeError,'Error: field %s: parent equals %s but child excludes this field' % (field,value)
        if (len(fieldsToRecombine) == 0):
            raise RuntimeError,'Error: parent and child are identical'
        if (len(fieldsToRecombine) > 1):
            raise RuntimeError,'Error: parent and child differ by more than 1 field: %s' % (fieldsToRecombine)
        self.count += child.count
        self.prior = 1.0 * self.count / self.totalCount
        del self.fields[fieldsToRecombine[0][0]].excludes[ fieldsToRecombine[0][1] ]
        return True

    def __str__(self):
        '''
        Renders this partition as a string.  Example:

          city x();state x();last x(WILLIAMS);first=JASON;count=386

        This is the partition of 386 listings which have first name
        JASON, and do NOT have last name WILLIAMS (located in any city
        and any state).
        '''
        s = ''
        if (len(self.fields) > 0):
            elems = []
            for conceptName in self.fieldList:
                if (self.fields[conceptName].type == 'equals') :
                    elems.append('%s=%s' % (conceptName,self.fields[conceptName].equals))
                elif (len(self.fields[conceptName].excludes) <= 2):
                    elems.append('%s x(%s)' % (conceptName,','.join(self.fields[conceptName].excludes.keys())))
                else:
                    elems.append('%s x([%d entries])' % (conceptName,len(self.fields[conceptName].excludes)))
            elems.append('count=%d' % (self.count))
            s = ';'.join(elems)
        else:
            s = "(all)"
        return s

    def _getClosestUserAct(self,userAction):
        if userAction.type == 'non-understanding':
            return 'non-understanding'
      
        acts = [['I:ap','I:bn','I:dp','I:tt'],\
                      ['I:ap','I:bn','I:dp'],\
                      ['I:ap','I:dp','I:tt'],\
                      ['I:bn','I:dp','I:tt'],\
                      ['I:ap','I:dp'],\
                      ['I:bn','I:tt'],\
                      ['I:bn'],\
                      ['I:dp'],\
                      ['I:ap'],\
                      ['I:tt'],\
                      ['yes'],\
                      ['no']]
        ua = []
        for field in userAction.content:
            if field == 'confirm':
                ua.append('yes' if userAction.content[field] == 'YES' else 'no')
            elif field == 'route':
                ua.append('I:bn')
            elif field == 'departure_place':
                ua.append('I:dp')
            elif field == 'arrival_place':
                ua.append('I:ap')
            elif field == 'travel_time':
                ua.append('I:tt')
        
        score = [float(len(set(act).intersection(set(ua))))/len(set(act).union(set(ua))) for act in acts] 
        closestUserAct = ','.join(acts[score.index(max(score))])
#        self.appLogger.info('Closest user action %s'%closestUserAct) 
        return closestUserAct

    def UserActionLikelihood(self, userAction, history, sysAction):
        '''
        Returns the probability of the user taking userAction given dialog
        history, sysAction, and that their goal is within this partition.
        '''
#        if (sysAction.type == 'ask'):
#            if (sysAction.force == 'request'):
#                if (userAction.type == 'non-understanding'):
#                    result = self.umParams['request_nonUnderstandingProb']
#                else:
#                    targetFieldIncludedFlag = False
#                    overCompleteFlag = False
#                    allFieldsMatchGoalFlag = True
#                    askedField = sysAction.content
#                    for field in userAction.content:
#                        if field == 'confirm':
#                            allFieldsMatchGoalFlag = False
#                            continue
#                        val = userAction.content[field]
#                        if (self.fields[field].type == 'equals' and self.fields[field].equals == val):
#                            if (field == askedField):
#                                targetFieldIncludedFlag = True
#                            else:
#                                overCompleteFlag = True
#                        else:
#                            allFieldsMatchGoalFlag = False
#                    if (not allFieldsMatchGoalFlag):
#                        # This action doesn't agree with this partition
#                        result = 0.0
#                    elif (askedField == 'all'):
#                        # A response to the open question
#                        result = self.umParams['open_answerProb']
#                    elif (not targetFieldIncludedFlag):
#                        # This action doesn't include the information that was asked for
#                        # This user model doesn't ever do this
#                        result = 0.0
#                    elif (overCompleteFlag):
#                        # This action include extra information - this happens
#                        # request_overCompleteProb amount of the time
#                        result = self.umParams['request_overCompleteProb']
#                    else:
#                        # This action just answers the question that was asked
#                        result = self.umParams['request_directAnswerProb']
#            elif (sysAction.force == 'confirm'):
#                if (userAction.type == 'non-understanding'):
#                    result = self.umParams['confirm_nonUnderstandingProb']
#                else:
#                    allFieldsMatchGoalFlag = True
#                    for field in sysAction.content:
#                        val = sysAction.content[field]
#                        if (self.fields[field].type == 'excludes' or not self.fields[field].equals == val):
#                            allFieldsMatchGoalFlag = False
#                    if (allFieldsMatchGoalFlag):
#                        if (userAction.content['confirm'] == 'YES'):
#                            result = self.umParams['confirm_directAnswerProb']
#                        else:
#                            result = 0.0
#                    else:
#                        if (userAction.content['confirm'] == 'NO'):
#                            result = self.umParams['confirm_directAnswerProb']
#                        else:
#                            result = 0.0
#            else:
#                raise RuntimeError, 'Dont know sysAction.force = %s' % (sysAction.force)
        if not self.useLearnedUserModel:
            result = 0.0
            if (sysAction.type == 'ask'):
                if (userAction.type == 'non-understanding'):
                    if (sysAction.force == 'confirm'):
                        result = self.umParams['confirm_nonUnderstandingProb']
                    else: 
                        result = self.umParams['request_nonUnderstandingProb']
                else:
                    targetFieldIncludedFlag = False
                    overCompleteFlag = False
                    allFieldsMatchGoalFlag = True
                    askedField = sysAction.content
                    for field in userAction.content:
                        if field == 'confirm':
                            if sysAction.force == 'request':
                                allFieldsMatchGoalFlag = False
                                continue
                            for field in sysAction.content:
                                val = sysAction.content[field]
                                if (self.fields[field].type == 'excludes' or not self.fields[field].equals == val):
                                    allFieldsMatchGoalFlag = False
                            if (allFieldsMatchGoalFlag):
                                if (userAction.content['confirm'] == 'YES'):
                                    result = self.umParams['confirm_directAnswerProb']
                                    targetFieldIncludedFlag = True
                                else:
                                    result = self.umParams['request_irrelevantAnswerProb']
                            else:
                                if (userAction.content['confirm'] == 'NO'):
                                    result = self.umParams['confirm_directAnswerProb']
                                    targetFieldIncludedFlag = True
                                else:
                                    result = self.umParams['request_irrelevantAnswerProb']
                        else:
                            val = userAction.content[field]
                            if (self.fields[field].type == 'equals' and self.fields[field].equals == val):
                                if (field == askedField):
                                    targetFieldIncludedFlag = True
                                else:
                                    overCompleteFlag = True
                            else:
                                allFieldsMatchGoalFlag = False
                    if (not allFieldsMatchGoalFlag):
                        # This action doesn't agree with this partition
                        result = self.umParams['request_irrelevantAnswerProb']
                    elif (askedField == 'all'):
                        # A response to the open question
                        result = self.umParams['open_answerProb']
                    elif (not targetFieldIncludedFlag):
                        # This action doesn't include the information that was asked for
                        # This user model doesn't ever do this
                        result = self.umParams['request_irrelevantAnswerProb']
                    elif (overCompleteFlag):
                        # This action include extra information - this happens
                        # request_overCompleteProb amount of the time
                        result = self.umParams['request_overCompleteProb']
                    else:
                        # This action just answers the question that was asked
                        result = result if result > 0 else self.umParams['request_directAnswerProb']
            else:
                raise RuntimeError, 'Dont know sysAction.type = %s' % (sysAction.type)
        else:
#            self.appLogger.info('Apply learned user model')
            if sysAction.type != 'ask':
                raise RuntimeError, 'Cannot handle sysAction %s'%str(sysAction)
            result = self.irrelevantUserActProb
            allFieldsMatchGoalFlag = True
            directAnswer = False
            if sysAction.force == 'confirm':
                askedField = sysAction.content.keys()[0]
                if userAction.type != 'non-understanding':
                    for ua_field in userAction.content:
                        self.appLogger.info('User action field: %s:%s'%(ua_field,userAction.content[ua_field]))
                        if ua_field == 'confirm' and userAction.content[ua_field] == 'YES':
                            val = sysAction.content[askedField]
                            if self.fields[askedField].type == 'excludes' or not self.fields[askedField].equals == val:
                                self.appLogger.info('Mismatched YES')
                                allFieldsMatchGoalFlag = False
                        elif ua_field == 'confirm' and userAction.content[ua_field] == 'NO':
                            val = sysAction.content[askedField]
                            if (self.fields[askedField].type == 'equals' and self.fields[askedField].equals == val) or\
                            (self.fields[askedField].type == 'excludes' and val not in self.fields[askedField].excludes):
                                self.appLogger.info('Mismatched NO')
                                allFieldsMatchGoalFlag = False
                        elif askedField == ua_field:
                            directAnswer = True
#                            val = sysAction.content[askedField]
#                            if self.fields[askedField].type != 'excludes' and \
#                            self.fields[askedField].equals == userAction.content[askedField]:
#                                self.appLogger.info('Matched %s'%userAction.content[askedField])
#                                allFieldsMatchGoalFlag = True
                            if self.fields[askedField].type == 'excludes' or \
                            self.fields[askedField].equals != userAction.content[askedField]:
                                self.appLogger.info('Mismatched %s'%userAction.content[askedField])
                                allFieldsMatchGoalFlag = False
                        else:
                            val = userAction.content[ua_field]
                            if self.fields[ua_field].type == 'excludes' or not self.fields[ua_field].equals == val:
                                if not ((ua_field == 'arrival_place' and 'departure_place' in userAction.content and \
                                userAction.content['departure_place'] == userAction.content['arrival_place'] and \
                                self.fields['departure_place'].type == 'equals' and \
                                self.fields['departure_place'].equals == userAction.content['departure_place']) or\
                                (ua_field == 'departure_place' and 'arrival_place' in userAction.content and \
                                userAction.content['departure_place'] == userAction.content['arrival_place'] and \
                                self.fields['arrival_place'].type == 'equals' and \
                                self.fields['arrival_place'].equals == userAction.content['arrival_place'])):
                                    self.appLogger.info('Mismatched %s in field %s'%(val,ua_field))
                                    allFieldsMatchGoalFlag = False
                elif self.ignoreNonunderstandingFactor:
                    allFieldsMatchGoalFlag = False
                if allFieldsMatchGoalFlag:
                    self.appLogger.info('All fields matched')
                    if (userAction.type != 'non-understanding' and 'confirm' in userAction.content and userAction.content['confirm'] == 'YES') or\
                    directAnswer:
                        result = self.userModel['C-o'][self._getClosestUserAct(userAction)]
                    else:
                        if userAction.type != 'non-understanding' and 'confirm' in userAction.content and directAnswer:
                            del userAction.content['confirm']
                        if 'departure_place' in userAction.content and 'arrival_place' in userAction.content and \
                        userAction.content['departure_place'] == userAction.content['arrival_place']:
                            tempUserAction = deepcopy(userAction)
                            del tempUserAction.content['arrival_place']
                            result = self.userModel['C-x'][self._getClosestUserAct(tempUserAction)]
                        else:
                            result = self.userModel['C-x'][self._getClosestUserAct(userAction)]
                    self.appLogger.info('User action likelihood %g'%result)
                    result = self.minRelevantUserActProb if result < self.minRelevantUserActProb else result
                    self.appLogger.info('Set minimum user action likelihood %g'%result)
            elif sysAction.force == 'request':
                askedField = sysAction.content
                if userAction.type != 'non-understanding':
                    for ua_field in userAction.content:
                        if ua_field != 'confirm':
                            val = userAction.content[ua_field]
                            if self.fields[ua_field].type == 'excludes' or not self.fields[ua_field].equals == val:
                                if not ((ua_field == 'arrival_place' and 'departure_place' in userAction.content and \
                                userAction.content['departure_place'] == userAction.content['arrival_place'] and \
                                self.fields['departure_place'].type == 'equals' and \
                                self.fields['departure_place'].equals == userAction.content['departure_place']) or\
                                (ua_field == 'departure_place' and 'arrival_place' in userAction.content and \
                                userAction.content['departure_place'] == userAction.content['arrival_place'] and \
                                self.fields['arrival_place'].type == 'equals' and \
                                self.fields['arrival_place'].equals == userAction.content['arrival_place'])):
                                    self.appLogger.info('Mismatched %s in field %s'%(val,ua_field))
                                    allFieldsMatchGoalFlag = False
                elif self.ignoreNonunderstandingFactor:
                    allFieldsMatchGoalFlag = False
                if allFieldsMatchGoalFlag:
                    if askedField == 'route':
#                        print self.userModel['R-bn']
                        result = self.userModel['R-bn'][self._getClosestUserAct(userAction)]
                    elif askedField == 'departure_place':
#                        print self.userModel['R-dp']
                        result = self.userModel['R-dp'][self._getClosestUserAct(userAction)]
                    elif askedField == 'arrival_place':
#                        print self.userModel['R-ap']
                        result = self.userModel['R-ap'][self._getClosestUserAct(userAction)]
                    elif askedField == 'travel_time':
#                        print self.userModel['R-tt']
                        if 'departure_place' in userAction.content and 'arrival_place' in userAction.content and \
                        userAction.content['departure_place'] == userAction.content['arrival_place']:
                            tempUserAction = deepcopy(userAction)
                            del tempUserAction.content['arrival_place']
                            result = self.userModel['R-tt'][self._getClosestUserAct(tempUserAction)]
                        else:
                            result = self.userModel['R-tt'][self._getClosestUserAct(userAction)]
                    elif askedField == 'all':
#                        print self.userModel['R-open']
                        if 'departure_place' in userAction.content and 'arrival_place' in userAction.content and \
                        userAction.content['departure_place'] == userAction.content['arrival_place']:
                            tempUserAction = deepcopy(userAction)
                            del tempUserAction.content['arrival_place']
                            result = self.userModel['R-open'][self._getClosestUserAct(tempUserAction)]
                        else:
                            result = self.userModel['R-open'][self._getClosestUserAct(userAction)]
                    self.appLogger.info('User action likelihood %g'%result)
                    result = self.minRelevantUserActProb if result < self.minRelevantUserActProb else result
                    self.appLogger.info('Set minimum user action likelihood %g'%result)
        return result
    
    def UserActionUnlikelihood(self, userAction, history, sysAction):
        '''
        Returns the probability of the user not taking userAction given dialog
        history, sysAction, and that their goal is within this partition.
        '''
        if sysAction.type != 'ask':
            raise RuntimeError, 'Dont know sysAction.type = %s' % (sysAction.type)

#        self.appLogger.info('Apply confirmUnlikelyDiscountFactor %f'%self.confirmUnlikelyDiscountFactor)
        if sysAction.force == 'request':
            result = self.prior
            reason = 'request'
        elif sysAction.force == 'confirm':
            result = self.confirmUnlikelyDiscountFactor * self.prior
            reason = 'confirm'
#        self.appLogger.info('UserActionUnlikelihood by (%s): %g'%(reason,result))
        return result
Beispiel #4
0
class Grammar():
    '''
    Class representing a grammar.  The cardinality of a grammar
    (i.e., how many distinct utterances it can recognize) is
    available in

      grammar.cardinality

    Configuration option:

      [Grammar]
      useSharedGrammars: only relevant when using an interactive dialog manager
      with ASR on the AT&T Speech Mashup platform.  If 'true', then Grammar.GetFullName
      returns the public, shared versions of the grammars (e.g.,
      'asdt-demo-shared.db100k.all').  If 'false', Grammar.GetFullName returns the
      private versions of the grammars (e.g., 'db100k.all').  If you have not
      generated and built your own grammars, set this to 'false'.

    '''
    MY_ID = 'Grammar'
    def __init__(self,name):
        '''
        The "name" of the grammar is either:

          - a field name from the DB
          - "confirm" (which accepts "yes" and "no") only
          - "all" (which accepts any ordered subset of any listing, like
            "JASON" or "JASON WILLIAMS" or "JASON NEW YORK"

        '''
        self.config = GetConfig()
        db = GetDB()
#        assert (name in db.GetFields() or name in ['all','confirm']),'Unknown Grammar name: %s' % (name)
        assert (name in ['route','departure_place','arrival_place','travel_time'] or name in ['all','confirm']),'Unknown Grammar name: %s' % (name)
        
        self.name = name
        if (self.name == 'confirm'):
            self.fullName = 'confirm'
        else:
            stem = db.GetDBStem()
            self.fullName = '%s.%s' % (stem,self.name)
        if (self.config.has_option(self.MY_ID,'useSharedGrammars') and self.config.getboolean(self.MY_ID,'useSharedGrammars')):
            if (self.name == 'all'):
                self.fullName = 'asdt-demo-shared.%s.loc' % (self.fullName)
            else:
                self.fullName = 'asdt-demo-shared.%s' % (self.fullName)
        if (name == 'confirm'):
            self.cardinality = 2
        elif (name == 'all'):
            fields = ['route','departure_place','arrival_place','travel_time']#db.GetFields()
            fieldCount = len(fields)
            fieldCombos = 0
            for r in range(fieldCount):
                fieldCombos += Combination(fieldCount,r)
            self.cardinality = db.GetListingCount({}) * fieldCombos
        else:
            self.cardinality = db.GetFieldSize(self.name)

    def GetFullName(self):
        '''
        Returns the "fullName" of a grammar, i.e.,

          fullName.grxml

        For example, the "name" might be "first", but the "fullName"
        is "db-100k.first"
        '''
        return self.fullName

    def __str__(self):
        return '%s:%d' % (self.name,self.cardinality)