nlp.js icon indicating copy to clipboard operation
nlp.js copied to clipboard

Classification sometimes only produce "None" intent,

Open IrocNinoNiel opened this issue 3 years ago • 3 comments

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)

image

And this is the bug sometimes image

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);
}

IrocNinoNiel avatar Nov 07 '21 02:11 IrocNinoNiel

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

IrocNinoNiel avatar Nov 07 '21 02:11 IrocNinoNiel

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

TobiasNickel avatar Nov 23 '21 02:11 TobiasNickel

@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.

ScienceLion avatar Apr 16 '22 17:04 ScienceLion

Closing due to inactivity. Please, re-open if you think the topic is still alive.

aigloss avatar Nov 24 '22 13:11 aigloss