Handle Multiple Intents in single Utterance in LUIS - nlp

I need to handle multiple Intents in single Utterance in Luis. For example, there is an Intent called "Order" and i have configured that with Utterance below.
I want 2 pizza from Dominos and 2 bucket chicken from abc and xyz.
In the above Utterance there is 2 different orders i need to track.
1) 2 pizza from Dominos
where the Entitees are:
Quantity - 2,
Dish - Pizza,
Store - Dominos
2) 2 bucket chicken from KFC
where the Entitees are
Quantity - 2,
Dish - bucket chicken,
Store - abc and xyz
abc and xyz is the Store name and its a single store (store name itself contains and like Larson & toubro).
How can i handle this in LUIS? How can we handle same entitees multiple times in single utterance? Anyother NLP supports this thing?.
Can someone guide me on this?

With the example you provided, it looks like there is only one intent and that is Order. The user might order different items from different stores. So basically your utterances follow a pattern:
Buy x from b
Buy x,y,z from store a
Buy x from a and y from b
You can train your LUIS app with possible patterns to achieve more accuracy.
At the API endpoint you can check for entities do the following:
If there is only one entity of type item and one entity of type store then its type 1.
If there are multiple entities of type items and only one entity of
store then its type 2.
If there are multiple entities of type item and multiple entities of type store then type 3.
Its pretty much easy to get the store and items to order in the first 2 types. For the third type you can make use of the startIndex and endIndex property of entity returned by LUIS. You can group item entity with store entity checking the index values i.e Buy x from a and y from b so x is the first item encountered and so the store a so map item x with store a.
PS: This ain't the best approach, I'll update you if I get a better way out.

Related

How to append parameter to existing parameters list from previous context in Dialogflow?

I'm building a chatbot that asks users for symptoms, one at a time.
There is a single entity #symptom, which is a list. I'd like to figure out how to append each new symptom into the symptoms parameter list from existing contexts.
For example,
Bot: Please type in your 1st symptom.
User: Cough
symptoms = ['cough']
Bot: Please type in your 2nd symptom.
Fever: Fever
symptoms = ['cough', 'fever']
Bot: Please type in your 3rd symptom.
User: Breathlessness
symptoms = ['cough', 'fever']
How do I go about building such a flow?
(N.B. I know I can simply have one intent that asks user to type out all the symptoms in one line, but I'd prefer for the symptoms to be asked one by one so I can ensure data cleansing before inserting the symptom into the list)
This too is more of a design issue:) You can roughly achieve what you have described with Follow-up intents and contexts, but a better way would be to more clearly separate the intent and parameter matching from any kind of further backend processing.
You should, if you haven't already, define your symptom entity as a Developer mapping entity. This gives you the option to map an arbitrary number of synonyms to one reference value:
reference value: fever
synonyms: fever, feverishness, high temperature, febricity, febrility
The user can now enter any of the synonyms, you will always get the reference value as the parameter (and list of these values if the parameter is a list). The reference value doesn't even have to be a normal word, it can be any unique identifier (e.g. a primary key from database of symptoms). It is only matched if it itself is included in the list of synonyms.
This structure would ensure that you will always get a parameter from a clearly defined set of values, even if the actual user input has a much greater variability. Any further processing of these parameters should be part of your backend code and not be tied to the Dialogflow agent. Ideally you would think of the reference values as the API between the user input and you backend business logic.

Core data model - relationships

I am confused about how to design a Core Data Model for a particular trio of entities -- specifically, the relationships between them.
"Place" is an entity comprised of a name (String) and an address (String).
"Leg" is an entity comprised of a start (Place) and an end (Place).
"Route" is an entity comprised of an arbitrary number of legs (Leg) in a particular order.
In sum, a Route consists of an ordered list of Legs which themselves simply represent straight lines between two Places.
How would I model the relationship between the Leg and Place entities in the data model? Each Leg has exactly two Places (start and end); and any Place could be associated with an unlimited number of Legs, either as a start or an end.
In the Leg entity Add two relationships , one for startPlace and another for endPlace , make their type "To One"
In the Place entity add two inverse relationships (legsByStartPlaceInverse and legsByEndPlaceInverse) and make their type "To Many".
Make sure delete rules are not "Cascade".

Redis string or sets?

I want to store person & food pairs, person eats food in 5 minutes, so I need to expire the key. So I have 2 ways to do that, string or sets:
1. setex person:tommy:food:chicken 300 anything
setex person:tommy:food:chip 300 anything
...
2. sadd person:tommy chicken chip
expire person:tommy 300
Which is better? Or is there other way?
I would go with the second option. My reasons being:
Since there is no other information attached to entries, there is no reason to give each item its own key (this would be different if each item needed to store a hash of information, for example).
You can find out how many food items are linked to a person (SCARD) without creating another key.
You have all of the other set functions available to you if you need to manipulate or compare several sets to each other.
If you read the documentation on how redis expires keys, you notice that Redis has an active approach to expiring keys. Using the second option's design, it is guaranteed that all food data associated with someone will be removed at the same time, when the key expiration method runs.
To some degree, this question seems analogous to using individual variables in a programming language, as opposed to an array:
a = 3, b = 5, c = 7
sum = a + b + c
versus
items = [3, 5, 7]
sum = sum(items)

self-referencing core data model for specific use case

I have seen other posts that self-referencing a core data entity is possible, but I feel my use case is a little different and I am having a hard time understanding how to wire things up.
I have a Person entity and I want to track 2 things:
- an array of Person entities whose profile the user "visited"
- an array of Person entities who have viewed "this" users profile
The inverse logic is making it hard to understand.
I have User A, User B.
If user A visits user B, the following relationships should be set up:
- User A's visited profiles shows User B.
- User B should see that user A visited him.
This is a To-Many relationship as things are "interesting" only when you know who you followed and who's following you... :-)
Am I making this more complex than it is? :-(
What I tried:
Person Entity
-visitedProfiles : inverse is viewedProfiles (To-Many relationship)
-viewedProfiles : inverse is visitedProfiles (To-Many relationship)
Result:
User A --> User B (user A visists user B)
User A sees User B in BOTH (visitedProfiles and viewedProfiles) relationship.
Side-effect:
Also, regardless of how many profiles I visit, "visitedProfiles" and "viewedProfiles" always has only 1 item in the array (ie. the last profile I visited)
It's not an especially complicated case. I personally find your choice of words a bit confusing, though. "viewedProfiles" and "visitedProfiles" don't sound like inverses of each other to me. How about "viewedProfiles" and "viewers" instead?
Regardless of the word choice, though, set up the relationships as you have described. If you add B to "viewers of A", then B's "viewedProfiles" will also be updated.
Your side effect of knowing the most recent view/visit takes a little extra work. You could use an ordered relationship for the viewers/viewees; that feels like the simplest thing to do. Or you could add a new entity, a Visit, which notes the viewer, the viewee, and the time/date of the visit. But that second approach is indeed more complicated.
Your definition of the relationships looks OK. You can call either
[a addVisitedProfilesObject:b];
or
[b addViewedProfilesObject:a];
to add b to a.visitedProfiles and a to b.viewedProfiles.

Matching Based on Arbitrary Categories and Similarity Measures

I have customer database who have certain attributes, and a customer type. The collection of attributes can vary (they do come from a finite set though), and when I look at a new customer with unknown type, with given attributes, I would like to determine which type s/he belongs to. For example, say I have these customers already in DB,
Customer | Type | Attributes
1 A 44,32,5,'X'
2 A 3,32,66,'A'
3 B 6,32,'A', 'B'
4 C 47,31,2,'H'
5 C 14,32,2,'O'
6 C 2,'C'
7 A 44
When I receive a new customer who has attributes, for example, 3,32,2, I would like to determine which type this customer belongs to, and the code should report its confidence (as percentage) of this match.
What is the best method to use here? Something statistical, or a method based on an affinity matrix of some kind, or recommendation engine style Pearson Correlation coefficients based approach? Sample, pseude code would be most welcome, but any, all ideas are fine.
Thanks,
The way to solve this problem is using Naive Bayes.

Resources