-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Chatterbot returns a random answer when asked the same question multiple times. Fixes #71 #72
Conversation
…lar to the one in the training set) multiple times
Thank you for the pull request. This looks like it should be good to merge, I just want to check a few things locally first. Mainly because this makes modifications to the response statement, which was previously unmodified so this creates a small hole for test results because nothing is checking to see what is added to the response statement in the database. |
Would it help if the test_similar_sentence_gets_same_response_multiple_times functions checks all the values present in in_response_to list? |
Hi @jamdagni86, I just checked over this pull request. I cannot merge the changes to I believe the issue may be being caused elsewhere in the code. Running the test case you created against the current codebase I noticed that subsequent calls of the response1 = self.chatbot.get_response('how do you login to gmail?')
response2 = self.chatbot.get_response('how do I login to gmail?')
response3 = self.chatbot.get_response('how do I login to gmail?') actually ignores the chatbot's responses so that it thinks 'how do I login to gmail?' is a response to whatever was returned from 'how do you login to gmail?'. This can also be seen in the database dumps from each step in the test case: After training: {
"Goto gmail.com, enter your login information and hit enter!":{
"in_response_to":[
["how do you login to gmail?", 1]
]
},
"how do you login to gmail?":{
"in_response_to":[]
}
} After response_to_trained_set {
"Goto gmail.com, enter your login information and hit enter!":{
"in_response_to":[
["how do you login to gmail?", 1]
]
},
"how do you login to gmail?":{
"in_response_to":[]
}
} After similar_question_1: {
"Goto gmail.com, enter your login information and hit enter!":{
"in_response_to":[
["how do you login to gmail?", 1]
]
},
"how do you login to gmail?":{
"in_response_to":[]
},
"how do I login to gmail?":{
"in_response_to":[
["Goto gmail.com, enter your login information and hit enter!", 1]
]
}
} After similar_question_2: {
"Goto gmail.com, enter your login information and hit enter!":{
"in_response_to":[
["how do you login to gmail?", 1]
]
},
"how do you login to gmail?":{
"in_response_to":[]
},
"how do I login to gmail?":{
"in_response_to":[
["Goto gmail.com, enter your login information and hit enter!", 2]
]
}
} Based on what I am seeing I don't believer there is an issue here. I can see how it would be useful to get a response independent of the current conversation. Perhaps an additional method to accomplish this would be a better solution? |
Hey @gunthercox, this is an existing behavior. Without my code change, this is how the db looks. Training set: training = [
"how do you login to gmail?",
"Goto gmail.com, enter your login information and hit enter!?"
] db after training: {
"Goto gmail.com, enter your login information and hit enter!?": {
"in_response_to": [
[
"how do you login to gmail?",
1
]
]
},
"how do you login to gmail?": {
"in_response_to": []
}
} If you ask the same question twice, chatbot.get_response('how do you login to gmail?') {
"Goto gmail.com, enter your login information and hit enter!?": {
"in_response_to": [
[
"how do you login to gmail?",
1
]
]
},
"how do you login to gmail?": {
"in_response_to": [
[
"Goto gmail.com, enter your login information and hit enter!?",
1
]
]
}
} As you pointed out, the bot now thinks that the answer to previous_statement = self.get_last_statement()
if previous_statement:
input_statement.add_response(previous_statement) My changes in the {
"Goto gmail.com, enter your login information and hit enter!?": {
"in_response_to": [
[
"how do you login to gmail?",
1
],
[
"how do I login to gmail?",
1
]
]
},
"how do I login to gmail?": {
"in_response_to": []
},
"how do you login to gmail?": {
"in_response_to": []
}
} Now, if the same question is asked repeatedly, it updates the db like this. {
"Goto gmail.com, enter your login information and hit enter!?": {
"in_response_to": [
[
"how do you login to gmail?",
1
],
[
"how do I login to gmail?",
1
]
]
},
"how do I login to gmail?": {
"in_response_to": [
[
"Goto gmail.com, enter your login information and hit enter!?",
1
]
]
},
"how do you login to gmail?": {
"in_response_to": []
}
} The bug I'm trying to fix here is, if a similar question (how do i login to gmail) - to the one in the training set (how do you login to gmail) - is asked multiple times, the bot replies properly the first time. From then onwards, it will return a random answer to the same question. This is because, the first time the question is asked, it is going to add this to the db. "how do I login to gmail?": {
"in_response_to": []
} The next time the same question is asked, the closest match logic will find this statement and since this question is not configured to have a response, the bot returns a random answer. |
Hi @jamdagni86, I'm very sorry about not getting back to you promptly. My schedule has been very busy lately. I just had a chance to walk through the test output you provided and figured out where the main part of the issue is. In the main The issue that you ran into was because after the first time the the similar statement was entered as input, the statement then existed in the database, however it had no response values. Your fix modifies the input statement to correct this. However this can lead to possible problems later if the input response that chatterbot provides is incorrect (very possible when working with small data sets). To correct this issue with out modifying response data, I am going to modify the storage adapter to include a not filter. This will allow the initial filter set of all known responses to exclude any statements that do not have a known response. I am currently working on adding these changes and will create a new pull request later (likely tonight). Again, thank you for bringing this issue to my attention, and my apologies for not getting to this sooner. |
I just opened #81 which adds a check to remove statements that are no in response to a known statement. Contrary to what I mentioned yesterday, it wasn't actually that statements with no values in their I've made additional comments to explain this where the modification was added in the main I have also included the test case that you provided all except for the last line: self.assertIn(similar_question, self.chatbot.storage.find(response_to_trained_set).in_response_to) This had to be removed because the response should not have the input added to it. Thank you again for opening this ticket and for your time. This was a significant bug that I likely wouldn't have noticed otherwise. |
@gunthercox - no problem! I guess you are apologising too much ;) I'd like to contribute more. Last few weeks have been too busy for me and couldn't start the context feature we discussed. Hope I can start it this week! |
Closes #71