using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
public class SentimentAnalyzer
public static string ClassifyText(string text, Dictionary<string, Dictionary<string, int>> trainingData)
if (string.IsNullOrWhiteSpace(text) || trainingData == null || trainingData.Count == 0)
var sentiments = trainingData.Keys.ToList();
var vocabulary = new HashSet<string>();
var sentimentWordCounts = new Dictionary<string, int>();
foreach (var sentiment in sentiments)
if (!trainingData.ContainsKey(sentiment)) continue;
var sentimentData = trainingData[sentiment];
vocabulary.UnionWith(sentimentData.Keys);
sentimentWordCounts[sentiment] = sentimentData.Values.Sum();
totalWords += sentimentWordCounts[sentiment];
int vocabularySize = vocabulary.Count;
var probabilities = new Dictionary<string, double>();
foreach (var sentiment in sentiments)
var wordsInSentiment = trainingData[sentiment];
double totalWordsInSentiment = sentimentWordCounts[sentiment];
double logPrior = Math.Log(totalWordsInSentiment / (double)totalWords);
double logLikelihood = 0.0;
var textWords = text.Split(' ', StringSplitOptions.RemoveEmptyEntries);
foreach (var word in textWords)
if (!vocabulary.Contains(word)) continue;
double wordCount = wordsInSentiment.ContainsKey(word) ? wordsInSentiment[word] : 0;
double wordProbability = (wordCount + 1) / (totalWordsInSentiment + vocabularySize);
logLikelihood += Math.Log(wordProbability);
probabilities[sentiment] = logPrior + logLikelihood;
return probabilities.OrderByDescending(p => p.Value).First().Key;
public static void Main(string[] args)
var trainingData = new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
"negative", new Dictionary<string, int>
string text1 = "this is a good and great movie";
string sentiment1 = ClassifyText(text1, trainingData);
Console.WriteLine($"'{text1}' is classified as: {sentiment1}");
string text2 = "this is a bad and terrible movie";
string sentiment2 = ClassifyText(text2, trainingData);
Console.WriteLine($"'{text2}' is classified as: {sentiment2}");
string text3 = "this is a good and bad movie";
string sentiment3 = ClassifyText(text3, trainingData);
Console.WriteLine($"'{text3}' is classified as: {sentiment3}");
string text4 = "unknown words test";
string sentiment4 = ClassifyText(text4, trainingData);
Console.WriteLine($"'{text4}' is classified as: {sentiment4}");
var trainingDataOneSentiment = new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
string text5 = "this is a bad and terrible movie";
string sentiment5 = ClassifyText(text5, trainingDataOneSentiment);
Console.WriteLine($"'{text5}' is classified as: {sentiment5}");
public class SentimentAnalyzerTests
private Dictionary<string, Dictionary<string, int>> GetTrainingData()
return new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
"negative", new Dictionary<string, int>
public void ClassifyText_PositiveText_ReturnsPositive()
var trainingData = GetTrainingData();
string text = "this is a good and great movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_NegativeText_ReturnsNegative()
var trainingData = GetTrainingData();
string text = "this is a bad and terrible movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("negative", sentiment);
public void ClassifyText_MixedText_ReturnsPositive()
var trainingData = GetTrainingData();
string text = "this is a good and bad movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_UnknownWords_ReturnsPositive()
var trainingData = GetTrainingData();
string text = "unknown words test";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_EmptyText_ReturnsPositive()
var trainingData = GetTrainingData();
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_NullText_ReturnsPositive()
var trainingData = GetTrainingData();
string sentiment = SentimentAnalyzer.ClassifyText(null, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_EmptyTrainingData_ReturnsPositive()
var trainingData = new Dictionary<string, Dictionary<string, int>>();
string text = "this is a good movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_NullTrainingData_ReturnsPositive()
string text = "this is a good movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, null);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_OneSentimentMissing_ReturnsCorrectSentiment()
var trainingData = new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
string text = "bad terrible movie";
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
trainingData = new Dictionary<string, Dictionary<string, int>>
"negative", new Dictionary<string, int>
text = "good great movie";
sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("negative", sentiment);
trainingData = new Dictionary<string, Dictionary<string, int>>
"positive", new Dictionary<string, int>
"neutral", new Dictionary<string, int>
sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);
public void ClassifyText_WhitespaceText_ReturnsPositive()
var trainingData = GetTrainingData();
string sentiment = SentimentAnalyzer.ClassifyText(text, trainingData);
Assert.AreEqual("positive", sentiment);