Text sentiment analysis on Node.js


Hello everyone. The topic is quite interesting and may seem rather difficult to implement. But I am a practical person and I want to touch the beautiful especially without straining. Today we will make a "microservice" for the analysis of sentimentality / tonality of the text. And the case, some more interesting things that will help you to prepare your textual appeal to Skynet.


Intro


? . , , ?


́ ́ ́ (-, . Sentiment analysis, . Opinion mining) — - , () , .

— ( , , /), . , , ( ). ( ) () .

by wikipedia


?


. — " ". " ..." . ", " — , .



, , . .



Node.js, Express. , Express low level .


npm install -g express-generator

express-generatorcreate-react-app Express .


node_nlp:


express node_nlp --no-view

npx:


npx express-generator node_nlp --no-view

, :


cd node_nlp
npm install
npm start

, , nodemon:


npm install --save nodemon

package.json:


"dev": "nodemon ./bin/www"

:


npm run dev

, . npm install.


npm install --save natural apos-to-lex-form spelling-corrector stopword



, ./routers, index.js :


const express = require('express');
const natural = require('natural');

const router = express.Router();

router.post('/', function(req, res, next) {
  const { text } = req.body;
});

module.exports = router;

POST body text.



, - , , , , . , " ...".




"" , I’m, you’re I am, you are.
apos-to-lex-form


const express = require('express');
const natural = require('natural');
const aposToLexForm = require('apos-to-lex-form')

const router = express.Router();

router.post('/', function(req, res, next) {
  const { text } = req.body;
  const lexedText = aposToLexForm(text);
});

module.exports = router;

lowercase ( )


, , , .


const casedReview = lexedText.toLowerCase();


, , @#$%^# . .
JavaScript — replace():


const alphaOnlyReview = casedReview.replace(/[^a-zA-Z\s]+/g, '')


. , .


Natural.
WordTokenizer:


...

const { WordTokenizer } = natural;
const tokenizer = new WordTokenizer();
const tokenizedReview = tokenizer.tokenize(alphaOnlyReview);

...


, . . spelling-corrector.


const express = require('express');
const natural = require('natural');
const aposToLexForm = require('apos-to-lex-form');
const SpellCorrector = require('spelling-corrector');

const router = express.Router();

const spellCorrector = new SpellCorrector();
spellCorrector.loadDictionary();

router.post('/', function(req, res, next) {
  const { text } = req.body;
  const lexedText = aposToLexForm(text);
  const casedReview = lexedText.toLowerCase();
  const alphaOnlyReview = casedReview.replace(/[^a-zA-Z\s]+/g, '')

  const { WordTokenizer } = natural;
  const tokenizer = new WordTokenizer();
  const tokenizedReview = tokenizer.tokenize(alphaOnlyReview);

  tokenizedReview.forEach((word, index) => {
    tokenizedReview[index] = spellCorrector.correct(word);
  });
});

module.exports = router;



, . , , , , , , . stopword.


const SW = require('stopword');

...

const filteredReview = SW.removeStopwords(tokenizedReview);

(Stemming)


, . “giving,” “gave,” and “giver” “give”.
, SentimentAnalyzer Natural, .


Natural


! . . SentimentAnalyzer , .


. Natural "" . "good" 3, "bad" -3. "" . , .
, 0.


SentimentAnalyzer 3 :


  • (AFINN, Senticon, Pattern),

:


const express = require('express');
const natural = require('natural');
const aposToLexForm = require('apos-to-lex-form');
const SpellCorrector = require('spelling-corrector');
const SW = require('stopword');

const router = express.Router();

const spellCorrector = new SpellCorrector();
spellCorrector.loadDictionary();

router.post('/', function(req, res, next) {
  const { text } = req.body;
  const lexedText = aposToLexForm(text);
  const casedReview = lexedText.toLowerCase();
  const alphaOnlyReview = casedReview.replace(/[^a-zA-Z\s]+/g, '')

  const { WordTokenizer } = natural;
  const tokenizer = new WordTokenizer();
  const tokenizedReview = tokenizer.tokenize(alphaOnlyReview);

  tokenizedReview.forEach((word, index) => {
    tokenizedReview[index] = spellCorrector.correct(word);
  });

  const filteredReview = SW.removeStopwords(tokenizedReview);

  const { SentimentAnalyzer, PorterStemmer } = natural;
  const analyzer = new SentimentAnalyzer('English', PorterStemmer, 'afinn');
  const analysis = analyzer.getSentiment(filteredReview);

  res.status(200).json({ analysis });
});

module.exports = router;

. natural, analysis.
SentimentAnalyzer, . . C , Natrual.


UI , DevTools:


fetch('/', 
 {
   method: 'POST',
   headers: {
     'Content-Type': 'application/json'
   }, 
  body: JSON.stringify({text: 'hey'})
})

// {"analysis":0}

fetch('/', 
 {
   method: 'POST',
   headers: {
     'Content-Type': 'application/json'
   }, 
  body: JSON.stringify({text: 'hey f*** you'})
})

// {"analysis":-2}

fetch('/', 
 {
   method: 'POST',
   headers: {
     'Content-Type': 'application/json'
   }, 
  body: JSON.stringify({text: 'hey love you'})
})

// {"analysis":1}

:)


Github repo



"" . , . . !



Source: https://habr.com/ru/post/undefined/


All Articles