Use of Rasa -- Taking constellation fortune as a case

After two weeks of exploration and experiment, today we finally pushed the horoscope to the final test stage. Although running through a demo will feel that rasa is very simple, it is found that the understanding of Rasa is limited to the tip of the iceberg after completing a function, from separating different intent s, designing Dialogue framework, setting rasa pipeline, reading specific months, and considering boundaries and abnormalities.

Design story with BotSociety

Write stories from the perspective of API functions and user questions

API functions:

  • Query the overall constellation trend
  • Query love index
  • Query work index
  • Query financial index
  • Query health index
  • Query lucky color
  • Query matching constellation
  • Constellation mapping to date
  • Date mapped to constellation
  • Emotional response such as comfort

User angle:

  • Know the constellation and ask clear questions
  • Don't know constellation, fuzzy question, date mapping
  • See all your luck
  • Check the specific fortune

Design story:

rasa part

Chinese word segmentation

Problem Description:
At the rasa train stage, the boundary error is reported

The ideal entity is Capricorn, but what is extracted is Capricorn
Solution:

https://github.com/howl-anderson/rasa_chinese

Clear slot memory

Problem Description:

In the figure above, bot first asked Virgo's love index to make starsign_ The slot of type is filled into Virgo, but in the new round of dialogue, the slot is not empty, which affects the next judgment.

Solution:
First, the author sets the slot position to None in action, as shown below

class ResetAction(Action):
    def name(self) -> Text:
        return "action_reset"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

        return [SlotSet('starsign_type', None)]

However, it does not have the effect of emptying, but uses AllSlotsReset() to achieve the expected effect and restart the conversation. Through experiments, it is found that the current slot can be set to a certain value, but setting it to None does not respond.

# Correct scheme:
        return [AllSlotsReset(), Restarted(), SlotSet('starsign_type', None)]

Date constellation mapping

Problem Description:
Because some users do not know their constellation, it is necessary to set the constellation date mapping link in the constellation trend query. There are many query methods for users, such as "July 2", "July 2", "July 2" and "7 / 2"
Solution 1: negative
Extract all the numbers in the information entered by the user in the way of entities/slot (type = list), match the constellations in action, and then return the results to the user.
However, in practice, it is impossible to extract all numbers. Sometimes only one number can be obtained, which is very unstable, and Chinese numbers can not be extracted.
Solution 2:
The conjecture may be that the elements are not well extracted. Although the month and day share a number (1-12, 1-12), they still need to be distinguished more clearly, so they are distinguished by the role in rasa.

I was born in[7]{"entity": "date", "role": "month"}month[2]{"entity": "date", "role": "day"} .

But it's no use. Sigh.

Solution 3:
I would like to call it, there is no wall that python can't hold up.
The idea is to read the user's sentence and use Python's regularity to process the high degree of freedom part of action. Aside: Although rasa has regular rules, there will always be some bug s, Chinese mismatch and other problems, so choose python with high proficiency and ease index.

class ReturnStarAction(Action):
    def name(self) -> Text:
        return "action_return_star"

    def checkdate(self, tracker):
        inp = tracker.latest_message['text']
        print(inp)
        number = re.compile(r'([One two three four five six seven eight nine ten]+|[0-9]+)')
        pattern = re.compile(number)
        all = pattern.findall(inp)
        print(all)
        date_status = False
        date_accurate = False
        if len(all) != 2:
            return date_status, None, None, None
        else:
            date_status = True
            month = all[0]
            day = all[1]
            if not month.isdigit():
                month = pycnnum.cn2num(month)
            if int(month) > 0 and int(month) < 13:
                date_accurate = True
            if not day.isdigit():
                day = pycnnum.cn2num(day)
            if int(day) > 0 and int(day) < 32:
                date_accurate = True
            return date_status, date_accurate, month, day

    def findstar(self, month, day):
        daylist = [20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22]
        starlist = ['Capricornus', 'aquarius', 'Pisces', 'Aries', 'Taurus', 'Gemini',
                    'Cancer', 'leo', 'Virgo', 'libra', 'scorpio', 'sagittarius']
        if int(day) < daylist[int(month) - 1]:
            return starlist[int(month) - 1]
        else:
            return starlist[int(month)]

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
        date_status, date_accurate, month, day = self.checkdate(tracker)
        if not date_status or not date_accurate:
            dispatcher.utter_message(text=f'{"I thought this date should only be in the sky. Why don't you say something reliable?"}')
            return []
        else:
            star = self.findstar(month, day)
            dispatcher.utter_message(text=f"So you are{star}~!")
            return [SlotSet('starsign_type', star)]

Solution 4:
I would call it an escape strategy
When it is recognized that intent is the user asking for the constellation date, you can directly return to a map and let the user view it by himself.

Set keys to entities

At first, I didn't take love index, work index and lucky color as key words, but ordinary corpus information. After modification, the key information can be better extracted.

### Before modification
- intent: ask_horoscope
  examples: |
    - [Aries](starsign_type)Love fortune
    - [Taurus](starsign_type)Love
    - How's my luck
    - My love index
### After modification
- intent: ask_horoscope
  examples: |
    - [Aries](starsign_type)of[Love fortune](love)
    - [Taurus](starsign_type)of[love](love)
    - my[Peach blossom luck](love)how
    - my[Love index](love)

Merge intent

Combine intents with high similarity, the number of intents becomes less, and the hit accuracy is improved accordingly. On the contrary, if there are too many subdivisions, the model is not so good, and will not achieve the expected effect, which is prone to the dislocation of intent recognition.

Merge path s and split with slot

Because intent is merged, it means that there is a public path. One end of the path is intent and the other end is action. To decide which action to go, it is determined by filling the slot. The principle followed here is to take the public path as much as possible, which is also to adapt to the model, improve the hit rate, and use the slot position to judge more accurately.

Rasa test

According to official documents https://rasa.com/docs/rasa/testing-your-assistant Test.
nlu is divided into training set and test set according to 4:1 for cross validation.

  • Check whether Data and Stories are valid
  • Split nlu
  • test nlu
  • View intent/slot confusion matrix


Since such test data sets are all from the written nlu, it is still necessary to test manually in the interactive page.

Added by rpadilla on Tue, 11 Jan 2022 00:29:51 +0200