Shaokang's Blog

Even though the official repo of Nlp.js has a description about using in React Native. Running directly on Expo might have some problems. Due to some limitation on the web version of @nlpjs/core @nlpjs/lang-en-min @nlpjs/nlp, like no entity extraction and can not customize entity, using node-nlp-rn is a good choice. More details on implementing in below:

Installation:

1
npm install node-nlp-rn

process.hrtime() error

A common error I met was process.hrtime() is not a function. Because expo is not a total Node.js environment, this function wouldn’t exist. By checking the place that is using this function at Github, it is just used to measure the performance of the Nlp.js. So, a good and reasonable way to overcome this is to block this function by defining a global function using window, like:

1
window.process.hrtime = function () { return 0 }

This is the key in my case to make Nlp.js run

Remaining:

By solving the previous issue, everything is on set and just do not use any saving function. Other functions are the same as node-nlp

A sample could be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import React, { Component } from 'react';
window.process.hrtime = function () { return 0}

import {NlpManager} from 'node-nlp-rn';
class MainScreen extends Component {

async componentDidMount() {
const manager = new NlpManager({ languages: ['en'], forceNER: true });
// Adds the utterances and intents for the NLP
manager.addDocument('en', 'goodbye for now', 'greetings.bye');
manager.addDocument('en', 'bye bye take care', 'greetings.bye');
manager.addDocument('en', 'okay see you later', 'greetings.bye');
manager.addDocument('en', 'bye for now', 'greetings.bye');
manager.addDocument('en', 'i must go', 'greetings.bye');
manager.addDocument('en', 'hello', 'greetings.hello');
manager.addDocument('en', 'hi', 'greetings.hello');
manager.addDocument('en', 'howdy', 'greetings.hello');

// Train also the NLG
manager.addAnswer('en', 'greetings.bye', 'Till next time');
manager.addAnswer('en', 'greetings.bye', 'see you soon!');
manager.addAnswer('en', 'greetings.hello', 'Hey there!');
manager.addAnswer('en', 'greetings.hello', 'Greetings!');

// Train and save the model.

await manager.train();
const response = await manager.process('en', 'I should go now');
console.log(response);


}
render() {
return (
<View></View>
);
}
}

And some info will be shown in the console.

Advanced step

The benefit of using Nlp.js is that it is able to define our own entity, called enum entity. Unlike dialogflow, it always contains the exact matching option which will tell developer which one is detected. To use this, just add some definition like below:

1
2
3
4
5
6
7
const manager = new NlpManager({ languages: ['en'], forceNER: true });
manager.addNamedEntityText(
'categoryIncome',//name of entity
i,//entity option
[lang],//language config
[i, i.toLowerCase()],//possible match, this one will be automatically expanded to know other cases via different methods.
);

Entity information extraction

With forceNER: true, the entity recognition will be turned on automatically. Each object would have different returning syntax, but a general case is value would contain the information extracted. A sample code to extract key information as follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  generateRelationship(SourceObj) {
switch (SourceObj.entity) {
case "number":
return SourceObj.resolution.subtype + ";" + SourceObj.resolution.value
case "ip":
return SourceObj.resolution.value + ";" + SourceObj.resolution.type
case "percentage":
return SourceObj.resolution.strValue
case "dimension":
case "age":
case "currency":
return SourceObj.resolution.value + " " + SourceObj.resolution.localeUnit
case "date":
switch (SourceObj.resolution.type) {
case "date":
return SourceObj.resolution.strValue
default:
return SourceObj.resolution.timex
}
case "duration":
return SourceObj.resolution.values[0].timex + ":" + SourceObj.resolution.values[0].value + " Seconds"
case "datetime":
return SourceObj.resolution.values[0].value

default:
return SourceObj.resolution.value
}
}

 Comments