コード例 #1
0
 def say(self, session, answer):
     self.logger.info(u'say "%s"', answer)
     answer_interpretation = InterpretedPhrase(answer)
     answer_interpretation.is_bot_phrase = True
     answer_interpretation.set_modality(*self.modality_model.get_modality(
         answer, self.text_utils, self.word_embeddings))
     session.add_to_buffer(answer)
     session.add_phrase_to_history(answer_interpretation)
コード例 #2
0
ファイル: actors.py プロジェクト: yaroschak/chatbot
    def do_action(self, bot, session, interlocutor, interpreted_phrase):
        uttered = False

        wordbag = []
        for question in self.wordbag_questions:
            if bot.get_engine().does_bot_know_answer(question, bot, session, interlocutor):
                interpreted_phrase2 = InterpretedPhrase(question)
                answers = bot.get_engine().build_answers(session, bot, interlocutor, interpreted_phrase2)
                for answer in answers:
                    tokens = bot.get_engine().get_text_utils().tokenize(answer)
                    wordbag.extend((word, 1.0) for word in tokens)

        wordbag.extend((word, 1.0) for word in self.wordbag_words)

        if len(wordbag) > 0:
            replicas = []
            for template_str in self.templates:
                replicas1 = bot.get_engine().replica_grammar.generate_by_terms(template_str,
                                                                               wordbag,
                                                                               bot.get_engine().get_text_utils().known_words,
                                                                               use_assocs=False)
                replicas.extend(replicas1)

            if len(replicas) > 0:

                # Выбираем одну рандомную реплику среди сгенерированных.
                # TODO: взвешивать через модель уместности по контексту
                bot.say(session, bot.get_engine().select_relevant_replica(replicas, session, interlocutor))
                uttered = True

        return uttered
コード例 #3
0
    def do_action(self, bot, session, interlocutor, interpreted_phrase,
                  condition_matching_results, text_utils):
        if self.np_sources:
            if condition_matching_results is None:
                condition_matching_results = RuleConditionMatching.create(True)

            for np, question in self.np_sources.items():
                if bot.get_engine().does_bot_know_answer(
                        question, bot, session, interlocutor):
                    interpreted_phrase2 = InterpretedPhrase(question)
                    answers = bot.get_engine().build_answers(
                        session, bot, interlocutor, interpreted_phrase2)
                    if answers:
                        answer = answers[0]
                        tokens = text_utils.tokenize(answer)
                        tagsets = list(text_utils.postagger.tag(tokens))
                        lemmas = text_utils.lemmatizer.lemmatize(tagsets)

                        phrase_tokens = []
                        for word_index, (token, tagset, lemma) in enumerate(
                                zip(tokens, tagsets, lemmas)):
                            t = PhraseToken()
                            t.word = token
                            t.norm_word = token.lower()
                            t.lemma = lemma[2]
                            t.tagset = tagset[1]
                            t.word_index = word_index
                            phrase_tokens.append(t)

                        condition_matching_results.add_group(
                            np, tokens, phrase_tokens)
                    else:
                        return None

        # Сначала попробуем убрать из списка те реплики, которые мы уже произносили.
        new_utterances = []
        for utterance0 in self.phrases:
            utterance = self.prepare4saying(utterance0,
                                            condition_matching_results,
                                            text_utils)

            if '$' in utterance:
                # Не удалось подставить значение в один из $-слотов, значит
                # надо исключить фразу.
                continue

            if session.count_bot_phrase(utterance) == 0:
                if self.known_answer_policy == 'skip' and utterance[-1] == '?':
                    # Проверим, что бот еще не знает ответ на этот вопрос:
                    if bot.does_bot_know_answer(utterance, session,
                                                interlocutor):
                        continue

                new_utterances.append(utterance)

        uttered = False
        if len(new_utterances) > 0:
            # Выбираем одну из оставшихся фраз.
            if len(new_utterances) == 1:
                bot.say(session, new_utterances[0])
            else:
                bot.say(session, random.choice(new_utterances))
            uttered = True
        else:
            # Все фразы бот уже произнес
            # Если задан список фраз на случай исчерпания (типа "не знаю больше ничего про кошек"),
            # то выдадим одну из них.

            new_utterances = []
            for utterance0 in self.exhausted_phrases:
                utterance = self.prepare4saying(utterance0,
                                                condition_matching_results,
                                                text_utils)

                if '$' in utterance:
                    # Не удалось подставить значение в один из $-слотов, значит
                    # надо исключить фразу.
                    continue

                if session.count_bot_phrase(utterance) == 0:
                    if self.known_answer_policy == 'skip' and utterance[
                            -1] == '?':
                        # Проверим, что бот еще не знает ответ на этот вопрос:
                        if bot.does_bot_know_answer(utterance, session,
                                                    interlocutor):
                            continue

                    new_utterances.append(utterance)

            if new_utterances:
                bot.say(session, random.choice(new_utterances))
                uttered = True
            else:
                if self.known_answer_policy == 'skip':
                    pass
                else:
                    # Начиная с этого момента данное правило будет повторно выдавать
                    # одну из фраз.
                    #for src_phrase in sorted(self.phrases, key=lambda z: random.random()):
                    #    random_phrase = self.prepare4saying(src_phrase, condition_matching_results, text_utils)
                    #    if '$' not in random_phrase:
                    #        bot.say(session, random_phrase)
                    #        uttered = True
                    #        break
                    uttered = False

        return uttered
コード例 #4
0
    def interpret_phrase(self, bot, session, raw_phrase, internal_issuer):
        interpreted = InterpretedPhrase(raw_phrase)
        phrase = raw_phrase
        phrase_modality, phrase_person = self.modality_model.get_modality(
            phrase, self.text_utils, self.word_embeddings)
        phrase_is_question = phrase_modality == ModalityDetector.question

        # история фраз доступна в session как conversation_history
        was_interpreted = False

        last_phrase = session.conversation_history[-1] if len(
            session.conversation_history) > 0 else None

        if not internal_issuer:
            # Интерпретация вопроса собеседника (человека):
            # (H) Ты яблоки любишь?
            # (B) Да
            # (H) А виноград? <<----- == Ты виноград любишь?
            if len(session.conversation_history) > 1 and phrase_is_question:
                last2_phrase = session.conversation_history[
                    -2]  # это вопрос человека "Ты яблоки любишь?"

                if not last2_phrase.is_bot_phrase\
                    and last2_phrase.is_question\
                    and self.interpreter is not None:

                    if self.req_interpretation.require_interpretation(
                            raw_phrase, self.text_utils, self.word_embeddings):
                        context_phrases = list()
                        # Контекст состоит из двух предыдущих фраз
                        context_phrases.append(last2_phrase.raw_phrase)
                        context_phrases.append(last_phrase.raw_phrase)
                        context_phrases.append(raw_phrase)
                        phrase = self.interpreter.interpret(
                            context_phrases, self.text_utils,
                            self.word_embeddings)

                        if self.intent_detector is not None:
                            interpreted.intent = self.intent_detector.detect_intent(
                                raw_phrase, self.text_utils,
                                self.word_embeddings)
                            self.logger.debug(u'intent="%s"',
                                              interpreted.intent)

                        was_interpreted = True

            # and last_phrase.is_question\
            if not was_interpreted\
                    and len(session.conversation_history) > 0\
                    and last_phrase.is_bot_phrase\
                    and not phrase_is_question\
                    and self.interpreter is not None:

                if self.req_interpretation.require_interpretation(
                        raw_phrase, self.text_utils, self.word_embeddings):
                    # В отдельной ветке обрабатываем ситуацию, когда бот
                    # задал вопрос или квази-вопрос типа "А давай xxx", на который собеседник дал краткий ответ.
                    # с помощью специальной модели мы попробуем восстановить полный
                    # текст ответа собеседника.
                    context_phrases = list()
                    context_phrases.append(last_phrase.interpretation)
                    context_phrases.append(raw_phrase)
                    phrase = self.interpreter.interpret(
                        context_phrases, self.text_utils, self.word_embeddings)
                    if self.intent_detector is not None:
                        interpreted.intent = self.intent_detector.detect_intent(
                            raw_phrase, self.text_utils, self.word_embeddings)
                        self.logger.debug(u'intent="%s"', interpreted.intent)

                    was_interpreted = True

        if not interpreted.intent:
            if self.intent_detector is not None:
                interpreted.intent = self.intent_detector.detect_intent(
                    raw_phrase, self.text_utils, self.word_embeddings)
                self.logger.debug(u'intent="%s"', interpreted.intent)

        if was_interpreted:
            phrase = self.interpreter.normalize_person(phrase, self.text_utils,
                                                       self.word_embeddings)

        if not internal_issuer:
            # Попробуем найти шаблон трансляции, достаточно похожий на эту фразу.
            # Может получиться так, что введенная императивная фраза станет обычным вопросом:
            # "назови свое имя!" ==> "Как тебя зовут?"
            translated_str = self.translate_interlocutor_replica(
                bot, session, phrase)
            if translated_str is not None:
                phrase = translated_str
                raw_phrase = translated_str
                phrase_modality, phrase_person = self.modality_model.get_modality(
                    phrase, self.text_utils, self.word_embeddings)
                was_interpreted = True

        if not was_interpreted:
            phrase = self.interpreter.normalize_person(raw_phrase,
                                                       self.text_utils,
                                                       self.word_embeddings)

        # TODO: Если результат интерпретации содержит мусор, то не нужно его обрабатывать.
        # Поэтому тут надо проверить phrase  с помощью верификатора синтаксиса.
        # ...

        interpreted.interpretation = phrase
        interpreted.set_modality(phrase_modality, phrase_person)

        return interpreted