Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slots not populating #1987

Closed
dejanmarich opened this issue Mar 20, 2018 · 37 comments
Closed

Slots not populating #1987

dejanmarich opened this issue Mar 20, 2018 · 37 comments

Comments

@dejanmarich
Copy link

Rasa Core version: 0.8.3

Python version: 3.6.3

Operating system (windows, osx, ...): OSX 10.11.16 (El Capitan)

Issue: When using train_online.py script for dialogue training, when i enter my answer, slots does not fill. Slot "person" is filled most of the time, slot "currency" never and slot "amount" always. Wish I can figure out what is wrong, because they are all the same name as entities in NLU model.

Content of domain file (if used & relevant):

slots:
  person:
    type: text
  value:
    type: float
  currency:
    type: text

entities:
  - value
  - currency
  - person

intents:
  - pay
  - greet
  - bye

templates:
  utter_greet:
    - 'Hello! How can I help?'
  utter_bye:
    - 'Glad I could help! Bye!'
  utter_ask_person:
    - 'To whom you want to pay?'
  utter_ask_value:
    - 'How much would you like to pay?'
  utter_ask_currency:
    - 'In which currency'
  utter_ask_payconfirm:
    - 'Are you sure you want to pay VALUE: {value} CURRENCY: {currency} to PERSON: {person}'
  utter_payconfirmed:
    - 'You succesfuly paid VALUE: {value} CURRENCY: {currency} to PERSON: {person}'
  utter_anythingelse:
    - 'Can I help with anything else?'

actions:
    - utter_bye
    - utter_greet
    - utter_ask_value
    - utter_ask_person
    - utter_ask_currency
    - utter_ask_payconfirm
    - utter_payconfirmed
    - utter_anythingelse

screen shot 2018-03-20 at 11 58 42

@dejanmarich
Copy link
Author

when i try all at once, it's populating.. really don't understand what is happening :)

screen shot 2018-03-20 at 12 35 20

@tmbo
Copy link
Member

tmbo commented Mar 21, 2018

Try running with --debug. I think the reason the slots do not get populated is that the NLU did not find your entities. E.g. adding more training data to your NLU model might fix that.

@dejanmarich
Copy link
Author

--debug shows nothing.. will try to add more training data and try again, thanks

@tmbo
Copy link
Member

tmbo commented Mar 21, 2018

It should show you the intent of the messages as well as detected entities, you need to pass that to the training script, e.g. python -m rasa_core.train --debug ...

@dejanmarich
Copy link
Author

screen shot 2018-03-21 at 15 12 44

@dejanmarich
Copy link
Author

with 170 examples for intent "pay" and 15 examples for intents "greet" and "bye"

@dejanmarich
Copy link
Author

still not getting slots populated via train_online.py..

@dejanmarich
Copy link
Author

botina.zip

if you can try to reproduce please, thanks

@foxjr
Copy link

foxjr commented Mar 23, 2018

The machine is going to know what slots to fill via the stories file. I looked at your stories, and they seem very random. I doubt that with the few stories you have, your model will be at all effective in predicting story flow.

For instance:

* pay{"value": "3000"}
    - slot{"value": "3000"}
    - utter_ask_currency
    - slot{"currency": "kuna"}
* pay
    - utter_ask_payconfirm

You're telling the machine that the intent pay may have the entity value, and should be followed by a value slot fill. Then, the bot should utter_ask_currency and fill the currency slot, but without any user interaction at all. How is the machine supposed to know to fill the currency slot without any indication from the user to do so?

In the same story, you then have a user intent of pay, but without any entities. Subsequently, the bot should utter_ask_payconfirm. That would be fine if every time the intent is pay without any entities being extracted, the bot should utter_ask_payconfirm, but in another story you have an entity-less pay being followed by utter_ask_value. How is the bot supposed to differentiate between those utterances based on the same user intent?

It looks like you need more user intents, to start. And your stories should look a little more like this:

* pay[value=3000]
  - slot{"value": "3000"}
  - action_check_details
  - slot{"has_currency": 0}
  - utter_ask_currency
* inform[currency=kuna]
  - slot{"currency": "kuna"}
  - action_check_details
  - slot{"has_person": 0}
  - utter_ask_person
* inform[person=mario]
  - slot{"person": "mario"}
  - action_check_details
  - slot{"is_complete": 1}
  - utter_confirm_details
* confirm
  - utter_confirm_pay
* confirm
  - action_complete_payment
  - slot{"confirmation": "1234567890"}
  - utter_pay_complete

In the above story, the are multiple user intents to correspond to different categories of intent that could be possible. When the user indicates an intent and an entity is extracted (e.g., pay[value=3000]), the machine should know to fill the value slot. Next, the action should fill a bool slot to show that the currency has not been acquired, which would tell the machine to ask for the currency. This format continues throughout the story.

I hope this helps!

@dejanmarich
Copy link
Author

thank you, but not quite sure how to define "inform" intent in nlu training data and "action_check_details" should be some custom action I suppose?

@dejanmarich
Copy link
Author

i don't understand how you define those 2 actions (check_details and complete_payment)

@foxjr
Copy link

foxjr commented Mar 26, 2018

Yeah, those are all custom. I'm just giving you some ideas for how you could expand your content to allow smarter interactions. As far as how to create those NLU objects, have a look at the documentation.

@surya103
Copy link

surya103 commented Mar 26, 2018

@foxjr - One question, in the above story you described

  • pay[value=3000]
    • slot{"value": "3000"}
    • action_check_details
    • slot{"has_currency": 0}
    • utter_ask_currency

if NLU identifies the intent as "Pay" and the entity "Value" as "3000", do you really need to set the slot again? By using - slot{"value": "3000"} ?
I am assuming you are having value as both entity and slot in the domain and hence, Rasa would automatically fill the slot value.

@dejanmarich
Copy link
Author

why can't i use intent PAY instead of INFORM? "pay 200" and bot should ask me for person and currency, why i need another intent inform?

and how do I write custom action for "check_details", sorry for so much questions, but documentation isn't helping me much

@foxjr
Copy link

foxjr commented Mar 26, 2018

@surya103 Yeah, that's it; in my example, value is both an entity and a slot. I played around with some different methods for slot-filling, and the most consistently good outcome I achieved was by doing it like that. The format given tells the machine that the entity should be extracted from the user's statement, and then the slot by that same name should be filled with the same value given. The slot fill is also the cue for the machine to check the details next to confirm whether all details have been given.

Here's some example code to illustrate what I had in mind with those bool slots, which may also be helpful for @dejanmarich :

return_slots = []
details = ['value', 'currency', 'person']

for detail in details:
    if tracker.get_slot(detail) == None:
        has_detail =  'has_' + detail
        return_slots.append(SlotSet(has_detail, 0))
        break

return return_slots

Slot-filling isn't just a way to pass data to actions--it's really important for the conversational flow. Filling a certain has_detail slot with 0 would indicate to the machine that a particular detail is missing, and so the bot should ask for it.

@foxjr
Copy link

foxjr commented Mar 26, 2018

@dejanmarich Having the inform intent was just based on my own intuition of how best to direct a conversation; you may arrive at a different conclusion. The pay NLU objects would be statements such as pay 200 kuna from robert, 40 usd, 250, etc. They are statements the user would make that are not in response to a question posed by the bot--unless you have an utterance such as How are you paying for this today? The inform intent is only in response to utterances such as What currency are you using?, How much is the payment?, May I please have the payer's name?, etc. It's a nuanced distinction, to be sure.

@surya103
Copy link

@foxjr Understood the logic to find what else needs to be filled. But, my question was primarily on "value" slot - i.e. assuming that, the slot is filled and also explicitly setting in the story. Isn't that redundant?

@foxjr
Copy link

foxjr commented Mar 26, 2018

Extracting an entity and filling a slot are completely different things, and are independent of each other by default. In my stories, I show explicitly the entities being extracted and the slots being filled to create the association between the two.
Using the same example,

* inform[person=mario]
  - slot{"person": "mario"}
  - action_check_details
  - slot{"is_complete": 1}
  - utter_confirm_details

The person slot should be filled on its own, and the is_complete slot is filled by the logic of the action. Either way, I've had the best outcome when explicitly indicating the slots to be filled and the entities to be extracted.

Does this answer your question?

@dejanmarich
Copy link
Author

I will have "change", "pay", "credit", "funds", "balance" intents.. what I don't understand is when should I use "inform" and when "pay"?!
(send 200$, send and send 200 to Mark) = "pay"
(change 20$ to EUR, change, change 20$) = "change"

idk if i'm getting something wrong, but how should bot recognize intent as "pay" if i define in NLU "pay 200" as "inform"

@foxjr
Copy link

foxjr commented Mar 26, 2018

With enough examples, you could get either of those to work. I'm just giving you some options to consider to get your project up and running.

@dejanmarich
Copy link
Author

dejanmarich commented Mar 27, 2018

  • pay[value=3000]
  • slot{"value": "3000"}
  • slot{"has_currency": 0}
  • utter_ask_currency
  • pay[currency=HRK]
    • slot{"currency": "HRK"}
    • slot{"has_person": 0}
    • utter_ask_person
  • pay[person=mario]
    • slot{"person": "mario"}
    • slot{"is_complete": 1}
    • utter_ask_payconfirm
  • confirm
    • utter_payconfirmed
    • utter_anythingelse
  • bye
    • utter_bye

still wondering why can't I fill the slot with online training method. When I used weatherbot, it was same logic, with only 3 stories and was working just fine. Entities and slots have same name. Should I try to add more stories or more NLU examples then?

And I'm bit confused with using custiom actions, if i name my file "actions.py" then in domain.yml I just use actions.name_of_action or I need to define somewhere else source file (actions.py)?

(can you give me some contact, skype/mail/slack, I would really appreciate some input/help)

tnx (mail: dejan.marich@gmail.com , skype: dmaricsb)

@Harish0596
Copy link

@foxjr your example is perfect in case of dependent entities i mean in order to execute something you need all those entities. In my case i'm having two entities which are also slots, which are independent. Those two entities will be of numerical data(three digit eg:123). Here rasa fails to fill the value of that entity into it's respective slot instead it is filling the two value slots only into one slot

For example consider my entities(also slots) are orderId, tId

- get the details of order with id 123

slot : orderId : 123, tId : none

- i need details of ticket which has id 623

slot : orderId : 623, tId: none
It fails to sit in tId

How to overcome this situation ?

@DhruvMevada
Copy link

@dejanmarich getting same issue, Slots are not populating. Values are not getting set in slot.

@dejanmarich
Copy link
Author

graf

according to this, it should be fine, but drugin online training it's not populating slots and intents and slots have the same name. In "weather bot" example everything works fine, still can't find out why is this happening..

@foxjr
Copy link

foxjr commented Mar 29, 2018

@Harish0596 Personally, I would create a category slot that allows only tId or orderId for values, and another slot for the ID itself. This should be illustrated through ample stories and NLU objects. From there, you could have separate actions for each type of search, or a single action for both searches.

{
  "text": "i need details of ticket which has id 623",
  "intent": "search_details",
  "entities": [
    {
      "start": 18,
      "end": 24,
      "value": "tId",
      "entity": "search_term"
    },
    {
      "start": 38,
      "end": 41,
      "value": "623",
      "entity": "search_value"
    }
  ]
}

@dejanmarich
Copy link
Author

dejanmarich commented Apr 5, 2018

DEBUG:rasa_core.policies.keras_policy:None INFO:rasa_core.policies.keras_policy:Fitting model with 82 total samples and a validation split of 0.0 INFO:rasa_core.policies.keras_policy:Done fitting keras policy model DEBUG:rasa_core.tracker_store:Creating a new tracker for id 'default'. DEBUG:rasa_core.processor:Received user message 'pay 800 to Dora' with intent '{'name': 'pay', 'confidence': 0.9999955660379932}' and entities '[{'start': 4, 'end': 7, 'value': '800', 'entity': 'value', 'extractor': 'ner_crf'}, {'start': 11, 'end': 15, 'value': 'dora', 'entity': 'person', 'extractor': 'ner_crf'}]' DEBUG:rasa_core.processor:Logged UserUtterance - tracker now has 4 events DEBUG:rasa_core.processor:Current slot values: currency: None person: dora value: 800 DEBUG:rasa_core.policies.memoization:Current tracker state [ None None [('intent_pay', 1), ('entity_value', 1), ('entity_person', 1), ('slot_person_0', 1), ('slot_value_0', 1), ('prev_action_listen', 1)]] DEBUG:rasa_core.policies.ensemble:Predicted next action 'action_check_currency' with prob 0.81. DEBUG:rasa_core.processor:Bot utterance 'BotUttered(text: Please enter CURRENCY, data: null)' DEBUG:rasa_core.processor:Action 'action_check_currency' ended with events '[]' DEBUG:rasa_core.policies.memoization:Current tracker state [ None [('intent_pay', 1), ('entity_value', 1), ('entity_person', 1), ('slot_person_0', 1), ('slot_value_0', 1), ('prev_action_listen', 1)] [('intent_pay', 1), ('entity_value', 1), ('entity_person', 1), ('slot_person_0', 1), ('slot_value_0', 1), ('prev_action_check_currency', 1)]] DEBUG:rasa_core.policies.ensemble:Predicted next action 'action_listen' with prob 1.00. DEBUG:rasa_core.processor:Action 'action_listen' ended with events '[]' DEBUG:rasa_core.processor:Current topic: None DEBUG:rasa_core.tracker_store:Recreating tracker for id 'default' DEBUG:rasa_core.processor:Received user message 'kn' with intent '{'name': 'greet', 'confidence': 0.4738416012153414}' and entities '[]' DEBUG:rasa_core.processor:Logged UserUtterance - tracker now has 8 events DEBUG:rasa_core.processor:Current slot values: currency: None person: dora value: 800 DEBUG:rasa_core.policies.memoization:Current tracker state [ [('intent_pay', 1), ('entity_value', 1), ('entity_person', 1), ('slot_person_0', 1), ('slot_value_0', 1), ('prev_action_listen', 1)] [('intent_pay', 1), ('entity_value', 1), ('entity_person', 1), ('slot_person_0', 1), ('slot_value_0', 1), ('prev_action_check_currency', 1)] [('intent_greet', 1), ('slot_person_0', 1), ('slot_value_0', 1), ('prev_action_listen', 1)]]

@foxjr
Copy link

foxjr commented Apr 5, 2018

Looks good, up until not recognizing kn as a currency. Do you have synonyms for discrepancies like that?

@dejanmarich
Copy link
Author

i tried EUR, USD, $, HRK.. none of these works.. in another example it's not recognizing "person", only value works fine

@foxjr
Copy link

foxjr commented Apr 5, 2018

Looks like you're still going with the single intent of pay instead of breaking it up into separate ones. Do you have lots of NLU objects showing single words mapping to the correct intents and entities? You should have NLU objects with text kn mapping to intent pay with entity currency being kuna. That will create the synonyms, and synonyms should be referenced in your pipeline. My intuition is still to have an inform intent to handle those single word answers, but that's just me.

@foxjr
Copy link

foxjr commented Apr 5, 2018

And keep in mind that entity ranges are specified in NLU objects using [n,m) intervals; for example, text kn would have "start": 0 and "end": 2.

@dejanmarich
Copy link
Author

dejanmarich commented Apr 5, 2018

class ActionCheckCurrency(Action):
def name(self):
return 'action_check_currency'
def run(self, dispatcher, tracker, domain):
currency = tracker.get_slot("currency")
if currency == None:
dispatcher.utter_message("Please enter CURRENCY")
return []
else:
return [SlotSet("currency", currency)]

this is my custom action for checking if curreny is set (if not then it should ask for it), but it's not getting populated either.

my nlu data is in attachment and yes, I use only "pay" intent..
data.json.zip

@foxjr
Copy link

foxjr commented Apr 5, 2018

Ah, okay. I see a problem. You're using dispatcher.utter_message to do what your flow should be handling. When you use that backdoor to say things, you're bypassing the flow. Instead, have Please enter CURRENCY as a template, and reference that template in your stories.

I posted this a while up as an example for part of the action:

return_slots = []
details = ['value', 'currency', 'person']

for detail in details:
    if tracker.get_slot(detail) == None:
        has_detail =  'has_' + detail
        return_slots.append(SlotSet(has_detail, 0))
        break

return return_slots

In effect, you're setting the slot of the first missing detail to 0 and then moving on. Your stories will show that when a has_<detail> slot is set to 0, the template to ask for that detail should be used. Following that, the bot should expect--in a manner of speaking, of course--that the user's response is an attempt to provide that detail.

As it is now, you're using dispatcher.utter_message to request information, and then expecting the bot to understand that the next thing the user says belongs to a particular slot.

@foxjr
Copy link

foxjr commented Apr 5, 2018

Also, I don't see any NLU objects that are currencies alone, such as:

{
  "text": "kn",
...
}

That's going to come into play when users are simply answering a template question.

@dejanmarich
Copy link
Author

Hi, could you provide complete code for class ActionCheckDetails(Action): or action_complete_payment. I tried this method, but can't train because some errors

@foxjr
Copy link

foxjr commented Apr 9, 2018

I haven't written it. Post what you have so far, including the errors.

@foxjr
Copy link

foxjr commented Apr 11, 2018

I think it would be more helpful to others if we close this question and create new ones as needed. It's become quite a long thread for others to sift through for information.

@tmbo
Copy link
Member

tmbo commented Apr 11, 2018

Yes, very true. Please if you have any issues, create separate ones on github. 👍

@tmbo tmbo closed this as completed Apr 11, 2018
@tmbo tmbo transferred this issue from RasaHQ/rasa_core Mar 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants