Skip to content

Instantly share code, notes, and snippets.

@mssfang
Last active August 12, 2020 06:15
Show Gist options
  • Save mssfang/5e04ce1a695223ddf91f297d33f0bbe2 to your computer and use it in GitHub Desktop.
Save mssfang/5e04ce1a695223ddf91f297d33f0bbe2 to your computer and use it in GitHub Desktop.
Samples for Opinion Mining

(1) Exmaple for atomic single string input,

(1.1) Sync Version

String document = "Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.";

System.out.printf("Text = %s%n", document);

AnalyzeSentimentOptions options = new AnalyzeSentimentOptions().setIncludeOpinionMining(true);
final DocumentSentiment documentSentiment = client.analyzeSentiment(document, "en", options);
SentimentConfidenceScores scores = documentSentiment.getConfidenceScores();
System.out.printf(
    "Recognized document sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
    documentSentiment.getSentiment(), scores.getPositive(), scores.getNeutral(), scores.getNegative());

List<MinedOpinion> positiveMinedOpinions = new ArrayList<>();
List<MinedOpinion> mixedMinedOpinions = new ArrayList<>();
List<MinedOpinion> negativeMinedOpinions = new ArrayList<>();
documentSentiment.getSentences().forEach(sentenceSentiment -> {
    SentimentConfidenceScores sentenceScores = sentenceSentiment.getConfidenceScores();
    System.out.printf("\tSentence sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
	sentenceSentiment.getSentiment(), sentenceScores.getPositive(), sentenceScores.getNeutral(), sentenceScores.getNegative());
    sentenceSentiment.getMinedOpinions().forEach(minedOpinion -> {
	TextSentiment aspectTextSentiment = minedOpinion.getAspect().getSentiment();
	if (NEGATIVE.equals(aspectTextSentiment)) {
	    negativeMinedOpinions.add(minedOpinion);
	} else if (POSITIVE.equals(aspectTextSentiment)) {
	    positiveMinedOpinions.add(minedOpinion);
	} else if (MIXED.equals(aspectTextSentiment)) {
	    mixedMinedOpinions.add(minedOpinion);
	}
    });
});

System.out.printf("Positive aspects count: %d%n", positiveMinedOpinions.size());
for (MinedOpinion positiveMinedOpinion : positiveMinedOpinions) {
    System.out.printf("\tAspect: %s%n", positiveMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : positiveMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

System.out.printf("Mixed aspects count: %d%n", mixedMinedOpinions.size());
for (MinedOpinion mixedMinedOpinion : mixedMinedOpinions) {
    System.out.printf("\tAspect: %s%n", mixedMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : mixedMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

System.out.printf("Negative aspects count: %d%n", negativeMinedOpinions.size());
for (MinedOpinion negativeMinedOpinion : negativeMinedOpinions) {
    System.out.printf("\tAspect: %s%n", negativeMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : negativeMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

(1.1) Output

Text = Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.
Recognized document sentiment: negative, positive score: 0.010000, neutral score: 0.140000, negative score: 0.850000.
	Sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
	Sentence sentiment: negative, positive score: 0.020000, neutral score: 0.440000, negative score: 0.540000.
	Sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
Positive aspects count: 0
Mixed aspects count: 0
Negative aspects count: 2
	Aspect: atmosphere
		'negative' sentiment because of "bad". Does the aspect negated: false.
	Aspect: Staff
		'negative' sentiment because of "friendly". Does the aspect negated: true.
		'negative' sentiment because of "helpful". Does the aspect negated: true.

(1.2) Async Version

String document = "Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.";

AnalyzeSentimentOptions options = new AnalyzeSentimentOptions().setIncludeOpinionMining(true);
client.analyzeSentiment(document, "en", options).subscribe(
    documentSentiment -> {
	SentimentConfidenceScores scores = documentSentiment.getConfidenceScores();
	System.out.printf(
	    "Recognized document sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
	    documentSentiment.getSentiment(), scores.getPositive(), scores.getNeutral(), scores.getNegative());

	List<MinedOpinion> positiveMinedOpinions = new ArrayList<>();
	List<MinedOpinion> mixedMinedOpinions = new ArrayList<>();
	List<MinedOpinion> negativeMinedOpinions = new ArrayList<>();
	documentSentiment.getSentences().forEach(sentenceSentiment -> {
	    SentimentConfidenceScores sentenceScores = sentenceSentiment.getConfidenceScores();
	    System.out.printf("\tsentence sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
		sentenceSentiment.getSentiment(), sentenceScores.getPositive(), sentenceScores.getNeutral(), sentenceScores.getNegative());

	    sentenceSentiment.getMinedOpinions().forEach(minedOpinion -> {
		TextSentiment aspectTextSentiment = minedOpinion.getAspect().getSentiment();
		if (NEGATIVE.equals(aspectTextSentiment)) {
		    negativeMinedOpinions.add(minedOpinion);
		} else if (POSITIVE.equals(aspectTextSentiment)) {
		    positiveMinedOpinions.add(minedOpinion);
		} else if (MIXED.equals(aspectTextSentiment)) {
		    mixedMinedOpinions.add(minedOpinion);
		}
	    });
	});

	System.out.printf("Positive aspects count: %d%n", positiveMinedOpinions.size());
	for (MinedOpinion positiveMinedOpinion : positiveMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", positiveMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : positiveMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}

	System.out.printf("Mixed aspects count: %d%n", mixedMinedOpinions.size());
	for (MinedOpinion mixedMinedOpinion : mixedMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", mixedMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : mixedMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}

	System.out.printf("Negative aspects count: %d%n", negativeMinedOpinions.size());
	for (MinedOpinion negativeMinedOpinion : negativeMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", negativeMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : negativeMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}
    },
    error -> System.err.println("There was an error analyzing sentiment of the text." + error),
    () -> System.out.println("Sentiment analyzed."));

(1.2) Output

Recognized document sentiment: negative, positive score: 0.010000, neutral score: 0.140000, negative score: 0.850000.
	sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
	sentence sentiment: negative, positive score: 0.020000, neutral score: 0.440000, negative score: 0.540000.
	sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
Positive aspects count: 0
Mixed aspects count: 0
Negative aspects count: 2
	Aspect: atmosphere
		'negative' sentiment because of "bad". Does the aspect negated: false.
	Aspect: Staff
		'negative' sentiment because of "friendly". Does the aspect negated: true.
		'negative' sentiment because of "helpful". Does the aspect negated: true.
Sentiment analyzed.

(2) Batch string inputs, (2.1) Sync Version

List<String> documents = Arrays.asList(
    "Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful.",
    "Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful."
);

AnalyzeSentimentOptions options = new AnalyzeSentimentOptions()
    .setIncludeOpinionMining(true)
    .setRequestOptions(new TextAnalyticsRequestOptions().setIncludeStatistics(true).setModelVersion("latest"));

// Analyzing sentiment for each document in a batch of documents
AnalyzeSentimentResultCollection sentimentBatchResultCollection = client.analyzeSentimentBatch(documents, "en", options);

// Model version
System.out.printf("Results of Azure Text Analytics \"Sentiment Analysis\" Model, version: %s%n", sentimentBatchResultCollection.getModelVersion());

// Analyzed sentiment for each document in a batch of documents

List<MinedOpinion> positiveMinedOpinions = new ArrayList<>();
List<MinedOpinion> mixedMinedOpinions = new ArrayList<>();
List<MinedOpinion> negativeMinedOpinions = new ArrayList<>();
AtomicInteger counter = new AtomicInteger();
for (AnalyzeSentimentResult analyzeSentimentResult : sentimentBatchResultCollection) {
    System.out.printf("%nText = %s%n", documents.get(counter.getAndIncrement()));
    DocumentSentiment documentSentiment = analyzeSentimentResult.getDocumentSentiment();

    SentimentConfidenceScores scores = documentSentiment.getConfidenceScores();
    System.out.printf("Analyzed document sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
	documentSentiment.getSentiment(), scores.getPositive(), scores.getNeutral(), scores.getNegative());
    documentSentiment.getSentences().forEach(sentenceSentiment -> {
	SentimentConfidenceScores sentenceScores = sentenceSentiment.getConfidenceScores();
	System.out.printf(
	    "\tAnalyzed sentence sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
	    sentenceSentiment.getSentiment(), sentenceScores.getPositive(), sentenceScores.getNeutral(), sentenceScores.getNegative());

	sentenceSentiment.getMinedOpinions().forEach(minedOpinion -> {
	    TextSentiment aspectTextSentiment = minedOpinion.getAspect().getSentiment();
	    if (NEGATIVE.equals(aspectTextSentiment)) {
		negativeMinedOpinions.add(minedOpinion);
	    } else if (POSITIVE.equals(aspectTextSentiment)) {
		positiveMinedOpinions.add(minedOpinion);
	    } else if (MIXED.equals(aspectTextSentiment)) {
		mixedMinedOpinions.add(minedOpinion);
	    }
	});
    });
}

System.out.printf("Positive aspects count: %d%n", positiveMinedOpinions.size());
for (MinedOpinion positiveMinedOpinion : positiveMinedOpinions) {
    System.out.printf("\tAspect: %s%n", positiveMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : positiveMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

System.out.printf("Mixed aspects count: %d%n", mixedMinedOpinions.size());
for (MinedOpinion mixedMinedOpinion : mixedMinedOpinions) {
    System.out.printf("\tAspect: %s%n", mixedMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : mixedMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

System.out.printf("Negative aspects count: %d%n", negativeMinedOpinions.size());
for (MinedOpinion negativeMinedOpinion : negativeMinedOpinions) {
    System.out.printf("\tAspect: %s%n", negativeMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : negativeMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

(2.1) Output

Results of Azure Text Analytics "Sentiment Analysis" Model, version: 2020-04-01

Text = Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful.
Analyzed document sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: neutral, positive score: 0.130000, neutral score: 0.860000, negative score: 0.010000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.

Text = Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.
Analyzed document sentiment: negative, positive score: 0.010000, neutral score: 0.140000, negative score: 0.850000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
	Analyzed sentence sentiment: negative, positive score: 0.020000, neutral score: 0.440000, negative score: 0.540000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
Positive aspects count: 4
	Aspect: atmosphere
		'positive' sentiment because of "great". Does the aspect negated: false.
	Aspect: restaurants
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: hotels
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: Staff
		'positive' sentiment because of "friendly". Does the aspect negated: false.
		'positive' sentiment because of "helpful". Does the aspect negated: false.
Mixed aspects count: 0
Negative aspects count: 2
	Aspect: atmosphere
		'negative' sentiment because of "bad". Does the aspect negated: false.
	Aspect: Staff
		'negative' sentiment because of "friendly". Does the aspect negated: true.
		'negative' sentiment because of "helpful". Does the aspect negated: true.

(2.2) Async Version

List<String> documents = Arrays.asList(
    "Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful.",
    "Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful."
);

AnalyzeSentimentOptions options = new AnalyzeSentimentOptions()
    .setIncludeOpinionMining(true)
    .setRequestOptions(new TextAnalyticsRequestOptions().setIncludeStatistics(true).setModelVersion("latest"));

// Analyzing sentiment for each document in a batch of documents
client.analyzeSentimentBatch(documents, "en", options).subscribe(
    sentimentBatchResultCollection -> {
	System.out.printf("Results of Azure Text Analytics \"Sentiment Analysis\" Model, version: %s%n", sentimentBatchResultCollection.getModelVersion());

	// Batch statistics
	TextDocumentBatchStatistics batchStatistics = sentimentBatchResultCollection.getStatistics();
	System.out.printf("Documents statistics: document count = %s, erroneous document count = %s, transaction count = %s, valid document count = %s.%n",
	    batchStatistics.getDocumentCount(), batchStatistics.getInvalidDocumentCount(), batchStatistics.getTransactionCount(), batchStatistics.getValidDocumentCount());

	// Analyzed sentiment for each document in a batch of documents
	AtomicInteger counter = new AtomicInteger();

	List<MinedOpinion> positiveMinedOpinions = new ArrayList<>();
	List<MinedOpinion> mixedMinedOpinions = new ArrayList<>();
	List<MinedOpinion> negativeMinedOpinions = new ArrayList<>();
	for (AnalyzeSentimentResult analyzeSentimentResult : sentimentBatchResultCollection) {
	    // Analyzed sentiment for each document
	    System.out.printf("%nText = %s%n", documents.get(counter.getAndIncrement()));
	    if (analyzeSentimentResult.isError()) {
		// Erroneous document
		System.out.printf("Cannot analyze sentiment. Error: %s%n", analyzeSentimentResult.getError().getMessage());
	    } else {
		// Valid document
		DocumentSentiment documentSentiment = analyzeSentimentResult.getDocumentSentiment();
		SentimentConfidenceScores scores = documentSentiment.getConfidenceScores();
		System.out.printf("Analyzed document sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
		    documentSentiment.getSentiment(), scores.getPositive(), scores.getNeutral(), scores.getNegative());
		documentSentiment.getSentences().forEach(sentenceSentiment -> {
		    SentimentConfidenceScores sentenceScores = sentenceSentiment.getConfidenceScores();
		    System.out.printf(
			"\tAnalyzed sentence sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
			sentenceSentiment.getSentiment(), sentenceScores.getPositive(), sentenceScores.getNeutral(), sentenceScores.getNegative());
		    sentenceSentiment.getMinedOpinions().forEach(minedOpinion -> {
			TextSentiment aspectTextSentiment = minedOpinion.getAspect().getSentiment();
			if (NEGATIVE.equals(aspectTextSentiment)) {
			    negativeMinedOpinions.add(minedOpinion);
			} else if (POSITIVE.equals(aspectTextSentiment)) {
			    positiveMinedOpinions.add(minedOpinion);
			} else if (MIXED.equals(aspectTextSentiment)) {
			    mixedMinedOpinions.add(minedOpinion);
			}
		    });
		});
	    }
	}

	System.out.printf("Positive aspects count: %d%n", positiveMinedOpinions.size());
	for (MinedOpinion positiveMinedOpinion : positiveMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", positiveMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : positiveMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}

	System.out.printf("Mixed aspects count: %d%n", mixedMinedOpinions.size());
	for (MinedOpinion mixedMinedOpinion : mixedMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", mixedMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : mixedMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}

	System.out.printf("Negative aspects count: %d%n", negativeMinedOpinions.size());
	for (MinedOpinion negativeMinedOpinion : negativeMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", negativeMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : negativeMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}
    },
    error -> System.err.println("There was an error analyzing sentiment of the documents." + error),
    () -> System.out.println("Batch of sentiment analyzed."));

(2.2) Output

Results of Azure Text Analytics "Sentiment Analysis" Model, version: 2020-04-01
Documents statistics: document count = 2, erroneous document count = 0, transaction count = 2, valid document count = 2.

Text = Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful.
Analyzed document sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: neutral, positive score: 0.130000, neutral score: 0.860000, negative score: 0.010000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.

Text = Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.
Analyzed document sentiment: negative, positive score: 0.010000, neutral score: 0.140000, negative score: 0.850000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
	Analyzed sentence sentiment: negative, positive score: 0.020000, neutral score: 0.440000, negative score: 0.540000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
Positive aspects count: 4
	Aspect: atmosphere
		'positive' sentiment because of "great". Does the aspect negated: false.
	Aspect: restaurants
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: hotels
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: Staff
		'positive' sentiment because of "friendly". Does the aspect negated: false.
		'positive' sentiment because of "helpful". Does the aspect negated: false.
Mixed aspects count: 0
Negative aspects count: 2
	Aspect: atmosphere
		'negative' sentiment because of "bad". Does the aspect negated: false.
	Aspect: Staff
		'negative' sentiment because of "friendly". Does the aspect negated: true.
		'negative' sentiment because of "helpful". Does the aspect negated: true.
Batch of sentiment analyzed.

(3) Batch TextDocumentInput (3.1) Sync Version

List<TextDocumentInput> documents = Arrays.asList(
    new TextDocumentInput("A", "Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful.").setLanguage("en"),
    new TextDocumentInput("B", "Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.").setLanguage("en")
);

AnalyzeSentimentOptions options = new AnalyzeSentimentOptions()
    .setIncludeOpinionMining(true)
    .setRequestOptions(new TextAnalyticsRequestOptions().setIncludeStatistics(true).setModelVersion("latest"));

// Analyzing sentiment for each document in a batch of documents
Response<AnalyzeSentimentResultCollection> sentimentBatchResultResponse =
    client.analyzeSentimentBatchWithResponse(documents, options, Context.NONE);

// Response's status code
System.out.printf("Status code of request response: %d%n", sentimentBatchResultResponse.getStatusCode());
AnalyzeSentimentResultCollection sentimentBatchResultCollection = sentimentBatchResultResponse.getValue();

// Model version
System.out.printf("Results of Azure Text Analytics \"Sentiment Analysis\" Model, version: %s%n", sentimentBatchResultCollection.getModelVersion());

// Batch statistics
TextDocumentBatchStatistics batchStatistics = sentimentBatchResultCollection.getStatistics();
System.out.printf("Documents statistics: document count = %s, erroneous document count = %s, transaction count = %s, valid document count = %s.%n",
    batchStatistics.getDocumentCount(), batchStatistics.getInvalidDocumentCount(), batchStatistics.getTransactionCount(), batchStatistics.getValidDocumentCount());

// Analyzed sentiment for each document in a batch of documents
AtomicInteger counter = new AtomicInteger();

List<MinedOpinion> positiveMinedOpinions = new ArrayList<>();
List<MinedOpinion> mixedMinedOpinions = new ArrayList<>();
List<MinedOpinion> negativeMinedOpinions = new ArrayList<>();
sentimentBatchResultCollection.forEach(analyzeSentimentResult -> {
    System.out.printf("%n%s%n", documents.get(counter.getAndIncrement()));
    if (analyzeSentimentResult.isError()) {
	// Erroneous document
	System.out.printf("Cannot analyze sentiment. Error: %s%n", analyzeSentimentResult.getError().getMessage());
    } else {
	// Valid document
	DocumentSentiment documentSentiment = analyzeSentimentResult.getDocumentSentiment();
	SentimentConfidenceScores scores = documentSentiment.getConfidenceScores();
	System.out.printf("Analyzed document sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
	    documentSentiment.getSentiment(), scores.getPositive(), scores.getNeutral(), scores.getNegative());
	documentSentiment.getSentences().forEach(sentenceSentiment -> {
	    SentimentConfidenceScores sentenceScores = sentenceSentiment.getConfidenceScores();
	    System.out.printf(
		"\tAnalyzed sentence sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
		sentenceSentiment.getSentiment(), sentenceScores.getPositive(), sentenceScores.getNeutral(), sentenceScores.getNegative());
	    sentenceSentiment.getMinedOpinions().forEach(minedOpinion -> {
		TextSentiment aspectTextSentiment = minedOpinion.getAspect().getSentiment();
		if (NEGATIVE.equals(aspectTextSentiment)) {
		    negativeMinedOpinions.add(minedOpinion);
		} else if (POSITIVE.equals(aspectTextSentiment)) {
		    positiveMinedOpinions.add(minedOpinion);
		} else if (MIXED.equals(aspectTextSentiment)) {
		    mixedMinedOpinions.add(minedOpinion);
		}
	    });
	});
    }
});

System.out.printf("Positive aspects count: %d%n", positiveMinedOpinions.size());
for (MinedOpinion positiveMinedOpinion : positiveMinedOpinions) {
    System.out.printf("\tAspect: %s%n", positiveMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : positiveMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

System.out.printf("Mixed aspects count: %d%n", mixedMinedOpinions.size());
for (MinedOpinion mixedMinedOpinion : mixedMinedOpinions) {
    System.out.printf("\tAspect: %s%n", mixedMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : mixedMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

System.out.printf("Negative aspects count: %d%n", negativeMinedOpinions.size());
for (MinedOpinion negativeMinedOpinion : negativeMinedOpinions) {
    System.out.printf("\tAspect: %s%n", negativeMinedOpinion.getAspect().getText());
    for (OpinionSentiment opinionSentiment : negativeMinedOpinion.getOpinions()) {
	System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
	    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
    }
}

(3.1) Output

Status code of request response: 200
Results of Azure Text Analytics "Sentiment Analysis" Model, version: 2020-04-01
Documents statistics: document count = 2, erroneous document count = 0, transaction count = 2, valid document count = 2.

Text = Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful., Id = A, Language = en
Analyzed document sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: neutral, positive score: 0.130000, neutral score: 0.860000, negative score: 0.010000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.

Text = Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful., Id = B, Language = en
Analyzed document sentiment: negative, positive score: 0.010000, neutral score: 0.140000, negative score: 0.850000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
	Analyzed sentence sentiment: negative, positive score: 0.020000, neutral score: 0.440000, negative score: 0.540000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
Positive aspects count: 4
	Aspect: atmosphere
		'positive' sentiment because of "great". Does the aspect negated: false.
	Aspect: restaurants
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: hotels
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: Staff
		'positive' sentiment because of "friendly". Does the aspect negated: false.
		'positive' sentiment because of "helpful". Does the aspect negated: false.
Mixed aspects count: 0
Negative aspects count: 2
	Aspect: atmosphere
		'negative' sentiment because of "bad". Does the aspect negated: false.
	Aspect: Staff
		'negative' sentiment because of "friendly". Does the aspect negated: true.
		'negative' sentiment because of "helpful". Does the aspect negated: true.

(3.2) Async Version

List<TextDocumentInput> documents = Arrays.asList(
    new TextDocumentInput("A", "Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful.").setLanguage("en"),
    new TextDocumentInput("B", "Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful.").setLanguage("en")
);

AnalyzeSentimentOptions options = new AnalyzeSentimentOptions()
    .setIncludeOpinionMining(true)
    .setRequestOptions(new TextAnalyticsRequestOptions().setIncludeStatistics(true).setModelVersion("latest"));

// Analyzing sentiment for each document in a batch of documents
client.analyzeSentimentBatchWithResponse(documents, options).subscribe(
    sentimentBatchResultResponse -> {
	// Response's status code
	System.out.printf("Status code of request response: %d%n", sentimentBatchResultResponse.getStatusCode());
	AnalyzeSentimentResultCollection sentimentBatchResultCollection = sentimentBatchResultResponse.getValue();

	System.out.printf("Results of Azure Text Analytics \"Sentiment Analysis\" Model, version: %s%n", sentimentBatchResultCollection.getModelVersion());

	// Batch statistics
	TextDocumentBatchStatistics batchStatistics = sentimentBatchResultCollection.getStatistics();
	System.out.printf("Documents statistics: document count = %s, erroneous document count = %s, transaction count = %s, valid document count = %s.%n",
	    batchStatistics.getDocumentCount(), batchStatistics.getInvalidDocumentCount(), batchStatistics.getTransactionCount(), batchStatistics.getValidDocumentCount());

	// Analyzed sentiment for each document in a batch of documents
	AtomicInteger counter = new AtomicInteger();
	List<MinedOpinion> positiveMinedOpinions = new ArrayList<>();
	List<MinedOpinion> mixedMinedOpinions = new ArrayList<>();
	List<MinedOpinion> negativeMinedOpinions = new ArrayList<>();
	for (AnalyzeSentimentResult analyzeSentimentResult : sentimentBatchResultCollection) {
	    System.out.printf("%n%s%n", documents.get(counter.getAndIncrement()));
	    if (analyzeSentimentResult.isError()) {
		// Erroneous document
		System.out.printf("Cannot analyze sentiment. Error: %s%n", analyzeSentimentResult.getError().getMessage());
	    } else {
		// Valid document
		DocumentSentiment documentSentiment = analyzeSentimentResult.getDocumentSentiment();
		SentimentConfidenceScores scores = documentSentiment.getConfidenceScores();
		System.out.printf("Analyzed document sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
		    documentSentiment.getSentiment(), scores.getPositive(), scores.getNeutral(), scores.getNegative());
		documentSentiment.getSentences().forEach(sentenceSentiment -> {
		    SentimentConfidenceScores sentenceScores = sentenceSentiment.getConfidenceScores();
		    System.out.printf(
			"\tAnalyzed sentence sentiment: %s, positive score: %f, neutral score: %f, negative score: %f.%n",
			sentenceSentiment.getSentiment(), sentenceScores.getPositive(), sentenceScores.getNeutral(), sentenceScores.getNegative());
		    sentenceSentiment.getMinedOpinions().forEach(minedOpinion -> {
			TextSentiment aspectTextSentiment = minedOpinion.getAspect().getSentiment();
			if (NEGATIVE.equals(aspectTextSentiment)) {
			    negativeMinedOpinions.add(minedOpinion);
			} else if (POSITIVE.equals(aspectTextSentiment)) {
			    positiveMinedOpinions.add(minedOpinion);
			} else if (MIXED.equals(aspectTextSentiment)) {
			    mixedMinedOpinions.add(minedOpinion);
			}
		    });
		});
	    }
	}

	System.out.printf("Positive aspects count: %d%n", positiveMinedOpinions.size());
	for (MinedOpinion positiveMinedOpinion : positiveMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", positiveMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : positiveMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}

	System.out.printf("Mixed aspects count: %d%n", mixedMinedOpinions.size());
	for (MinedOpinion mixedMinedOpinion : mixedMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", mixedMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : mixedMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}

	System.out.printf("Negative aspects count: %d%n", negativeMinedOpinions.size());
	for (MinedOpinion negativeMinedOpinion : negativeMinedOpinions) {
	    System.out.printf("\tAspect: %s%n", negativeMinedOpinion.getAspect().getText());
	    for (OpinionSentiment opinionSentiment : negativeMinedOpinion.getOpinions()) {
		System.out.printf("\t\t'%s' sentiment because of \"%s\". Does the aspect negated: %s.%n",
		    opinionSentiment.getSentiment(), opinionSentiment.getText(), opinionSentiment.isNegated());
	    }
	}
    },
    error -> System.err.println("There was an error analyzing sentiment of the documents." + error),
    () -> System.out.println("Batch of sentiment analyzed."));

3.2 Output

Status code of request response: 200
Results of Azure Text Analytics "Sentiment Analysis" Model, version: 2020-04-01
Documents statistics: document count = 2, erroneous document count = 0, transaction count = 2, valid document count = 2.

Text = Great atmosphere. Close to plenty of restaurants, hotels, and transit! Staff are friendly and helpful., Id = A, Language = en
Analyzed document sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.
	Analyzed sentence sentiment: neutral, positive score: 0.130000, neutral score: 0.860000, negative score: 0.010000.
	Analyzed sentence sentiment: positive, positive score: 1.000000, neutral score: 0.000000, negative score: 0.000000.

Text = Bad atmosphere. Not close to plenty of restaurants, hotels, and transit! Staff are not friendly and helpful., Id = B, Language = en
Analyzed document sentiment: negative, positive score: 0.010000, neutral score: 0.140000, negative score: 0.850000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
	Analyzed sentence sentiment: negative, positive score: 0.020000, neutral score: 0.440000, negative score: 0.540000.
	Analyzed sentence sentiment: negative, positive score: 0.000000, neutral score: 0.000000, negative score: 1.000000.
Positive aspects count: 4
	Aspect: atmosphere
		'positive' sentiment because of "great". Does the aspect negated: false.
	Aspect: restaurants
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: hotels
		'positive' sentiment because of "close to plenty". Does the aspect negated: false.
	Aspect: Staff
		'positive' sentiment because of "friendly". Does the aspect negated: false.
		'positive' sentiment because of "helpful". Does the aspect negated: false.
Mixed aspects count: 0
Negative aspects count: 2
	Aspect: atmosphere
		'negative' sentiment because of "bad". Does the aspect negated: false.
	Aspect: Staff
		'negative' sentiment because of "friendly". Does the aspect negated: true.
		'negative' sentiment because of "helpful". Does the aspect negated: true.
Batch of sentiment analyzed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment