IBM Watson Assistant: How to ask a series of questions and store related answers? - ibm-cloud

I want to ask a series of question , taking each input and saving them in a context variable and then moving to the next question.
The problem is whenever a user responds IBM Watson starts classifying it into intents. and goes to that specific intent. What i want would look something like this:
Whats your name?
user input = xyz
xyz gets stored in username and then the bot asks the next question
whats your organ name
and so on.

My advice would be to work with slots and to define entities for what you want to capture. This allows for a more natural flow. "Henrik from xyz" could be directly stored as name "Henrik" and "yyz" as org.
If you just want to have a series of questions and store whatever was answered, take a look at special conditions. If you use true as condition and store the entire input into a context variable, you get what you asked for.

Related

IBM Watson Assistant - exclude a specific entity value so as not to match it ever

This could be a simple one that I haven't been able to find but I'm trying to exclude a single value ("girlfriend") from being picked up as an entity in a chatbot I'm building. The entity list is currently "dog, cat, pet, mum, horse" with relevant synonyms for each of those entities as well.
Watson keeps picking up "girlfriend" and matching it as an entity despite it not being in there which is stuffing up the logic in the conversation.
Is there a way to stop Watson identifying similar words in an entity list beyond what is in the list? I have tried turning off fuzzy matching but that just misses spelling mistakes.
Please note this is not an intent training issue, it is specifically asking about entity identification.
Any help appreciated.
-T-
Your question is not entirely clear, but likely you want to take a look at how to improve a skill. Because Watson Assistant is built on AI technology, a key part is about learning.
You can "teach" Watson Assistant by going back to conversations and correct wrong matches with the right ones. Watson Assistant is going to pick this up and then retrain the dialog. This should result in excluding "girlfriend".
I had a similar problem. My bot kept picking its own name as a username and I wanted it to ignore its own name even if the user typed it (e.g. Hello Robot, I am Jill) I wanted it to respond to 'Jill' and not 'Robot' but it kept missing it. I later realized the context variables I created had similar values to user names. So what I did was create a variable #bot-name and gave it only 1 value (Robot), no synonyms, no fuzzy match, no annotations. Then tried it again and the Bot recognized its own name, ignored that and picked the second name correctly as the user name. So when I repeated the sentence 'Hello Robot, I am Jill' it recognized #entity:bot-name and #entity:user-name and then responded only to the username. You can try something similar.
Its not clear how you created your entity list. If its was via contextual entities then Watson may be taking "girlfriend" as being in the same "family" as the other entities and adding to the entity list. If the entity list was hard coded, along with the synonyms, then I would guess that one of your synonyms shares some of the spelling of girlfriend, girl or friend. Which via fuzzy logic would match an entity, but with a lower confidence level.
To fix you could create a new entity list and have a condition that looks to match entity list one, but not entity list two (girlfriend).
Or you could set your condition on the entity list and entity confidence level > 0.8 - but you may then miss some spelling mistakes. (Select a confidence level thats just above that reported for girlfriend).
I can't say if this is a solution, However I'd prefer to call it a workaround as it worked for me in my case.
Non-Contextual Case:
Create a new entity and add girlfriend as a value. Thus it would never interfere with your current entity in a dialog flow.
Contextual Case:
Train an intent with examples which includes girlfriend and annotate it with new entity.

Watson Assistant: Can I define Intent using Entities in the Examples?

How to I create an #Intent which looks something like this:
How much is a #ProductType?
Whereas the #ProductType is an simple Entity which consists of:
Soft Drinks: Coke, Pepsi, Sprite, Fanta
Fruits: Apple, Banana, Watermelon
I tried adding an Intent with above settings, but it doesn't seem to work. Is such ability natively supported in IBM Watson? Or otherwise, do I need to manually handle in the Dialog, using Conditions and stuffs? Please kindly advise.
The training is based on regular language and typical sentences or phrases. So #ProductType is not what you want in the phrase, but any of the fruits or drinks.
By defining the entities, Watson Assistant later learns the connection and to identify the entities and intents.
To get started, you define the intents and entities. Both can be imported from lists. Then you add the dialog which references the different types.
This blog should give insight to all the ways to train an entity and how it is used within intents.
https://medium.com/ibm-watson/all-about-entities-dictionaries-and-patterns-with-watson-assistant-part-1-5ef7254df76b
There are a number of possible pipelines you can choose from.
1. Indirect references: this is the preferred method.
Use natural language in your intent training data. "I want to buy a pear"
Watson will automatically see the other values you have related to pear and use those as intent training as well. This will be the fastest and simplest way to manage your data
2. Direct references: this should only be used if absolutely necessary
Directly reference the entity in your intent data. "I want to buy an #pear"
Nothing is done in the UI to tell you this works, but it does. This tells Watson the entity is a very important term and will increase the weight, as well as reference all synonyms with high weight. This is more effort for you to go through your entire workspace and relabel everything this way, hence why it is not recommended unless absolutely necessary. By doing this, you also tell watson that when the system sees various fruits without the # symbol, to ignore them as entities which is not ideal
3. Contextual entities. This is highlighting them like in your screenshot.
Note the UI has been updated so there is no an annotation mode instead of just highlighting. This builds a model around the entity, and is good for things like names or locations, but not necessary for a small list of items like crayons in a box, or fruit in a store. This will ignore all of the dictionary values youve created and only look at the model. It should be used according to the blog above when the use case is ideal.
What #data_henrik answered was partially correct. But it doesn't seem like Watson Assistant "automatically" learns the preferred #Entity just by simply inputting the pure (plain-text) Examples into the #Intent. In fact, that step was required. But we still need to do one more step.
After keying in the good plain-text Examples into the #Intent, we then still need to "right click" on the text-string of the possible #Entity entry, and then choose (teach Watson) the correct #Entity name from the dropdown list appeared.
Only then Watson starts to understand such; this #Intent uses that #Entity, I suppose.
Thank you #data_henrik, and appreciate your hint.

Dealing with newlines or multi line responses from a user with a chatbot?

Is there a known way to deal with users writing responses over multiple lines? - is it best to handle this case on the client level? as in checking if the user is still typing and have a delay between responses, or can this be handled on Watson somehow?
An example would be:
Bot:
What's Your Name?
User:
My name is
Nour
Those are two independent messages by the user over 2 lines.
It is best to always send the full "utterance" to Assistant in one request, because the processing does not work across multiple split calls to Assistant. Otherwise you would need to do some complex logic with context variables, or ask back the user their name if they uttered "my name is" without an actual name.
Generally the client side UI would wait for the user to press Enter before sending the utterance to Assistant. So you can be sure they have entered the full utterance.
But perhaps if they do utter "my name is" you could have an intent which checks for a name and an entity that extracts the name, and a dialog node which if the intent is found has a slot which ensures the entity is also found. In that way, if they do say "my name is" and no name, the bot will ask them for their name.
DSeager's approach is potentially the right way for the example you gave. The reason being is that within your overall question you have an entity.
What about where there is on real entity? For example:
Two Intents.
Pay my speeding fine
Pay my parking fine
Here you are using the intents to understand the answer without the need of an entity. Some will argue the Intent->Entity approach, but depending on your solution it can generally not scale as well versus just an intent answer.
So now your user enters the following:
How do I pay my
parking fine
Entity solution doesn't really work here as you have no context that they want to pay.
So one approach.
1. Send "How do I pay my" to WA. Assuming you have trained the system well it should come back with a low confidence or irrelevant.
2. Before you respond to the user, see if another utterance has been cached to send. If it has, then append with some kind of marker and send. For example:
How do I pay my !! parking fine
This will return the correct answer.
But wait a second, what if they do this?
How do I pay my parking fine?
Where do I pay it?
Both are valid questions, but the second one will fail and you can't append it to the previous.
In this instance, when an answer displays have it set a $anaphora context variable. Then if you get a low confidence/irrelevant response try reasking with the $anaphora value appended.
For example:
Q: How do I pay my parking fine?
A: <Answer> $anaphora = "parking fine"
Q: Where do I pay it?
A: <Irrelevant>
Q: parking fine !! Where do I pay it?
Both of these require some work at the application layer.

Symfony2 - embedded forms without wanting to modify the parent

I'm in a bit of a design bind. I have a series of questions, and I want a user to enter a score for each question. There's a 1:* relationship between questions and scores, but on this particular form the user should only be able to enter one score per question. So, how can I create a form type that would automatically link the score to each question, like:
1. blah blah blah? Score: // user enters a score
2. blah blah blah? Score: // user enters a score
etc.
I can't divulge my entities due to a NDA, but suffice it to say, Question is on the 1 side, and Score is on the * side. Question::getScores() and Question::setScores($scores) are available to me, as are Score::getQuestion() and Score::setQuestion($question).
If this was straight PHP, it wouldn't be a problem. Symfony2's form component is a bit convoluted, so I'm not sure how to proceed.
What you want to accomplish is to create a Score object for each question in the form on submit for the current user.
To accomplish this, first create a form type for the Score object.
<?php
// src/Acme/Bundle/Form/Type/ScoreType.php
// ...
$builder->add('ranking', 'integer')
This will allow your application to create Score objects via a form.
Now, in your Question form type, you'll want to embed a non-mapped Score form (for reasons discussed below), ie.
<?php
// src/Acme/Bundle/Form/Type/QuestionType.php
// ...
$builder->add('question')
$builder->add('score', new ScoreType(), array('mapped'=>false))
I assume that you currently have a setup similar to this, except you are probably using a collection type on 'scores' with the ScoreType. However, if this form is meant to be seen by the current user, then you are not going to want to display a collection. You would rather only display one, the one attached to the current user. Symfony cannot know this logic, since it is specific to your business logic.
This is where events come in. Please see http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
My approach would be to bind an EventSubscriber to the Question form. You should probably listen to PRE_SET_DATA event and a SUBMIT event.
Your PRE_SET_DATA listener should inspect the incoming Question object for information about what score it should put into the "score" form. For example, if the entity manager is injected into your subscriber, you might ask the EM if this user has a score already for this particular question, and if so grab it and place it as the data in "score". If not, create a new blank Score object and associate it to this question and the current user.
Now, once a form is submitted, listen to SUBMIT and do some logic there with the score object. This is why we don't map it to the question, because its a 1:*. Our form is a 1:1. These events are where you do your logic to make the connection. During POST_SUBMIT you could grab the Score object and call $score->setQuestion() with the form's data.
I realize this is a little vague and somewhat rushed answer but I hope it guides you in the right direction.

word suggestion based on input algorithm?

I am thinking of creating a web site, which lets people to rate restaurants. Since I don't have a database containing all the restaurants, this web site relies on user's inputs.
But there is a problem of this method, because people may use different word (name) to describe a same restaurant, but I don't want to create different entries inside the database, as they refer to the same restaurant.
For example, when describing KFC, somebody use the name "KFC", others may use "Kentucky Fried Chicken"
How can I make the system to automatically detect this? and give the user a list of existing items of the database.
This should quite similar to stackoverflow, which tells you "questions with similar title". But I don't know how to implement this.
You can't ... you have to create a list of the restaurant names and their "synonyms" and other possible spellings.
How can I make the system to automatically detect this?
The system doesn't know that "KFC" means "Kentucky Fried Chicken".
Make a map of synonyms, to let it know.
This should quite similar to stackoverflow, which tells you "questions with similar title"
It generally matches word-for-word. It may have an internal list of synonyms to deal with common cases.

Categories