예제 #1
0
    def probabilities_using_best_policy(
            self, tracker: DialogueStateTracker,
            domain: Domain) -> Tuple[List[float], Text]:
        result = None
        max_confidence = -1
        best_policy_name = None

        for i, p in enumerate(self.policies):
            probabilities = p.predict_action_probabilities(tracker, domain)
            if isinstance(tracker.events[-1], ActionExecutionRejected):
                probabilities[domain.index_for_action(
                    tracker.events[-1].action_name)] = 0.0
            confidence = np.max(probabilities)
            if confidence > max_confidence:
                max_confidence = confidence
                result = probabilities
                best_policy_name = 'policy_{}_{}'.format(i, type(p).__name__)

        if (result.index(max_confidence)
                == domain.index_for_action(ACTION_LISTEN_NAME)
                and tracker.latest_action_name == ACTION_LISTEN_NAME
                and self.is_not_memo_policy(best_policy_name)):
            # Trigger the fallback policy when ActionListen is predicted after
            # a user utterance. This is done on the condition that:
            # - a fallback policy is present,
            # - there was just a user message and the predicted
            #   action is action_listen by a policy
            #   other than the MemoizationPolicy

            fallback_idx_policy = [(i, p) for i, p in enumerate(self.policies)
                                   if isinstance(p, FallbackPolicy)]

            if fallback_idx_policy:
                fallback_idx, fallback_policy = fallback_idx_policy[0]

                logger.debug("Action 'action_listen' was predicted after "
                             "a user message using {}. "
                             "Predicting fallback action: {}"
                             "".format(best_policy_name,
                                       fallback_policy.fallback_action_name))

                result = fallback_policy.fallback_scores(domain)
                best_policy_name = 'policy_{}_{}'.format(
                    fallback_idx,
                    type(fallback_policy).__name__)

        # normalize probablilities
        if np.sum(result) != 0:
            result = result / np.nansum(result)

        logger.debug("Predicted next action using {}"
                     "".format(best_policy_name))
        return result, best_policy_name
예제 #2
0
    def predict_action_probabilities(self,
                                     tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts a fallback action if NLU confidence is low
            or no other policy has a high-confidence prediction"""

        nlu_data = tracker.latest_message.parse_data

        # if NLU interpreter does not provide confidence score,
        # it is set to 1.0 here in order
        # to not override standard behaviour
        nlu_confidence = nlu_data["intent"].get("confidence", 1.0)

        if tracker.latest_action_name == self.fallback_action_name:
            result = [0.0] * domain.num_actions
            idx = domain.index_for_action('action_listen')
            result[idx] = FALLBACK_SCORE

        elif self.should_fallback(nlu_confidence, tracker.latest_action_name):
            logger.debug("NLU confidence {} is lower "
                         "than NLU threshold {}. "
                         "Predicting fallback action: {}"
                         "".format(nlu_confidence, self.nlu_threshold,
                                   self.fallback_action_name))
            # we set this to 1.1 to make sure fallback overrides
            # the memoization policy
            result = self.fallback_scores(domain)
        else:
            # NLU confidence threshold is met, so
            # predict fallback action with confidence `core_threshold`
            # if this is the highest confidence in the ensemble,
            # the fallback action will be executed.
            result = self.fallback_scores(domain, self.core_threshold)

        return result
예제 #3
0
    def action_as_one_hot(action: Text, domain: Domain) -> np.ndarray:
        if action is None:
            return np.ones(domain.num_actions, dtype=int) * -1

        y = np.zeros(domain.num_actions, dtype=int)
        y[domain.index_for_action(action)] = 1
        return y
예제 #4
0
    def predict_action_probabilities(self,
                                     tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts the corresponding form action if there is an active form"""
        result = [0.0] * domain.num_actions

        if tracker.active_form.get('name'):
            logger.debug("There is an active form '{}'"
                         "".format(tracker.active_form['name']))
            if tracker.latest_action_name == ACTION_LISTEN_NAME:
                # predict form action after user utterance

                if tracker.active_form.get('rejected'):
                    # since it is assumed that training stories contain
                    # only unhappy paths, notify the form that
                    # it should not be validated if predicted by other policy
                    tracker_as_states = self.featurizer.prediction_states(
                        [tracker], domain)
                    states = tracker_as_states[0]
                    memorized_form = self.recall(states, tracker, domain)

                    if memorized_form == tracker.active_form['name']:
                        logger.debug("There is a memorized tracker state {}, "
                                     "added `FormValidation(False)` event"
                                     "".format(self._modified_states(states)))
                        tracker.update(FormValidation(False))
                        return result

                idx = domain.index_for_action(tracker.active_form['name'])
                result[idx] = FORM_SCORE

            elif tracker.latest_action_name == tracker.active_form.get('name'):
                # predict action_listen after form action
                idx = domain.index_for_action(ACTION_LISTEN_NAME)
                result[idx] = FORM_SCORE
        else:
            logger.debug("There is no active form")

        return result
예제 #5
0
    def predict_action_probabilities(self, tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts the next action the bot should take
        after seeing the tracker.
        Returns the list of probabilities for the next actions"""
        if not self.connected:
            # TODO: connection seems to expire,
            # if expired we should set connected to false again.
            self.connect_to_rabbit()

        result = [0.0] * domain.num_actions
        intent = tracker.latest_message.intent
        if tracker.latest_action_name == self.custom_response_action_name:
            result = [0.0] * domain.num_actions
            idx = domain.index_for_action(ACTION_LISTEN_NAME)
            result[idx] = 1.0
        elif (intent.get("name") is None
              and intent.get("confidence") < self.nlu_threshold):

            text = tracker.latest_message.text or ""

            answer = self.call(text)

            logger.info("\n\n -- Answer Selected -- ")
            logger.info("Bot: " + answer["bot"])
            logger.info("Confidence: " + str(answer["intent_confidence"]))
            logger.info("Confidence: " + str(answer["utter_confidence"]))
            logger.info("Total Confidence: " + str(answer["total_confidence"]))
            logger.info("Policy: " + str(answer["policy_name"]))
            logger.info("Intent Name: " + answer["intent_name"])

            set_answer_slot_event = SlotSet("bot_answers", answer["messages"])
            tracker.update(set_answer_slot_event)

            result = self.bottis_score(result, domain, self.core_threshold)

        return result
예제 #6
0
    def predict_action_probabilities(self,
                                     tracker: DialogueStateTracker,
                                     domain: Domain) -> List[float]:
        """Predicts a fallback action.

        The fallback action is predicted if the NLU confidence is low
        or no other policy has a high-confidence prediction.
        """

        nlu_data = tracker.latest_message.parse_data

        # if NLU interpreter does not provide confidence score,
        # it is set to 1.0 here in order
        # to not override standard behaviour
        nlu_confidence = nlu_data.get("intent", {}).get("confidence", 1.0)

        if tracker.latest_action_name == self.fallback_action_name:
            result = [0.0] * domain.num_actions
            idx = domain.index_for_action(ACTION_LISTEN_NAME)
            result[idx] = 1.0

        elif self.should_nlu_fallback(nlu_confidence,
                                      tracker.latest_action_name):
            logger.debug("NLU confidence {} is lower "
                         "than NLU threshold {}. "
                         "".format(nlu_confidence, self.nlu_threshold))
            result = self.fallback_scores(domain)

        else:
            # NLU confidence threshold is met, so
            # predict fallback action with confidence `core_threshold`
            # if this is the highest confidence in the ensemble,
            # the fallback action will be executed.
            result = self.fallback_scores(domain, self.core_threshold)

        return result