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:
- I ran
rasa shell nluto test the recognition of names that were not encoded in mynlu.mdfile. I noticed that sometimes the extractor of the name wasCRFEntityExtractorand at other times it wasSpacy. When the extractor name wasCRFEntityExtractor, the entity name was the name of the entity I defined. When it showedSpacyas the extractor, the entity name wasPERSON. How can I ensure theSpacyextractor is used? - For my
slot_mappingsfunction 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 ifSpacyis extracting aPERSONorCITYor 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:
- This depends on the way you are extracting. If you currently use a
FormActionto 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.
- 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.
- 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
CRFEntityExtractorrather thanSpacyEntityExtractor. At times I’ve seenSpacyEntityExtractoridentified as the extractor of names but I’m not sure when one extractor is chosen over another for names that are common. - Also, the performance seems to vary quite a bit. When I type names into the
Spacyvisualizer I find that they’re recognized with the typePERSON. However, usingself.from_entity(entity=\"PERSON\", not_intent=\"chitchat\"), entities of names are not being recognized. - 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:
- 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.
- Did you verify that the model used for the visualizer is the same you used for the
SpacyNLPcomponent? 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. - 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.
- I checked the extractors in my config and simplified them to only use the pretrained_embeddings_spacy pipeline. What’s odd is that sometimes
Spacyis 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?
I verified that I’m using the same model on displaCy.
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
--endpointscommand line parameter when runningrasa shelland used the following in myconfig.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.