Define Concepts In Your Entity Data With Rasa

And Improve The Structure Of The Entity Data You Extract

Cobus Greyling
6 min readSep 24, 2020

--

Introduction

Looking at the chatbot development tools and environments currently available, there are three ailments which require remedy:

  • Compound Contextual Entities
  • Entity Decomposition
  • Deprecation of Rigid State Machine, Dialog Management

Rasa is actively addressing all three of these items. But, the concern of this article is entities which can be decomposed and broken up into types or groupings.

For example, in a banking scenario, you will most probably have the entity of account. This alone can suffice and in general you don’t have more options to work with.

But the ideal is to have the ability to create subsets for entities. Or, as in this case, be able to assign roles to the entity of account. For instance, there are different types of accounts. When you transfer money, you would want to have a to and from type of entity account.

Adding Entity Roles

In the nlu.md file, I have defined an intent to exchange money from one currency to another. This is an example of a user utterance with compound entities.

Within the user utterance, three entities are defined:

  • Transaction
  • Currency
  • Date/Time

Here is an example of how to define entities with roles in the nlu.md file.

## intent:exchange- I want to [change](transaction) [US dollars]{"entity": "currency", "role": "change_from"} to [Euros]{"entity": "currency", "role": "change_to"} on [Friday](date_time)- Can I [exchange](transaction) [euros]{"entity": "currency", "role": "change_from"} for [Rand]{"entity": "currency", "role": "change_to"} on [Saturday](date_time)- give me a rate to [change](transaction) [pounds sterling]{"entity": "currency", "role": "change_from"} for [Japanese Yen]{"entity": "currency", "role": "change_to"} on [Monday](date_time)- what are rates to [convert](transaction) [Australian Dollar]{"entity": "currency", "role": "change_from"} for [Russian Ruble]{"entity": "currency", "role": "change_to"} on [next week Thursday](date_time)- I want to [change](transaction) [US dollars]{"entity": "currency", "role": "change_from"} to [Canadian dollar]{"entity": "currency", "role": "change_to"} on [Friday](date_time)

The entity of currency is broken up into two roles:

  • Change From and
  • Change To.

Here is a practical example of user input requesting to exchange money. This is performed using Postman and the Rasa NLU API.

User utterance example with multiple compound entities.

The JSON output clearly define the recognized intent of exchange. With this, three entities are identified. The entity of currency has an additional value of role. In this case, the segmenting the currency changed from and to.

The intent is identified as exchange with the entities and respective roles.

Adding Entity Groups

Entity groups allow for entities to be grouped together. In the banking example, I have created the entity tiers. There are 5 tiers; Silver, Gold and Bronze; grouped together. Constituting group one.

Platinum & Black are grouped together. Constituting group two.

Here is an example on how to define entities with groups in the nlu.md file.

## intent:tiers- [Silver]{"entity": "tiers", "group": "1"} accounts have lower interest for saving than [Platinum]{"entity": "tiers", "group": "2"} - [Gold]{"entity": "tiers", "group": "1"} accounts have lower interest for saving than [black]{"entity": "tiers", "group": "2"}- [Bronze]{"entity": "tiers", "group": "1"} accounts have lower interest for saving than [Platinum]{"entity": "tiers", "group": "2"}

And the example of a user utterance, mentioning two of the tiers.

User utterance with different tiers which can be grouped.

The result is a JSON output with the entity tiers defined, and the grouping of the entity.

The intent tiers is correctly identified, with the group value for each entity.

Rasa Entities

Contextual & Compound

One of Rasa’s strong points all along were compound and contextual entities.

Contextually means that entities are not recognized by the chatbot by asking the user directly for the input, or found via a finite lookup list. But rather entities are detected based on their context within the utterance or sentence.

This is closer aligned with how we as humans detect entities in a conversation.

Rasa ~ Compound & Contextual Entities in Rasa-X

Compound entities mean I can capture multiple entities per intent, or user utterance. In a scenario where the user gives you all the information in one utterance, you have the ability to capture all those values in one go.

This translate into fewer dialog turns and a more efficient chatbot.

Entity Roles

The starting point of entities are that you can add labels to words. Hence you can define concepts in your data.

In the example below, you have different city types defined with other entities.

## intent:travel_details- I want to travel by [train](travel_mode) from [Berlin](from_city) to [Stuttgart](to_city) on [Friday](date_time)

This is not elegant, as multiple entities need to be created for one real-word object, namely city.

And in this example, city have two roles; the city of departure and the city of arrival. With Rasa you are able to define these entities with specific roles in your project’s nlu.md file.

## intent:travel_details
- I want to travel by [train](travel_mode) from [Berlin]{"entity": "city", "role": "depart"} to [Stuttgart]{"entity": "city", "role": "arrive"} on [Friday](date_time)

The output looks like this:

I want to travel by train from Berlin to Stuttgart on next week Wednesday.
{
"intent": {
"name": "travel_details",
"confidence": 0.9981381893157959
},
"entities": [
{
"entity": "travel_mode",
"start": 20,
"end": 25,
"value": "train",
"extractor": "DIETClassifier"
},
{
"entity": "city",
"start": 31,
"end": 37,
"role": "depart",
"value": "Berlin",
"extractor": "DIETClassifier"
},
{
"entity": "city",
"start": 41,
"end": 49,
"role": "arrive",
"value": "Stuttgart",
"extractor": "DIETClassifier"
}
],
"intent_ranking": [
{
"name": "travel_details",
"confidence": 0.9981381893157959
},

Entity Groups

This feature allows for entities to be grouped together with a specific group label. The best way to explain this is with an example…

Again, defined in your /data/nlu.md file:

## intent:teams
- The first team will be [John]{"entity": "teamMember", "group": "1"}, [Mary]{"entity": "teamMember", "group": "1"} and [Geoff]{"entity": "teamMember", "group": "1"} and the second groupto travel will be [Martha]{"entity": "teamMember", "group": "2"}, [Adam]{"entity": "teamMember", "group": "2"} and [Frank]{"entity": "teamMember", "group": "2"}.

And the output from Rasa NLU:

The first team will be John, Mary and Geoff and the second group to travel will be Martha, Adam and Frank.
{
"intent": {
"name": "teams",
"confidence": 0.9999754428863525
},
"entities": [
{
"entity": "teamMember",
"start": 23,
"end": 33,
"group": "1",
"value": "John, Mary",

"extractor": "DIETClassifier"
},
{
"entity": "teamMember",
"start": 38,
"end": 43,
"group": "1",
"value": "Geoff",

"extractor": "DIETClassifier"
},
{
"entity": "teamMember",
"start": 83,
"end": 95,
"group": "2",
"value": "Martha, Adam",

"extractor": "DIETClassifier"
},
{
"entity": "teamMember",
"start": 100,
"end": 105,
"group": "2",
"value": "Frank",

"extractor": "DIETClassifier"
}

Conclusion

It is evident that there are a few applications where complex user utterances and compound entities will need to be handled. This development by Rasa will most probably be extended and include other structures.

Read More Here

--

--

Cobus Greyling

I explore and write about all things at the intersection of AI & language; LLMs/NLP/NLU, Chat/Voicebots, CCAI. www.cobusgreyling.com