Basic Question on Extracting Values from User Input Using FormAction - Getting Started with Rasa / Tutorials, Resources & Videos - Rasa Community Forum

Basic Question on Extracting Values from User Input Using FormAction

post by d7x on Feb 21, 2020

I’m trying to extract a person’s name using a form action. I am picking up all of the slots which are defined as entities in my slot_mappings function using "name": self.from_entity(entity=\"name\", not_intent=\"chitchat\"). However, I also want to be able to extract names that aren’t in the database. It’s easy to just capture the user input using "name": self.from_text(not_intent=\"chitchat\"). However, if the user types in "my name is bill" I want the name portion extracted from this response. Right now, I get "my name is bill" as the text captured instead of "bill".

How can I get Rasa to recognize the portion of the user text which is an entity if it is not in my nlu.md file?

post by JulianGerhard on Feb 22, 2020

Hi @d7x,

extracting names is a difficult thing sometimes. I always like to point to this amusing post about the task which might be of interest for you.

In the meantime, I am not sure what you are using to extract names as entities, but if you haven’t used Spacy to extract them, I can recommend Stanford NER to be used in a custom action like this:

def custom_validate_fullname(self, tracker):
    latest_message = tracker.latest_message["text"]
    latest_message = str(latest_message.encode("utf-8"))
    for sent in nltk.sent_tokenize(latest_message):
        tokens = nltk.tokenize.word_tokenize(sent)
        tags = self.st.tag(tokens)
        tag_string = ""
        for tag in tags:
            if tag[1] == "PERSON":
                tag_string += str(tag[0]) + " "
        return tag_string if tag_string != "" else None

The advantage is that the CRF extractor was explicitly trained on either first- and lastnames (alongside fullnames) which sometimes can be very difficult.

In addition to e.g. Spacy and/or self-trained NLU.md name entities, this is pretty much to accomplish the task.

Did that help? Don’t hesitate to ask, if you need help.

Kind regards
Julian

post by d7x on Feb 24, 2020

Julian,

That link was great! It’s certainly not a trivial task.

Thanks so much for the code for the Stanford NER. I decided to start with Spacy and hooked up Spacy by updating my pipeline to

pipeline:
- name: \"SpacyNLP\"
- name: \"SpacyEntityExtractor\"
- name: \"SpacyTokenizer\"
- name: \"RegexFeaturizer\"
- name: \"SpacyFeaturizer\"
- name: \"CRFEntityExtractor\"
- name: \"EntitySynonymMapper\"
- name: \"SklearnIntentClassifier\"

I have a few questions:

  1. I ran rasa shell nlu to test the recognition of names that were not encoded in my nlu.md file. I noticed that sometimes the extractor of the name was CRFEntityExtractor and at other times it was Spacy. When the extractor name was CRFEntityExtractor, the entity name was the name of the entity I defined. When it showed Spacy as the extractor, the entity name was PERSON. How can I ensure the Spacy extractor is used?
  2. For my slot_mappings function in my form, should I be using "name": self.from_entity(entity=\"PERSON\", not_intent=\"chitchat\") instead of "name": self.from_entity(entity=\"name\", not_intent=\"chitchat\")? I’m guessing that if Spacy is extracting a PERSON or CITY or other object that is what might make sense to specify. Is that correct?

Thanks so much for your help!

post by JulianGerhard on Feb 25, 2020

Hi @d7x,

thanks for kind words. I am glad that I could help. So concerning your questions:

  1. This depends on the way you are extracting. If you currently use a FormAction to extract them, the slot mapping you mentioned below is the exact right way:

self.from_entity(entity=\"PERSON\", not_intent=\"chitchat\")

You might even want to consider to remove your custom names if Spacy does the job. Personally I tend to use the CRF ones if I want to narrow accepted names down to a set of predefined and trained ones. However even for this task there would be more possibilities.

  1. If you set your slot mappings this way, Rasa will only use the entity set as parameter entity. How about:
"name": [
    self.from_entity(entity=\"PERSON\", not_intent=\"chitchat\"),
    self.from_entity(entity=\"name\", not_intent=\"chitchat\")
]

to respect both? Of course if you’d decide to remove either of them, don’t forget to remove it from the mapping.

Did that help?

Kind regards
Julian

post by d7x on Feb 27, 2020

Thanks Julian for answering my questions. I’ve updated my code and it’s now recognizing names which are not from the database more frequently.

  1. I’m not sure I understand the debug output that I’m seeing. It looks like the extractor which is recognizing all of my names is CRFEntityExtractor rather than SpacyEntityExtractor. At times I’ve seen SpacyEntityExtractor identified as the extractor of names but I’m not sure when one extractor is chosen over another for names that are common.
  2. Also, the performance seems to vary quite a bit. When I type names into the Spacy visualizer I find that they’re recognized with the type PERSON. However, using self.from_entity(entity=\"PERSON\", not_intent=\"chitchat\"), entities of names are not being recognized.
  3. I decided to try extracting city names as well and I changed the name of the slot to GPE. I tried recognizing "I live in Lisbon, Portugal". However, the debugger showed received user message ‘I live in Lisbon, Portugal.’ with intent ‘{‘name’: ‘inform’, ‘confidence’: 0.41268043945481514}’ and entities ‘[]’. This looks like the same issue as earlier in my post.

post by JulianGerhard on Feb 29, 2020

Hi @d7x,

you’re welcome. I try to address your questions as best as possible for the moment:

  1. I usually avoid using different extractors for the same type of entity. As far as I know, having two extractors for the same entity type results in two extraction results if successful, but the first one is picked out of the list. This could easily be verified by watching the picked value.
  2. Did you verify that the model used for the visualizer is the same you used for the SpacyNLP component? There are different models pretrained on different types of datasets that influence the extraction process. If you used the right model and still fail to extract those entities that were successfully extracted by the visualizer, then we have to investigate further.
  3. I tried this with the latest english model and got the result:

If that doesn’t work in Rasa, have you tried using the parse endpoint of the HTTP API? I’d suggest instead of using the bot, first examine the results by starting it with rasa run -vv --enable-api and then send the message to the parse endpoint and posting your results here such that we can take a look at it.

Hope that helps!

Regards
Julian

post by d7x on Mar 3, 2020

My responses correspond to the numerated items in the previous post.

  1. I checked the extractors in my config and simplified them to only use the pretrained_embeddings_spacy pipeline. What’s odd is that sometimes Spacy is used and other times a different extractor is used.

Your input → my name is Myron Banks

2020-03-03 17:39:24 DEBUG rasa.core.tracker_store - Recreating tracker for id ‘default’ 2020-03-03 17:39:24 DEBUG rasa.core.processor - Received user message ‘my name is Myron Banks’ with intent ‘{‘name’: ‘request_restaurant’, ‘confidence’: 0.7758417611589892}’ and entities ‘[{‘entity’: ‘PERSON’, ‘value’: ‘Myron Banks’, ‘start’: 11, ‘confidence’: None, ‘end’: 22, ‘extractor’: ‘SpacyEntityExtractor’}]’

However, the CRFEntityExtractor was used when replying to a different question: Your input → greek

2020-03-03 17:40:27 DEBUG rasa.core.tracker_store - Recreating tracker for id ‘default’ 2020-03-03 17:40:27 DEBUG rasa.core.processor - Received user message ‘greek’ with intent ‘{‘name’: ‘inform’, ‘confidence’: 0.9919272139205069}’ and entities ‘[{‘start’: 0, ‘end’: 5, ‘value’: ‘greek’, ‘entity’: ‘cuisine’, ‘confidence’: 0.693647167339515, ‘extractor’: ‘CRFEntityExtractor’}]’

Question: I’m not quite sure why I’m seeing CRFEntityExtractor when I specified pretrained_embeddings_spacy for the pipeline.

Question: The extractor seems to be case-sensitive. When I typed my name is m yron b anks, it came back with entities but when I typed this response with capital letters, Spacy extracted the name. Is that correct or is there a setting for case sensitivity?

  1. I verified that I’m using the same model on displaCy.

  2. This is an interesting approach for debugging. I wasn’t sure how to set up the test code to use the parse endpoint on the API. I specified the --endpoints command line parameter when running rasa shell and used the following in my config.yml:

action_endpoint:
  url: [http://localhost:5055/webhook](http://localhost:5055/webhook)

However, I got an error in my browser: Error: Method GET not allowed for URL /webhook.