Limit the entities extracted for a particular intent

Hi,

I wanted to know how we can limit the entities that get extracted for a particular intent.

For Example,

When the intent is greet, I don’t want any entities to get extracted.

When the intent is x I want only a and b entities to get extracted and exclude c and d even if they are present.

Thank you.

@souvikg10 @akelad @erohmensing @amn41

Anyone?

You could create a custom component and append it to your NLU pipeline as the last component. Then you can retrieve the intent and extracted entities and do some processing, such as clearing all entities if the intent is greet etc.

Hey thanks for replying Alex but I remember seeing this functionality in Rasa somewhere.

You just specify an in parameter and list the entities that you want to pick up. I am not able to recollect where that is documented and google search isn’t giving me the appropriate response.

@nikhilcss97 are you talking about the slot_mapping in a form? There you can specify which entity is extracted as the value of your slot.

See: Forms

From personal experience, I did not notice the entities being detected unless there was a sample phrase in my nlu.md specifying that particular entity. If the same entity value had samples in an another intent, it was detecting properly for those intents, but not in the intent in which there were no examples of it. Have you tried adding training phrases where entities c and d are part of the phrase but aren’t tagged as an entity? If your NLU model is complex, I would recommend you restructure its JSON response and deploy your own custom REST service. They have libraries that allow you to load a trained model and use it to predict phrases rather than deploying their defaulted REST service.

@nikhilcss97 I guess @alex38’s suggestion of creating a custom component would be the easiest way to do this.

Hi, I have the same problem as @nikhilcss97 and tried to write a Custom Component like suggested in this post. It checks if the extracted entities are required for the classified intent. If they are not, then those entities are dismissed. But after training and runnig my Bot, suddenly some of my Forms aren’t working anymore. It seems like my Custom Component is incomplete. Maybe someone wants to take a look and tell me what I’m missing.

from rasa.nlu.components import Component
import typing
from typing import Any, Optional, Text, Dict

if typing.TYPE_CHECKING:
    from rasa.nlu.model import Metadata

intent_entities_mapping = {"intent_a_name": ["entity_a_name", "entity_b_name"],
                           "Intent_b_name": ["entity_c_name"],
                           "intent_c_name": ["entity_d_name"]}


class CustomComponent(Component):

    provides = ["entities"]
    requires = ["intent", "entities"]
    defaults = {}
    language_list = None

    def __init__(self, component_config=None):
        super(CustomComponent, self).__init__(component_config)

    def train(self, training_data, cfg, **kwargs):
        pass

    def process(self, message, **kwargs):
        entities = message.get("entities", [])
        intent = message.get("intent")
        entities_res = []
        for entity in entities:
            if entity['entity'] in intent_entities_mapping[intent['name']]:
                entities_res.append(entity)
        message.set("entities", entities_res, add_to_output=True)

    def persist(self, file_name: Text, model_dir: Text) -> Optional[Dict[Text, Any]]:
        pass

    @classmethod
    def load(
        cls,
        meta: Dict[Text, Any],
        model_dir: Optional[Text] = None,
        model_metadata: Optional["Metadata"] = None,
        cached_component: Optional["Component"] = None,
        **kwargs: Any
    ) -> "Component":
        if cached_component:
            return cached_component
        else:
            return cls(meta)

I included this Component at the end of my pipeline.

1 Like

Guys, on the latest rasa (> 1.1.4) you should just be able to do this in the domain file :smile:

intents: 
- greet:
    use_entities: ["a","b"]

Sorry it isn’t well-documented – if someone wanted to add documentation on this it would make a great first PR!

Yess, I was trying to recall where I saw this functionality for 5 whole days:smile::laughing::laughing:

Thank you so much

Sorry about that!

@erohmensing I know this functionality and tried it but it isn’t working as intended. I wrote the following in my domain-file:

intents:
- intent_a
- intent_b:
    use_entities: ["entity_c"]

I started the conversation and the Bot detected intent_a with entity_c, which was extracted (even through there should be no entity extracted). After that I entered Input_b, and it was followed by the form_d as an action. The form should perform an utter_ask_entity_c (because entity_c is listed as required slot for form_d), but instead it used the in intent_a extracted entity_c. Maybe “use_entities” was the wrong approve for me or am I missing something else? Can somebody help me on this please? (Rasa version 1.2.2 and Rasa SDK version 1.1.1)

Hey @Hal, did you try doing something like this?

intents:
- intent_a:
use_entities: []

Yeah @nikhilcss97 is right, the default if you don’t define anything is that intent a will featurize all entities, so you’ll want to tell it to use none

Thank you @nikhilcss97 for your suggestion, but it’s still not working the way it should. intent_a extracts entities, even through I wrote “- intent_a: use_entities: []”. Does someone have another idea?

what about use_entities: None ?

Hm it’s likely that it still extracts the entities, but doesn’t featurize them, I think that is actually what this is for. Because the domain doesn’t have any influence over the entity extractors and what they output, just whether or that that influences the conversation flow or not.