Esempio n. 1
0
def test_nercrf():
    nludatafile = "/media/nvidia/ssd/catkin_ws/src/chu_bot_source/chubot/data/nlu_greet.json"

    chubot = ChuBotBrain("greet_en", language='en')
    chubot.load_data(nludatafile)

    meta = chubot.train_nercrf()
    print(meta)

    inmessage = "a bird and a dog"

    tagged_entities = chubot.predict_entity(inmessage)

    print(tagged_entities)
Esempio n. 2
0
def test_nlu_predict():
    nludatafile = "/media/nvidia/ssd/catkin_ws/src/chu_bot_source/chubot/data/nlu_greet.json"

    chubot = ChuBotBrain("greet_en", language='en')

    inmessage = "a bird and a dog"
    tagged_entities = chubot.predict_entity(inmessage)
    print(inmessage)
    print(tagged_entities)

    inmessage = "sad but great. want a dog picture"
    intent_probs = chubot.predict_intent(inmessage)
    print(inmessage)
    print(intent_probs)
Esempio n. 3
0
class ChuBotAction():
    def __init__(self, botname, language='vi'):
        self.botname = botname
        self.chubot = ChuBotBrain(botname, language)
        self.followup_actions = None
        self.action_templates = None
        self.action_custom = None
        self.slots = None
        self.start_flag = True
        self.active_entities = {}
        # TODO perhaps if folder exists -> load metadata file

    def load_domain(self, domain_file):
        """Load domain info to bot
        """
        # TODO handle exception here
        # setter -hmm, is this okay? should use @property or not?
        with io.open(domain_file) as f:
            action_domain = json.loads(
                open(domain_file, encoding="utf-8").read())

        # data fields
        self.followup_actions = action_domain["action_domain_data"][
            "followup_actions"]
        self.action_templates = action_domain["action_domain_data"][
            "action_templates"]
        self.action_custom = action_domain["action_domain_data"][
            "action_custom"]
        self.slots = action_domain["action_domain_data"]["slots"]

    def handle_action(self, action, **kwargs):
        """Handle a response action
            Select a random template for the action
            or fill the slot
            return a list of responses based on action
        """
        import random
        import re
        # TODO Handle KeyError dictionary
        response = ""
        if action in self.action_templates:
            # if action is a template
            templates = self.action_templates.get(action)
            template = random.choice(templates)

            # TODO handle multiple detected entity but template only one?
            # ->should in custom action
            # TODO handle multiple slots
            regex_pattern = r"{{(.*)}}"
            template_entity = re.search(regex_pattern, template, re.M | re.I)
            if not template_entity:
                # no found
                # return template as response
                return [template]
            else:
                active_entities = kwargs['active_entities']
                # TODO multiple slot filling
                entity = template_entity.group(1)
                for ent in active_entities:
                    if ent['entity'] == entity:
                        value = ent['value']
                return [template.replace(template_entity.group(), value)]

        elif action in self.action_custom:
            import custom_actions
            func = getattr(custom_actions,
                           self.action_custom[action].get("func_name"))
            response = func(
                action_args=self.action_custom[action].get("kwargs"), **kwargs)

        return response

    def begin_conversation(self, **kwargs):
        """Say welcome
        """
        # TODO should fix name of this action or not?
        start_flag = False
        return self.handle_action("bot_welcome")

    def handle_message(self,
                       inmessage,
                       debug=False,
                       intent_prob_threshold=0.3,
                       **kwargs):
        """Simple rule_based response
        """
        import itertools

        # TODO handle first welcome, repetitive input, etc -> state of conversation
        entities_pred = self.chubot.predict_entity(inmessage)
        intents_pred = self.chubot.predict_intent(inmessage)
        if debug:
            print("Predicted entity: ", entities_pred)
            print("Predicted intent: ", intents_pred)

        # select the first ranked predicted entity/intents
        # handle entities with different values but same entity type

        active_entities = {"active_entities": entities_pred}
        # select highest probable intent
        (prob, intent) = intents_pred[0]

        if prob < intent_prob_threshold:
            bot_actions = ["default_fallback"]
        else:
            # TODO handle key error?
            bot_actions = self.followup_actions.get(intent)

        if debug:
            print(bot_actions)

        bot_responses = [
            self.handle_action(action, **active_entities)
            for action in bot_actions
        ]
        bot_responses = list(itertools.chain(*bot_responses))

        return bot_responses

    def run_commandline_bot(self, **kwargs):
        """A commandline bot
        """
        # TODO handle action_domain_file doesnt match entities and intent in nludata file

        print("Type stop to end.\n -------------------")
        begin = self.begin_conversation()
        print("Chubot:", begin)
        while True:
            sys.stdout.write("You   > ")
            inmessage = input()
            if inmessage == 'stop':
                break
            responses = self.handle_message(inmessage, debug=False)
            for response in responses:
                print("Chubot:", response)

    def custom_handle_message(self,
                              inmessage,
                              debug=False,
                              intent_prob_threshold=0.3,
                              **kwargs):
        """Simple rule_based response
        """
        import itertools

        # TODO handle first welcome, repetitive input, etc -> state of conversation
        entities_pred = self.chubot.predict_entity(inmessage)
        intents_pred = self.chubot.predict_intent(inmessage)
        if debug:
            print("Predicted entity: ", entities_pred)
            print("Predicted intent: ", intents_pred)

        # select the first ranked predicted entity/intents
        # handle entities with different values but same entity type

        active_entities = {"active_entities": entities_pred}
        # select highest probable intent
        (prob, intent) = intents_pred[0]

        if prob < intent_prob_threshold:
            bot_actions = ["default_fallback"]
        else:
            # TODO handle key error?
            bot_actions = self.followup_actions.get(intent)

        if debug:
            print(bot_actions)

        bot_responses = [
            self.handle_action(action, **active_entities)
            for action in bot_actions
        ]
        bot_responses = list(itertools.chain(*bot_responses))

        return bot_responses