axa-group / nlp.js

An NLP library for building bots, with entity extraction, sentiment analysis, automatic language identify, and so more
MIT License
6.28k stars 621 forks source link

Entity isn't provided in the answer text #585

Closed mhallxyz closed 4 years ago

mhallxyz commented 4 years ago

The word "Clive" should make its way into the answer to replace the {{firstName}} text.

To reproduce just call the nlpListen() function.

const { containerBootstrap } = require('@nlpjs/core');
const { Nlp } = require('@nlpjs/nlp');
const { Ner } = require('@nlpjs/ner');
const { LangEn } = require('@nlpjs/lang-en-min');

const nlpListen = async () => {
  const container = await containerBootstrap();
  container.use(Nlp);
  container.use(Ner);
  container.use(LangEn);
  const nlp = container.get('nlp');
  nlp.settings.autoSave = false;
  nlp.addLanguage('en');
  nlp.addDocument('en', 'call @firstName', 'call.callFirstName');
  nlp.addNerRuleOptionTexts('en', 'firstName', 'Clive');
  nlp.addAnswer('en', 'call.callFirstName', 'Calling {{firstName}}');

  await nlp.train();
  const response = await nlp.process('en', 'call Clive');
  console.log(response);
  return response;
};

export default nlpListen;

Output "Calling {{firstName}}"

Expected Output "Calling Clive"

markgibaud commented 4 years ago

Hi @jesus-seijas-sp I also am struggling to understand how named entities are now put into answers in v4+.

It seems so are some others like https://github.com/axa-group/nlp.js/issues/440 and https://github.com/axa-group/nlp.js/issues/442

In v3 it looks like Handlebars was doing the work, but Handlebars is not present in v4+.

It looks like Evaluator might be the think we are looking for, with some context management? https://github.com/axa-group/nlp.js/tree/master/packages/evaluator

The example works with numerals and doesn't show us how to make the default evaluator part of the pipeline, ie. how tokens like {{ firstName }} in predefined answers are substituted with named entities from context when using nlpManager.process()

Or is it compile we need to use from @nlpjs/evaluator??

Any help appreciated.

jesus-seijas-sp commented 4 years ago

Hi, I updated @nlpjs/nlp to include entities in the context, and also by alias...

const { NlpManager } = require('node-nlp');

async function main() {
    const manager = new NlpManager({ languages: ['en'], nlu: { useNoneFeature: false, log:false }});
     manager.addDocument(
        'en',
        'I saw %hero% together with %hero%, they were eating %food%',
        'saw_heroes_eating'
    );
    manager.addAnswer('en', 'saw_heroes_eating', 'You saw {{ hero_0 }} with {{ entities.hero.items[1].sourceText }} eating {{ food }} {{ 5*2 }}')
    manager.addNamedEntityText('hero', 'spiderman', ['en'], ['Spider-man']);
    manager.addNamedEntityText('hero', 'iron man', ['en'], ['iron man']);
    manager.addNamedEntityText('hero', 'thor', ['en'], ['Thor']);
    manager.addNamedEntityText('food', 'burger', ['en'], ['Burger']);
    manager.addNamedEntityText('food', 'pizza', ['en'], ['pizza']);
    manager.addNamedEntityText('food', 'pasta', ['en'], ['Pasta', 'spaghetti']);

    await manager.train();

    const result = await manager.process('en','I saw spiderman together with ironman, they were eating spaghetti');
    console.log(result.answer);
}

main();

This returns "You saw Spider-man with iron man eating spaghetti". You can see it working here: https://runkit.com/jesus-seijas-sp/5f60a0d59e05de001b1cd637

Things to take into account:

jesus-seijas-sp commented 4 years ago

Closing as is solved