def __init__(self, dm): """create questioner agent""" threading.Thread.__init__(self) self.dialogManager = dm self.episodicBuffer = EpisodicBuffer() self.semanticKnowledge = SemanticKnowledge() self.lexicalAccess = LexicalAccess() # start with a uniform belief prior flat = nltk.probability.UniformProbDist( self.semanticKnowledge.entities()) self.semanticKnowledge.setPriors(flat) self.state = None self.daemon = True #important!
def __init__(self,dm): """create questioner agent""" threading.Thread.__init__(self) self.dialogManager = dm self.episodicBuffer = EpisodicBuffer() self.semanticKnowledge = SemanticKnowledge() self.lexicalAccess = LexicalAccess() # start with a uniform belief prior flat = nltk.probability.UniformProbDist(self.semanticKnowledge.entities()) self.semanticKnowledge.setPriors(flat) self.state = None self.daemon = True #important!
for q in questions: if not q in seen: seen.append(q) #if(ans == "yes"): Q.append(q) #else: # Q.appendleft(q) except KeyError: successors = [] def ask(qgloss): a = "other" #q = L.lookUp(qgloss) q = qgloss userInput = raw_input(q + "\n? ") if userInput.find("yes") == 0: a = "yes" if userInput.find("no") == 0: a = "no" return a D = DialogGraph() L = LexicalAccess() T = bfs_tree(D, "Emotion") s = bfs_successors(T, "Emotion") U = D.to_undirected() pr = nx.algorithms.link_analysis.pagerank(U) search20q(D, pr)
class QuestionerAgent(threading.Thread): """An agent that asks questions""" def __init__(self,dm): """create questioner agent""" threading.Thread.__init__(self) self.dialogManager = dm self.episodicBuffer = EpisodicBuffer() self.semanticKnowledge = SemanticKnowledge() self.lexicalAccess = LexicalAccess() # start with a uniform belief prior flat = nltk.probability.UniformProbDist(self.semanticKnowledge.entities()) self.semanticKnowledge.setPriors(flat) self.state = None self.daemon = True #important! def run(self): """thread main loop""" self.send("[Agent enters the Universe of Discourse]") self.toInitialState() try: while True: self.repl() except Exception as e: self.send(e) def repl(self): """ read-evaluate-print loop. note: _read, _eval, and _print are monkey patched """ #self._enterReplState() while True: #self._print(self._eval(self._read())) tmp = self._read() tmp = self._eval(tmp) self._print(tmp) tmp = None def welcomeMessage(self): """prints welcome message""" self.send("Welcome to Emo20Q") self.send("I'm going to try to guess the emotion you are thinking of") self.send("it needn't be the emotion you are currently feeling") self.send("Let me know when you are ready") def toInitialState(self): """enter initial state""" self.state = "initial" #self._enterReplState = self.welcomeMessage self.welcomeMessage() #self._read = self.receivePatiently self._read = self.receive self._eval = lambda i: self.startIfReady(i) self._print = lambda i: self.send(i) def startIfReady(self,i): """checks if user is ready to start match""" if nlp.isReady(i): return self.toAskingState() else: return "let me know when you are ready" def toAskingState(self): """enter question asking state""" self.state = "asking" self._read = self.semanticYnReceivePatiently self._eval = self.evalAndAsk self._print = self.semanticSend self.send("Okay, let me see here...") return self.evalAndAsk() def toGuessingState(self,q): """enter guessing/confirmation state""" self.state = "guessing" self._read = self.semanticYnReceivePatiently self._eval = self.confirmGuess self._print = self.semanticSend return q def toBetweenMatchesState(self): """enter guessing/confirmation state""" self.state = "betweenMatches" self._read = self.receive self._eval = lambda i: self.continueOrQuit(i) self._print = lambda i: self.send(i) return "Would you like to play again?" def continueOrQuit(self,i): """checks if user is ready to start match""" if nlp.isReady(i): #reset prior flat = nltk.probability.UniformProbDist(self.semanticKnowledge.entities()) self.semanticKnowledge.setPriors(flat) self.episodicBuffer.newMatch() return self.toAskingState() elif nlp.classifyYN(i) == -1: self.current_thread().exit() #sys.exit() else: return "let me know when you are ready" def evalAndAsk(self,*args): if self.episodicBuffer.turnCount > 20: self.send("Dammit, I failed. ") return self.toBetweenMatchesState() #if args: #self.send("you said %s " % str(args[0])) # check for semantically relevant and mnemonically accessible items in # the episodic buffer agentTurns = filter(lambda i: i['semantics'] is not None and i['talker'] == "me", self.episodicBuffer) userTurns = filter(lambda i: i['semantics'] is not None and i['talker'] == "you", self.episodicBuffer) #list features features = {} #self.send("my episodic buffer has %d units of information" % # len(userTurns)) for (a,u) in zip(agentTurns,userTurns): #self.send("I asked '%s'" % a['utterance']) #self.send("...and you said '%s'" % u['utterance']) f = self.getFeature(a,u) #self.send("which I interpreted as '%s'" % str(f)) for k,v in f.items(): features[k] = v if len(features) == 0: #if True: #return self.pickNextQuestion(self,features) return "e.valence==positive" #return "e==happiness" else: #update probabilities try: #post = self.semanticKnowledge.prob_classify({"e.valence==postive":"yes"}) post = self.semanticKnowledge.prob_classify(f) #self.send("Based on this data, I think you may have picked one of the following") #out = ", ".join(sorted(post.samples(),key=post.prob,reverse=True)[0:10]) #self.send(out) self.semanticKnowledge.setPriors(post) #self.send("But I will continue to ask...") #self.sendHesitation nextQuestion = self.pickNextQuestion(features) # switch to guessing emotion identity if the next # question is an identity question, if(re.search(r"^e==",nextQuestion)): return self.toGuessingState(nextQuestion) return nextQuestion except Exception as e: self.send(e) def confirmGuess(self,i): """checks if the guess is correct to start match""" if nlp.isAffirmative(i): self.send("yeah! Thanks for playing",1.5) return self.toBetweenMatchesState() else: #self.send("okay, I'll continue, but just let me update by belief vector") agentTurns = filter(lambda i: i['semantics'] is not None and i['talker'] == "me", self.episodicBuffer) tmpGloss = agentTurns[-1]['semantics'] match = re.search(r'^e==(.+)$', tmpGloss) if(match): tmpEmo = match.group(1) tmpDict = dict((key, self.semanticKnowledge._label_probdist.prob(key)) for key in self.semanticKnowledge._label_probdist.samples()) tmpDict[tmpEmo] = 0 self.semanticKnowledge._label_probdist = DictionaryProbDist(tmpDict,normalize=True) #assert(self.semanticKnowledge._label_probdist.prob(tmpEmo)==0) return self.toAskingState() else: #there was some kind of error self.send("oops, I misinterpreted some stuff and must quit") self.send(Exception()) def getFeature(self,agentTurn,userTurn): if("semantics" not in agentTurn or "semantics" not in userTurn): raise Exception("no freaking semantics") answer = None if userTurn['semantics'] == 1 : answer = "yes" if userTurn['semantics'] == 0 : answer = "other" if userTurn['semantics'] == -1 : answer = "no" return {agentTurn['semantics']:answer} def pickNextQuestion(self,features): #sort the question/features by probability of being != None #self.send("starting to pick next question based on the following features in my episodic buffer: %s" % str(features)) def sumNotNone(probdist): return sum([probdist.prob(x) for x in ("yes","no","other")]) def sumYes(probdist): return probdist.prob("yes") probYes = defaultdict(float) for ((label, fname), probdist) in self.semanticKnowledge._feature_probdist.items(): #probNotNone[fname] += sumNotNone(probdist)*self.semanticKnowledge._label_probdist.prob(label) probYes[fname] += sumYes(probdist)*self.semanticKnowledge._label_probdist.prob(label) #we pick the question that is the maximum probability of being yes #among the questions not asked already result = max([x for x in probYes if x not in features],key=probYes.__getitem__) match = re.search(r'^e==(.+)$', result) # if identity question or turnCount==20, choose from belief vector if match or self.episodicBuffer.turnCount>=20: guess = sorted(self.semanticKnowledge._label_probdist.samples(),key=self.semanticKnowledge._label_probdist.prob,reverse=True)[0] return "e==%s" % guess else: return result def send(self,msg,delay=0.5): """sends a message, with optional delay""" time.sleep(delay) self.episodicBuffer.addTurn("me",msg,self.state) self.dialogManager.inputBuffer.put(("agent",msg)) def semanticSend(self,gloss,delay=1): """ sends a message, with optional delay Also, it addes information to the episodic buffer """ msg = self.lexicalAccess.lookUp(gloss) time.sleep(delay) self.send("question %d: " % self.episodicBuffer.turnCount) self.episodicBuffer.addTurn("me",msg,self.state,gloss) self.dialogManager.inputBuffer.put(("agent",msg)) def receive(self): """receives a message""" msg = self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() self.episodicBuffer.addTurn("you",msg,self.state) return msg def receivePatiently(self): """receives a message while waiting for additional messages""" msg = self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() while True: time.sleep(2) if self.dialogManager.toAgentBuffer.empty(): break msg = msg + "\n" + self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() self.episodicBuffer.addTurn("you",msg,self.state) return msg def semanticYnReceivePatiently(self): """ receives a YN message while waiting for additional messages Also, it addes information to the episodic buffer """ msg = self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() while True: time.sleep(2) if self.dialogManager.toAgentBuffer.empty(): break msg = msg + "\n" + self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() sem = nlp.classifyYN(msg) self.episodicBuffer.addTurn("you",msg,self.state,semantics=sem) return msg
def __init__(self, episodicBuffer=EpisodicBuffer(), semanticKnowledge=SemanticKnowledge(), lexicalAccess=LexicalAccess()): super(QuestionerAgent, self).__init__() self.episodicBuffer = episodicBuffer self.semanticKnowledge = semanticKnowledge self.lexicalAccess = lexicalAccess self.stack = self.episodicBuffer self.belief = nltk.probability.UniformProbDist( self.semanticKnowledge.entities()) # to welcome message from startState self.add_transition( self.startState, self.welcomeState, test=lambda x: True, #transition on any input function=self.welcomeMessage) # reprompt til ready (loop in welcomeState) self.add_transition( self.welcomeState, self.welcomeState, test=lambda x: not emo20q.nlp.isReady(x), function=lambda x: "Let me know when you are ready... (some people get stuck here... try typing something into the box to let me know whether you are ready, or not)", ) #start match, to asking state from welcomeState self.add_transition(self.welcomeState, self.askingState, test=emo20q.nlp.isReady, function=self.beginPlaying) #main asking loop self.add_transition(self.askingState, self.askingState, test=self.shouldIAsk, function=self.evaluateQuestionAnswer) self.add_transition(self.askingState, self.confirmingState, test=lambda x: emo20q.nlp.isAffirmative(x) and self .episodicBuffer[-1].isIdentityQuestion(), function=self.confirmAnswer) #sucess! to betweenMatchesState from confirmingState self.add_transition( self.confirmingState, self.betweenMatchesState, test=emo20q.nlp.isAffirmative, function=lambda x: self.doYouWantToPlayAgain(x, outcome="success")) #a failed guess w/ <20 questions, to askingState from confirmingState self.add_transition(self.confirmingState, self.askingState, test=lambda x: not emo20q.nlp.isAffirmative(x) and self.shouldIAsk(x), function=self.evaluateQuestionAnswer) #a failed guess, >20 questions, to reviewingState self.add_transition(self.confirmingState, self.reviewingState, test=lambda x: not emo20q.nlp.isAffirmative(x) and self.episodicBuffer.numTurns() >= 20, function=self.reviewAnswerAfterDisconfirm) #ran out of questions, ask what the emotion was, to reviewingState self.add_transition(self.askingState, self.reviewingState, test=self.shouldIReview, function=self.reviewAnswer) #failed match, but try again, to betweenMatchesState from reviewingState self.add_transition( self.reviewingState, self.betweenMatchesState, test=lambda x: True, function=lambda x: self.doYouWantToPlayAgain(x, outcome="failure")) #replay self.add_transition(self.betweenMatchesState, self.welcomeState, test=emo20q.nlp.isReady, function=self.replayMessage) #no replay self.add_transition(self.betweenMatchesState, self.endState, test=lambda x: not emo20q.nlp.isAffirmative(x), function=self.goodbyeMessage) self.state = self.startState
class QuestionerAgent(threading.Thread): """An agent that asks questions""" def __init__(self, dm): """create questioner agent""" threading.Thread.__init__(self) self.dialogManager = dm self.episodicBuffer = EpisodicBuffer() self.semanticKnowledge = SemanticKnowledge() self.lexicalAccess = LexicalAccess() # start with a uniform belief prior flat = nltk.probability.UniformProbDist( self.semanticKnowledge.entities()) self.semanticKnowledge.setPriors(flat) self.state = None self.daemon = True #important! def run(self): """thread main loop""" self.send("[Agent enters the Universe of Discourse]") self.toInitialState() try: while True: self.repl() except Exception as e: self.send(e) def repl(self): """ read-evaluate-print loop. note: _read, _eval, and _print are monkey patched """ #self._enterReplState() while True: #self._print(self._eval(self._read())) tmp = self._read() tmp = self._eval(tmp) self._print(tmp) tmp = None def welcomeMessage(self): """prints welcome message""" self.send("Welcome to Emo20Q") self.send("I'm going to try to guess the emotion you are thinking of") self.send("it needn't be the emotion you are currently feeling") self.send("Let me know when you are ready") def toInitialState(self): """enter initial state""" self.state = "initial" #self._enterReplState = self.welcomeMessage self.welcomeMessage() #self._read = self.receivePatiently self._read = self.receive self._eval = lambda i: self.startIfReady(i) self._print = lambda i: self.send(i) def startIfReady(self, i): """checks if user is ready to start match""" if nlp.isReady(i): return self.toAskingState() else: return "let me know when you are ready" def toAskingState(self): """enter question asking state""" self.state = "asking" self._read = self.semanticYnReceivePatiently self._eval = self.evalAndAsk self._print = self.semanticSend self.send("Okay, let me see here...") return self.evalAndAsk() def toGuessingState(self, q): """enter guessing/confirmation state""" self.state = "guessing" self._read = self.semanticYnReceivePatiently self._eval = self.confirmGuess self._print = self.semanticSend return q def toBetweenMatchesState(self): """enter guessing/confirmation state""" self.state = "betweenMatches" self._read = self.receive self._eval = lambda i: self.continueOrQuit(i) self._print = lambda i: self.send(i) return "Would you like to play again?" def continueOrQuit(self, i): """checks if user is ready to start match""" if nlp.isReady(i): #reset prior flat = nltk.probability.UniformProbDist( self.semanticKnowledge.entities()) self.semanticKnowledge.setPriors(flat) self.episodicBuffer.newMatch() return self.toAskingState() elif nlp.classifyYN(i) == -1: self.current_thread().exit() #sys.exit() else: return "let me know when you are ready" def evalAndAsk(self, *args): if self.episodicBuffer.turnCount > 20: self.send("Dammit, I failed. ") return self.toBetweenMatchesState() #if args: #self.send("you said %s " % str(args[0])) # check for semantically relevant and mnemonically accessible items in # the episodic buffer agentTurns = filter( lambda i: i['semantics'] is not None and i['talker'] == "me", self.episodicBuffer) userTurns = filter( lambda i: i['semantics'] is not None and i['talker'] == "you", self.episodicBuffer) #list features features = {} #self.send("my episodic buffer has %d units of information" % # len(userTurns)) for (a, u) in zip(agentTurns, userTurns): #self.send("I asked '%s'" % a['utterance']) #self.send("...and you said '%s'" % u['utterance']) f = self.getFeature(a, u) #self.send("which I interpreted as '%s'" % str(f)) for k, v in f.items(): features[k] = v if len(features) == 0: #if True: #return self.pickNextQuestion(self,features) return "e.valence==positive" #return "e==happiness" else: #update probabilities try: #post = self.semanticKnowledge.prob_classify({"e.valence==postive":"yes"}) post = self.semanticKnowledge.prob_classify(f) #self.send("Based on this data, I think you may have picked one of the following") #out = ", ".join(sorted(post.samples(),key=post.prob,reverse=True)[0:10]) #self.send(out) self.semanticKnowledge.setPriors(post) #self.send("But I will continue to ask...") #self.sendHesitation nextQuestion = self.pickNextQuestion(features) # switch to guessing emotion identity if the next # question is an identity question, if (re.search(r"^e==", nextQuestion)): return self.toGuessingState(nextQuestion) return nextQuestion except Exception as e: self.send(e) def confirmGuess(self, i): """checks if the guess is correct to start match""" if nlp.isAffirmative(i): self.send("yeah! Thanks for playing", 1.5) return self.toBetweenMatchesState() else: #self.send("okay, I'll continue, but just let me update by belief vector") agentTurns = filter( lambda i: i['semantics'] is not None and i['talker'] == "me", self.episodicBuffer) tmpGloss = agentTurns[-1]['semantics'] match = re.search(r'^e==(.+)$', tmpGloss) if (match): tmpEmo = match.group(1) tmpDict = dict( (key, self.semanticKnowledge._label_probdist.prob(key)) for key in self.semanticKnowledge._label_probdist.samples()) tmpDict[tmpEmo] = 0 self.semanticKnowledge._label_probdist = DictionaryProbDist( tmpDict, normalize=True) #assert(self.semanticKnowledge._label_probdist.prob(tmpEmo)==0) return self.toAskingState() else: #there was some kind of error self.send("oops, I misinterpreted some stuff and must quit") self.send(Exception()) def getFeature(self, agentTurn, userTurn): if ("semantics" not in agentTurn or "semantics" not in userTurn): raise Exception("no freaking semantics") answer = None if userTurn['semantics'] == 1: answer = "yes" if userTurn['semantics'] == 0: answer = "other" if userTurn['semantics'] == -1: answer = "no" return {agentTurn['semantics']: answer} def pickNextQuestion(self, features): #sort the question/features by probability of being != None #self.send("starting to pick next question based on the following features in my episodic buffer: %s" % str(features)) def sumNotNone(probdist): return sum([probdist.prob(x) for x in ("yes", "no", "other")]) def sumYes(probdist): return probdist.prob("yes") probYes = defaultdict(float) for ((label, fname), probdist) in self.semanticKnowledge._feature_probdist.items(): #probNotNone[fname] += sumNotNone(probdist)*self.semanticKnowledge._label_probdist.prob(label) probYes[fname] += sumYes( probdist) * self.semanticKnowledge._label_probdist.prob(label) #we pick the question that is the maximum probability of being yes #among the questions not asked already result = max([x for x in probYes if x not in features], key=probYes.__getitem__) match = re.search(r'^e==(.+)$', result) # if identity question or turnCount==20, choose from belief vector if match or self.episodicBuffer.turnCount >= 20: guess = sorted(self.semanticKnowledge._label_probdist.samples(), key=self.semanticKnowledge._label_probdist.prob, reverse=True)[0] return "e==%s" % guess else: return result def send(self, msg, delay=0.5): """sends a message, with optional delay""" time.sleep(delay) self.episodicBuffer.addTurn("me", msg, self.state) self.dialogManager.inputBuffer.put(("agent", msg)) def semanticSend(self, gloss, delay=1): """ sends a message, with optional delay Also, it addes information to the episodic buffer """ msg = self.lexicalAccess.lookUp(gloss) time.sleep(delay) self.send("question %d: " % self.episodicBuffer.turnCount) self.episodicBuffer.addTurn("me", msg, self.state, gloss) self.dialogManager.inputBuffer.put(("agent", msg)) def receive(self): """receives a message""" msg = self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() self.episodicBuffer.addTurn("you", msg, self.state) return msg def receivePatiently(self): """receives a message while waiting for additional messages""" msg = self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() while True: time.sleep(2) if self.dialogManager.toAgentBuffer.empty(): break msg = msg + "\n" + self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() self.episodicBuffer.addTurn("you", msg, self.state) return msg def semanticYnReceivePatiently(self): """ receives a YN message while waiting for additional messages Also, it addes information to the episodic buffer """ msg = self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() while True: time.sleep(2) if self.dialogManager.toAgentBuffer.empty(): break msg = msg + "\n" + self.dialogManager.toAgentBuffer.get() self.dialogManager.toAgentBuffer.task_done() sem = nlp.classifyYN(msg) self.episodicBuffer.addTurn("you", msg, self.state, semantics=sem) return msg