Ignore intent to make prediction

Is it possible to ignore an intent in making a prediction in the next action? There are some intents that I just want to check their confidence, but I don’t want them to influence the prediction of the actions. How can I do this?

The problem that I have is that I have two slots, namely departure and destination, that I can fill with the entity “location” which is a lookup table. I tried having two entities (destination and departure) from the same lookup table but the entities often got mixed and weren’t automatically picked up. So I decided to just have one entity that I would map to the slots. Since Rasa does not automatically pick up slots that do not have the same name as the entity I wrote a function that maps the entity location to the slots. However, I need to disambiguate which is the departure and which is the destination. I was thinking of having two intents: give_departure and give_destination to disambiguate between the slots but I don’t want them to influence the next action. for example, I want to know if “I want to book a flight to Lisbon” is more similar to “give_destiantion” than to “give_departure”, but I want the top intent to still be “book_flight”. Otherwise, my BookFlightFlow will not be triggered and other problems might appear.

Quick Note: Using “entity=Location, from_intent: give_destination” won’t work since I am mapping the slots myself and not using Rasa for this mapping.

Here is some code:

Actions

def slot_mappings(self):
    return {
        'departure': [
            self.from_entity(entity='location'),
        ],

        'destination': [
            self.from_entity(entity='location'),
        ],

        .....


def extract_location(self, values, tracker):
    print(values)
    slots_that_belong_to_entity = ["departure", "destination"]
    slots_to_save = {}

    for value in values:
        for slot_name in slots_that_belong_to_entity:
            if not tracker.get_slot(slot_name):  # don't overwrite slot if it is already filled
                slots_to_save[slot_name] = value
                slots_that_belong_to_entity.remove(slot_name)  # go to the next slot
                break

    return slots_to_save

def get_slots_extracted_from_entities_with_different_names(self, tracker, slot_values):
    entities_extracted = {}

    for entity in tracker.latest_message['entities']:
        if entity["entity"] not in entities_extracted:
            entities_extracted[entity["entity"]] = [entity["value"]]
        else:
            entities_extracted[entity["entity"]].append(entity["value"])

    entities_with_different_names_than_slots = ["location"]

    for entity in entities_with_different_names_than_slots:
        if entity in entities_extracted.keys():
            slot_values_to_add = {}

            if entity == "location":
                slot_values_to_add = self.extract_location(entities_extracted[entity], tracker)

            slot_values.update(slot_values_to_add)

    return slot_values

async def validate(self, dispatcher, tracker, domain):
    slot_values = self.extract_other_slots(dispatcher, tracker, domain)
    slot_to_fill = tracker.get_slot("requested_slot")

    # Automatically extract slots that do not have the same name as the entity
    slot_values = self.get_slots_extracted_from_entities_with_different_names(tracker, slot_values)

    if slot_to_fill:
        slot_values.update(self.extract_requested_slot(dispatcher, tracker, domain))

        if slot_to_fill == 'departure':
            if not slot_values:
                utterances = ['Please repeat your departure city, country or airport.', 'Please say the departure again.']
                chosen_utterance = random.choice(utterances)
                dispatcher.utter_message(text=chosen_utterance, json_message={'emotion': 'SAD'})
        print(f"Validating extracted slots: {slot_values}")

    return await self.validate_slots(slot_values, dispatcher, tracker, domain)

Domain:

slots:
  departure:
    type: unfeaturized
  destination:
    type: unfeaturized

NLU:

 ## intent:book_flight
- Can you find me a trip flight from [Washington](location) to [Los Angeles](location) returning on March 4th.
- I wanna fly out to [Las Vegas](location) on the 12th please
- I am planning a trip. I will need business tickets. The tickets will be for a flight next week.
- Book a flight to [Lisbon](location)
- Book a flight from [Porto](location)
- I need to schedule a economy flight to [San Francisco](location)
- Book a flight between [Lisbon](location) and [Porto](location)
- Book 3 economy tickets on the flight from [London](location) to [San Francisco](location)
- I want to schedule a flight from [Zurich](location) to [New York](location)
- I need a  flight from [Lisbon](location) to [Faro](location)
- Book a flight from [Madrid](location) to [Barcelona](location)
- I need a to fly to [Spain](location) from [Portugal](location)
- Book a economy flight from [LAX](location) to [JFK](location)
- I would like to book a flight from [Lisbon](location) to [New York](location)
- I want to go to [London](location) from [Porto](location)
- I want to go to [Zurich](location)

## intent:give_departure
- I need a to fly from [Spain](location)
- Book a economy flight from [LAX](location)
- I would like to book a flight  from [Lisbon](location)
- I want to go from [Porto](location)
- I want to go from [Zurich](location)
- I want to book a flight from [New York](location)
- I want to schedule a flight from [Detroit](location)
- Can I book a flight from [Porto](location)
- I'd like to fly from [Porto](location) on economy

## intent:give_destination
- I need a to fly to [Spain](location)
- Book a economy flight to [JFK](location)
- I would like to book a flight to [New York](location)
- I want to go to [London](location)
- I want to go to [Zurich](location)
- I want to book a flight to [Porto](location)
- I want to schedule a flight to [Berlin](location)
- Can I book a flight to [Porto](location)
- I'd like to fly to [Lisbon](location)
- Would it be possible to schedule a flight to [Hong Kong](location)


## lookup:location
data/lookup_tables/location.txt

Can any of you please help me? @akelad @JiteshGaikwad @erohmensing @JulianGerhard Sorry to mention you individually but I believe this is a common issue amongst Rasa users

Hi @teresalazar13,

wouldnt this feature address your problem properly?

@Tanja - as far as I have seen, this should have been done but has not been released yet?

Kind regards
Julian

1 Like

Thank you @JulianGerhard. yes, that would! that’s great! When will it be released?

@teresalazar13 Thanks for the detailed description.

As @JulianGerhard mentioned, I’m currently working on supporting composite entities. I will have a working version ready end of the week and will ask some users to test it before we actually release the feature. @teresalazar13 would you be up to test the feature once we have a working solution?

The idea is that you can assign an additional role label to an entity. For example, let’s take this training data example of yours

- Can you find me a trip flight from [Washington](location) to [Los Angeles](location) returning on March 4th.

With the new feature you would be able to annotate it in more detail, for example

- Can you find me a trip flight from [Washington]{"entity": "location", "role": "departure"} to [Los Angeles]{"entity": "location", "role": "destination"} returning on March 4th.

We will also add support for forms so that you can fill slots in the slot mapping with the help of a function like self.from_entity_with_role(entity='location', role='departure'). Would that help in your case?

1 Like

Yes, I would, that’s very cool! So, with this feature, will also both slots be automatically filled, event if the bot does not specifically ask for for them? :slight_smile:

No, we decided for now that automatic slot filling will just be on the “entity” label itself. Role labels will not be considered. So, if you want to fill a slot that is dependent on a role label, you need to either use a form to fill it (using slot mapping) or write your own custom action.

I’ll let you know once I have a working version, so that you can test it. Thanks.

1 Like

Ok thank you. But if the form has 2 entities: departure - self.from_entity_with_role(entity='location', role='departure') . destination - self.from_entity_with_role(entity='location', role='destination') , will they be picked up if I say: "I want to book a flight from [Lisbon]{“entity”: “location”, “role”: “departure”} to [Porto]{“entity”: “location”, “role”: “destination”}?

Yes. Our model will be able to learn basically up to two labels per token. So it is able to assign location as entity label and departure as role label to a word. The output of the model will look like this, for example

{
  "start": x,
  "end": y,
  "value": "Washington",
  "entity": "location",
  "role": "departure",          
}
1 Like

Hi @Tanja,

if it would be okay for you, I’d like to test this also - opening lots of interesting possibilities since the grouping feature you mentioned can be very mighty - what do you think?

Kind regards
Julian

Hi @JulianGerhard, sure. Thanks for the offer. Will contact you next week with more details.