Question

How can we get sentiment score of complete sentence using Stanford core NLP?

It classifies complete sentence into positive and negative sentiment, but can we get total sentiment score out Stanford NLP tool?

Was it helpful?

Solution

What I did was to average out the score of each sentence based on sentence length. Logic behind it is that longer sentences should carry more weight than shorter ones.

The code looks like this:

String line = "Great item! HDMI and decent wifi required as with all streaming devices.\n" +
            "The flow on the homepage is very good and responsive. Watching a series is a doddle, flow is great, no action required.\n" +
            "The remote and controller app both work a treat.\n" +
            "I really like this device.\n" +
            "I'd like to see an Amazon-written mirroring app available for non-Amazon products but no-one likes talking to each other in this field!";

    Long textLength = 0L;
    int sumOfValues = 0;

    Properties props = new Properties();
    props.setProperty("annotators", "tokenize, ssplit, parse, sentiment");
    StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
    int mainSentiment = 0;
    if (line != null && line.length() > 0) {
        int longest = 0;
        Annotation annotation = pipeline.process(line);
        for (CoreMap sentence : annotation.get(CoreAnnotations.SentencesAnnotation.class)) {
            Tree tree = sentence.get(SentimentCoreAnnotations.AnnotatedTree.class);
            int sentiment = RNNCoreAnnotations.getPredictedClass(tree);
            String partText = sentence.toString();
            if (partText.length() > longest) {
                textLength += partText.length();
                sumOfValues = sumOfValues + sentiment * partText.length();

                System.out.println(sentiment + " " + partText);
            }
        }
    }

    System.out.println("Overall: " + (double)sumOfValues/textLength);

Download the entire project here

OTHER TIPS

Given sentences, once could average the predicted classes after annotation. The predicted classes can be accessed passing the annotated tree class to RNNCoreAnnotations.getPredictedClass:

public class SentimentAnalysis {
    private final String document;

    public SentimentAnalysis(String document) {
        this.document = document;
    }

    public SentimentAnalysis(Collection<String> sentences) {
        this.document = Joiner.on(". ").join(sentences);
    }

    public List<Integer> annotateAndScore(){
        List<Integer> scores = Lists.newArrayList();
        Properties props = new Properties();
        props.put("annotators", "tokenize, ssplit, pos, parse, sentiment");
        StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
        Annotation document = new Annotation(this.document);
        pipeline.annotate(document);
        for (CoreMap sentence : document.get(CoreAnnotations.SentencesAnnotation.class)) {
            Tree annotatedTree = sentence.get(SentimentCoreAnnotations.AnnotatedTree.class);
            int score = RNNCoreAnnotations.getPredictedClass(annotatedTree);
            scores.add(score);
        }
        return scores;
    }
}

I am taking Sentiment Analysis code from my blog: Code is straightforward go through that:

  1. Use SentimentCoreAnnotations.SentimentClass.class to get sentiment type.
  2. Use RNNCoreAnnotations.getPredictedClass to get sentiment score

Sentiment Analyzer

package com.interviewBubble.sentimentanalysis;

import java.util.Properties;

import org.ejml.simple.SimpleMatrix;

import edu.stanford.nlp.ling.CoreAnnotations;

import edu.stanford.nlp.neural.rnn.RNNCoreAnnotations;

import edu.stanford.nlp.pipeline.Annotation;

import edu.stanford.nlp.pipeline.StanfordCoreNLP;

import edu.stanford.nlp.sentiment.SentimentCoreAnnotations;

import edu.stanford.nlp.trees.Tree;

import edu.stanford.nlp.util.CoreMap;

public class SentimentAnalyzer {

 StanfordCoreNLP pipeline;

 public void initialize() {

  Properties properties = new Properties();

  properties.setProperty("annotators", "tokenize, ssplit, parse, sentiment");

  pipeline = new StanfordCoreNLP(properties);

 }

 public SentimentResult getSentimentResult(String text) {

  SentimentClassification classification = new SentimentClassification();

  SentimentResult sentimentResult = new SentimentResult();

  if (text != null && text.length() > 0) {

   Annotation annotation = pipeline.process(text);

   for(CoreMap sentence: annotation.get(CoreAnnotations.SentencesAnnotation.class)) {

       // System.out.println(sentence);

   Tree tree = sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class);

   //System.out.println(tree);

   SimpleMatrix simpleMatrix = RNNCoreAnnotations.getPredictions(tree);

   //System.out.println(simpleMatrix);

   classification.setVeryNegative((int)Math.round(simpleMatrix.get(0)*100d));

   classification.setNegative((int)Math.round(simpleMatrix.get(1)*100d));

   classification.setNeutral((int)Math.round(simpleMatrix.get(2)*100d));

   classification.setPositive((int)Math.round(simpleMatrix.get(3)*100d));

   classification.setVeryPositive((int)Math.round(simpleMatrix.get(4)*100d));

   String setimentType = sentence.get(SentimentCoreAnnotations.SentimentClass.class);

   sentimentResult.setSentimentType(setimentType);

   sentimentResult.setSentimentClass(classification);

   sentimentResult.setSentimentScore(RNNCoreAnnotations.getPredictedClass(tree));

   }

  }

  return sentimentResult;

 }

}

Sentiment Analysis:

package com.interviewBubble.sentimentanalysis;

public class SentimentAnalysis {

 public static void main(String[] args) {

     // I have taken iPhone X (Silver) User Review from Amazon

     String text = "Just love the X. Feel so Premium and a Head turner too. Face ID working fine but still miss "

       + "the fingerprint scanner very much. I jump from 5S to X so it’s a huge skip. I’m very very happy"

       + " with it. Specially battery backup is great after using with 4g cellular network and no heating "

       + "issue at all, though I’m not a mobile gamer, Oftentimes I play Boom Beach and I watch YouTube "

       + "videos and I surf a lot. It makes a deep hole in pocket at the Hefty price tag. So it’s all "

       + "upto your Consideration.\n";

     SentimentAnalyzer sentimentAnalyzer = new SentimentAnalyzer();

     sentimentAnalyzer.initialize();

     SentimentResult sentimentResult = sentimentAnalyzer.getSentimentResult(text);



     System.out.println("Sentiments Classification:");

  System.out.println("Very positive: " + sentimentResult.getSentimentClass().getVeryPositive()+"%");

  System.out.println("Positive: " + sentimentResult.getSentimentClass().getPositive()+"%");

  System.out.println("Neutral: " + sentimentResult.getSentimentClass().getNeutral()+"%");

  System.out.println("Negative: " + sentimentResult.getSentimentClass().getNegative()+"%");

  System.out.println("Very negative: " + sentimentResult.getSentimentClass().getVeryNegative()+"%");

     System.out.println("\nSentiments result:");

     System.out.println("Sentiment Score: " + sentimentResult.getSentimentScore());

  System.out.println("Sentiment Type: " + sentimentResult.getSentimentType());

 }

}

OUTPUT:

0    [main] INFO  edu.stanford.nlp.pipeline.StanfordCoreNLP  - Adding annotator tokenize

8    [main] INFO  edu.stanford.nlp.pipeline.TokenizerAnnotator  - No tokenizer type provided. Defaulting to PTBTokenizer.

12   [main] INFO  edu.stanford.nlp.pipeline.StanfordCoreNLP  - Adding annotator ssplit

17   [main] INFO  edu.stanford.nlp.pipeline.StanfordCoreNLP  - Adding annotator parse

512  [main] INFO  edu.stanford.nlp.parser.common.ParserGrammar  - Loading parser from serialized file edu/stanford/nlp/models/lexparser/englishPCFG.ser.gz ... done [0.5 sec].

517  [main] INFO  edu.stanford.nlp.pipeline.StanfordCoreNLP  - Adding annotator sentiment

Sentiments Classification:

Very positive: 4%

Positive: 23%

Neutral: 24%

Negative: 39%

Very negative: 8%

Sentiments result:

Sentiment Score: 1

Sentiment Type: Negative

Find whole project here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top