Help! How to respond differently based on entity/slot value?

In my nlu.md file I have defined an intent “meal_time” with following training samples

## intent:meal_time

- when is [breakfast](meal) served?

- what time is [lunch](meal) time?

- [dinner](meal) time

- [breakfast](meal) serving time

In my domain.yml I’ve defined meal as an entity and categorical slot with values breakfast, lunch and dinner. I’m trying to respond to the user according to which meal type he entered like so:

## breakfast time
* meal_time {"meal": "breakfast"}
  - utter_restaurant_breakfast_time

## lunch time
* meal_time {"meal": "lunch"}
  - utter_restaurant_lunch_time

## dinner time
* meal_time {"meal": "dinner"}
  - utter_restaurant_dinner_time

This approach doesn’t seem to work though. DIETClassifier manages to extract the entity and fill the slot with it’s value, but the answer is chosen randomly. For instance, if I type “when is breakfast served?” the bot may respond with any of the three different utters (utter_restaurant_dinner_time or utter_restaurant_lunch_time or utter_restaurant_breakfast_time). Can someone please explain why is this happening?

One thing I forgot to mention is that in my actual code, intents and entities are actually in non-English language (Greek to be precise). I tried running the example I provided above as is (in English) and it works perfectly! It responds with the correct utter based on meal type. When I switched back to Greek it failed again… I even tried changing the categorical values only of “meal” slot to English with no difference. Here is my config.yml

language: el
pipeline:
  - name: WhitespaceTokenizer
  - name: CRFEntityExtractor
  - name: RegexFeaturizer
  - name: LexicalSyntacticFeaturizer
  - name: CountVectorsFeaturizer
  - name: CountVectorsFeaturizer
    analyzer: "char_wb"
    min_ngram: 1
    max_ngram: 4
  - name: DIETClassifier
    epochs: 100
  - name: EntitySynonymMapper
  - name: ResponseSelector
    epochs: 100

policies:
  - name: MemoizationPolicy
  - name: TEDPolicy
    max_history: 5
    epochs: 100
  - name: MappingPolicy
  - name: "FallbackPolicy"
    nlu_threshold: 0.4
    core_threshold: 0.3
    fallback_action_name: "action_default_fallback"
1 Like

Hi @stavr ,

I think this problem is because the number of examples in your intent meal_time is very less. Go for atleast 10 - 15 examples per entity. (Refer this Video or Documentation).

Check out this Video which tells about extracting entities from one word inputs as well.

That should solve the issue.

There is also another approach you could try ,

In this case, as the values for entity meal limited ( I don’t know about other languages, but mostly just breakfast, lunch and dinner right) , an approach you could try is to have a Custom action.

You could have a custom action like ,

class ActionCheckMealTime(Action):

def name(self) -> Text:
    return "action_check_mealtime"

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

    time = tracker.latest_message['entities'][0]['value']
    if time['meal'] == "breakfast":
        dispatcher.utter_message(template="utter_restaurant_breakfast_time")
    elif time['meal'] == "lunch":
        dispatcher.utter_message(template="utter_restaurant_lunch_time")
    else:
        dispatcher.utter_message(template="utter_restaurant_breakfast_time")

    return []

And in your story , have just one example

breakfast time

  • meal_time {“meal”: “breakfast”}
    • action_check_mealtime

Don’t forget to edit the endpoints.yml file and start the action server. Make sure to include this custom action inside domain.yml file under actions:.

Hope this helps.

1 Like

Hello @_sanjay_r,

I tried the custom action way and noticed that slot values were filled with _meal where _ would be whitespace. After searching in my nlu data I noticed that the synonyms I’ve defined contained a whitespace. Here is what I mean:

## synonym: breakfast
- synonym_br_1
- synonym_br_2

## synonym: lunch
- synonym_lu_1
- synonym_lu_2

## synonym: dinner
- synonym_di_1
- synonym_di_2

Notice the whitespace between ## synonym: and breakfast (or any other meal type)? When I removed it the bot was finally able to understand and respond accordingly :partying_face:

Thank you for giving me the hint with the custom action! :smiley:

Glad I could help you solve the issue.

Cheers.