NLU Data: add placeholders to nlu data

I am fairly new to rasa. I am working on a small school project where a user can ask questions about its timetable.

E.g.: “When is my next lesson”, “Where is my next lesson”.

However, the user could also ask “In which room do I have the subject Maths?” or “When does Biologie start?”.

So my first question is, are these two different type of intents? (NEXT lesson and a specific lesson).

And secondly, how would I add a placeholder for such a specific lesson inside my data? (so placeholder for subject eg) Because I do not want to create examples for all the 20 subjects (When does Maths start, When does English start? etc).

I am not able to provide you with my data as it is in German. However, in case needed, I will post it.

HI @threxx

Da ich das Problem mit deutschen Trainings-Daten kenne, könnte ich dir auch auf Deutsch Fragen beantworten. Damit die anderen Foren-Nutzer folgen können, erkläre ich dir die Sache aber auf Englisch. Du kannst mich gern auch anderweitig kontaktieren.

First of all intents should be separated if they could be separated. Sometimes this might seem to be a bit penibel but makes things easier after a while. For your setup I would recommend (as a starting point):

# intent:location_next_lesson
- Where is my next lesson?
- Tell me the room of my next lesson
- Where do I have [biology](subject) next?
- In which room do I have [maths](subject)

# intent:time_next_lesson
- When do I have my next lesson?
- When does my next lesson start?
- When does [art](subject) start?
- When do I have [history](subject)

By defining those two intents you actually combined the questions for a general next lesson and a specific lesson but you did more: You told the algorithm that inside those training data, there are entities (your subjects) and you told it further how the sentences, embedding those entities, look like.

To avoid the necessity to add training samples for all entities, you could easily use a lookup table as described here:

Now you need a custom action that is able to get the information about the lessons and your timetable. Assuming that you are doing this the first time, here is a little sample:

class TimetableLocation(Action):
    def name(self):
        # type: () -> Text
        return "get_next_lesson_location"

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

        specific_subject = None
        for subject in tracker.get_latest_entity_values('subject'):
            specific_subject = subject
            break
            
        if specific_subject is not None:
            location = <code for getting the next lesson for the specific subject>
            message = 'Das Fach {} hast du das nächste Mal in Raum {}'.format(specific_subject, location)
        else:
            location = <code for getting the next lesson>
            message = 'Du musst als nächstes in Raum {}'.format(location)
                

        dispatcher.utter_message(message)

        return []

A crucial point here is to use:

tracker.get_latest_entity_values('subject')

since this line allows you to check if the user did not only trigger the intent rather than to trigger the intent and add an entity. This is only a simple sample, I am sure there are other things to take care of. If your cases are growing in complexity, you might want to consider a FormAction.

If you now provide a proper story and enough training data, it will work the way you wanted and your other mentioned intents work accordingly.

Feel free to ask for help.

Regards

1 Like

@JulianGerhard Thank you very much for that detailed explanation, it helped me a lot!

@threxx Glad that I could help. I’m almost sure that there will be new questions - feel free to ask.

@JulianGerhard Actually, I have an open question right now. It’s because I updated to a higher Rasa Core and NLU Version and there is a lot of debugging. Maybe you could help me out here as well: RasaNLUHttpInterpreter: takes from 1 to 4 positional arguments but 5 were given