Things I have learned making chatbots with LUIS

Things I have learned making chatbots with LUIS

Things I have learned making chatbots with LUIS

When coupled with the Bot Framework, LUIS – at it’s core – provides utterance to intent mapping. More simply, it converts what a user says into what code your bot should run. In this post I’ll share the small insights that I have gained by building chat bots that use LUIS.

This post is not meant to be a introduction to or and overview of LUIS. For that I would recommend this excellent post by Robin.

Train and publish

The simplest tip I can provide when working with LUIS is that every time you make a change, ensure that you hit both the Train (bottom left) and Publish (top left, below the header) buttons! Without doing both of these, your chatbot will not gain the benefits of any LUIS application changes that you make.

Entities overview

Beyond just mapping utterances to intents, LUIS can perform entity extraction. This feature allows you not only to classify what the user has said to what you should do but also pull out some data from that utterance for later use.

I’ll stay on the theme of a bot that provides sports scores that I touched upon in my previous post. Given an utterance “Did Arsenal win last night?”, we’d map that to some intent that is to give the score of a match that happened last night. In the general case this would be “Did [Team Name] win last night?”. Using LUIS we can extract the team name as an entity and pass it to our bot.

The steps to do this are very simple. First we create an entity in our LUIS application using the menu on the left:

Where to add Entities in a LUIS application
Where to add Entities in a LUIS application

Then start tagging some of our existing utterances with that entity. This isn’t explained very well anywhere but to tag something in an utterance as entity you either click on the word if it’s just one word or highlight multiple words using your cursor. You’ll then get a dropdown where you can choose which of your existing entities to tag this word (or words) as. The same as you would with intents, you’d do this multiple times to train the LUIS application to start recognising in what patterns that your entity appears.

When using the LuisDialog in your bot code, the extracted entities are passing in with the user’s input query as part of the LuisResult. Microsoft have provided a good working example of how to use these entities in their Alarm Bot sample

Pre-built entities

LUIS provides a bunch of pre-built entity types that you can add to your model just by adding them in the Pre-Built entity sub-menu on the left side of your LUIS application.

The pre-built entites cover a range of types from simple numbers to a very broad encyclopedia type that looks like it should be able to extract anything from famous people to architecure styles. I haven’t actually looked at all of them myself but it looks like they could be used to make really powerfull chatbots when applied to a specific subject!

Although the cover a range of types, not all of the pre-built entites are created equal. The biggest problem of some of the other pre-built entities is that they don’t provide a mapping from what was extracted to a generic value that isn’t confused by language. For example; if using the builtin.money entity, an utterance containing the phrase “1000.00 US dollars” will return the following JSON:

And an utterance of “$1000.00” will return:

The problem here is that the entity returned is exactly as the user said. Yes, LUIS has extracted it for us but has not abstracted the speech from the value. I would expect currency to provide some sort of resolution (as builtin.datetime does) that looks like this:

With this in my chatbot code, I don’t have to worry about what the user actually said but can just extract the values from the resolution object. builtin.datetime does this very well. For example; if we are looking to extract a time from an utterance like “what’s on at 4pm?” you’d get the following response from LUIS:

Using the time value in the resolution object, I can just pass this to DateTimeOffset.Parse(). Similarly with the utterance “what’s on at 3:00?” I’d get this response:

LUIS has still extracted the value for me but also returned a comment value that lets me know that this time is ambiguous as to whether it’s AM or PM.

LUIS can also extract relative dates or times as entities. For example; “Did Chelsea win last week?” would return:

when this is asked during the week commencing 24/10/2016. This one is a little harder to parse and is a completely different format to the resolutions that we were seeing for time. We could go and write a package worth of logic for parsing all of these dates and times and time spans or we could just use Chronic to do all that for us! With Chronic, I can just pass the entity to it’s parser and get a Span object to represent these different things.

Child entities

In my experience, child entities are best used when you want to extract two entities of the same type from one utterance but the order in which they appear is important.

Going back to the sports scores example from before; in the utterance “Who won between Tottenham Hotspur and Everton?” we have two team names but which one is mentioned first makes a difference as to what match we’d provide a score for. The first mentioned team would be our home team and the second would be the away team (note: I know that in North American sports the standard is “Away Team at Home Team” but that’s just silly!).

In LUIS terms, this would be an entity named Team and two child entities named HomeTeam and AwayTeam respectively.

Create child entities
Create child entities

With a few example utterances, LUIS will start correctly tagging our entities and learn at what point in the utterance do these entities normally appear. With this, it’s then easy to also add the American style utterance; “Tell me the winner for Miami at Cleveland”.

Phrase list features

The phrase list features are a way of giving LUIS explicit knowledge about things that your users will say that are related. Adding a phrase list is similar to adding an entity; click the + button on the left menu of a given LUIS application, give the phrase list a name and then fill in a list of comma separated phrases.

Phrase lists come in two flavours; exchangeable and non exchangable. Exchangable phrase lists are things that when substituted for something else on the phrase list the meaning of the utterance is the same. This phrase list then allows LUIS to apply anything it learns about utterances with any phrase from the list to all of the other phrases!

Non exchangable phrase lists are a bit more complicated. A non exchangeable phrase list can be used to describe a list of related phrases but when swapped for another from the list, the intent of the utterance would change. The example given when hovering over the radio button for non exchangable gives the list; “calendar”, “appointment”, “time”, “date”, “begin”, “end”. These phrases all relate to appointments but swapping “calendar” for “begin” would probably cause the utterance to no longer make sense.

Regex features

Regex features are intented to achieve the same thing as phrase list features but using regex pattern matching instead of a discrete list of phrases. This mostly comes into play when dealing with identifiers that follow a pattern such as order numbers or postcodes.

Remarks

This is obviously not an exhaustive list of things that can be done with LUIS when creating chatbots but I thought that it would be helpful to try and share some of things that I have discovered with anyone who is interested. The main goal for this post is to save at least one person a bunch of reading or Googling and allow them to spend more time building cool chat bots!

Leave a Reply

%d bloggers like this: