nlp.js
nlp.js copied to clipboard
Classification sometimes only produce "None" intent,
Hello, I have a node js program that would automatically answer student queries. But there is a bug, sometimes the response will return classification with only a "None" intent and mostly it would return the desired result
The following are the results of the same query "when is the next release of allowance"
This is my desired result (Most of the time this is the result)
And this is the bug sometimes
can I ask how can I prevent the result from the second image from happening??
This is my full code
const { NlpManager } = require('node-nlp'); const FAQ = require("../../models/FAQ"); const Category = require("../../models/Category"); const translate = require('@vitalets/google-translate-api');
const manager = new NlpManager({ languages: ['en'], forceNER: true ,nlu: { useNoneFeature: false }}); const manager1 = new NlpManager({ languages: ['en'], forceNER: true ,nlu: { useNoneFeature: false }});
let faq = await FAQ.find();
var stopwords = ['is','the',"myself", "ourselves", "yours", "yourself", "yourselves","himself", "herself", "itself", "they", "them", "their", "theirs", "themselves"]
try{
const category = await Category.find();
category.forEach(e=>{
manager.addDocument('en', e.category_name.toLowerCase(), e.category_name.toLowerCase());
manager.addAnswer('en', e.category_name.toLowerCase(), e._id.toString());
// console.log(e._id);
})
const translation = await translate(text, {to: 'en'});
await manager.train();
manager.save();
const response = await manager.process('en', translation.text.toLowerCase());
const findOthersID = await Category.findOne({category_name:'others'})
data = {
answer: '',
success: false,
categoryId: findOthersID._id,
faqID: null
}
if(response.answer == undefined){
console.log('123456789')
console.log(response);
return data;
}else{
faq = faq.filter(e=>e.category_id == response.answer);
translation.text = translation.text.replace(response.intent.toLowerCase(),'');
faq.forEach(e=>{
e.faq_utterances = e.faq_utterances.map(u=>u.value.toLowerCase().replace(response.intent.toLowerCase(),'').trim())
stopwords.forEach(s=>{
e.faq_utterances = e.faq_utterances.map(u=>u.toLowerCase().replace(s,'').trim())
translation.text = translation.text.replace(s,'').trim();
})
e.faq_utterances.forEach(u=>{
manager1.addDocument('en', u, e._id.toString());
})
manager1.addAnswer('en', e._id.toString(), e.faq_answer);
console.log(e.faq_utterances);
})
await manager1.train();
let response1 = await manager1.process('en', translation.text.toLowerCase());
console.log(response1);
}
}catch(e){
console.log(e);
}
Based on my testing so far, it seems that sometimes the manager1 would not addDocument and addAnswer but when i check the looping for manager1.addDocument() it log all the utterances and intent that i would like to add to manager1
can you check how you remove the stopwords from the utterances? from an utterance such as "how do I do this?" the code would result in "how do I do th?" it would remove the is from the middle of a word. also it would remove "the" from them, they. theirs... so these words would never be removed.
for removing the words, maybe the a tokenizer from the natural js library are useful to you: https://naturalnode.github.io/natural/Tokenizers.html
@IrocNinoNiel I haven't figured out what causes this yet, but you're getting that outcome because instances of NlpManager do NOT produce correct outcomes when re-trained.
My current workaround is to use var manager1 = new NlpManager({ languages: ['en'], forceNER: true ,nlu: { useNoneFeature: false }});
and print utterances to a JSON file, and each time I want to train a new model, I would re-instance manager1 = new NlpManager({ languages: ['en'], forceNER: true ,nlu: { useNoneFeature: false }});
then read the JSON to perform all the addDocument
and then train
.
Closing due to inactivity. Please, re-open if you think the topic is still alive.