202 lines
7.3 KiB
C#
202 lines
7.3 KiB
C#
using BotSharp.Algorithm.Bayesian;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
namespace BotSharp.Algorithm.UnitTest
|
|
{
|
|
[TestClass]
|
|
public class BayesianTest
|
|
{
|
|
/// <summary>
|
|
/// The training set
|
|
/// </summary>
|
|
private ITrainingSet _trainingSet;
|
|
|
|
/// <summary>
|
|
/// The classifier
|
|
/// </summary>
|
|
private IClassifier _classifier;
|
|
|
|
/// <summary>
|
|
/// The spam class
|
|
/// </summary>
|
|
private static IClass _spamClass;
|
|
|
|
/// <summary>
|
|
/// The ham class
|
|
/// </summary>
|
|
private static IClass _hamClass;
|
|
|
|
/// <summary>
|
|
/// Sets up.
|
|
/// </summary>
|
|
public void SetUp()
|
|
{
|
|
_trainingSet = BuildTrainingSet();
|
|
_classifier = BuildClassifier(_trainingSet);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the classifier.
|
|
/// </summary>
|
|
/// <returns>Classifier<StringClass, StringToken>.</returns>
|
|
private IClassifier BuildClassifier(ITrainingSetAccessor trainingSet)
|
|
{
|
|
var classifier = new NaiveClassifier(trainingSet)
|
|
{
|
|
// disable smoothing for exact probabilities
|
|
SmoothingAlpha = 0.0D
|
|
};
|
|
|
|
return classifier;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the training set.
|
|
/// </summary>
|
|
/// <returns>ITrainingSet<StringClass, StringToken>.</returns>
|
|
private static ITrainingSet BuildTrainingSet()
|
|
{
|
|
var trainingSet = new TrainingSet();
|
|
|
|
// build data sets
|
|
var spamSet = BuildSpamDataSet();
|
|
var hamSet = BuildHamDataSet();
|
|
|
|
// monkey test
|
|
//spamSet.SetSize.Should()
|
|
//.Be(hamSet.SetSize, "because this test relies on identical set sizes for exact probability testing");
|
|
|
|
// register classes
|
|
_spamClass = spamSet.Class;
|
|
_hamClass = hamSet.Class;
|
|
|
|
// add the sets and return
|
|
trainingSet.Add(spamSet, hamSet);
|
|
return trainingSet;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the spam data set.
|
|
/// </summary>
|
|
/// <returns>IDataSet<StringClass, StringToken>.</returns>
|
|
private static IDataSet BuildSpamDataSet()
|
|
{
|
|
return BuildDataSet("spam", 0.5D, "rolex", "watches", "viagra", "prince", "money", "send", "xyzzy");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the spam data set.
|
|
/// </summary>
|
|
/// <returns>IDataSet<StringClass, StringToken>.</returns>
|
|
private static IDataSet BuildHamDataSet()
|
|
{
|
|
return BuildDataSet("ham", 0.5D, "love", "flowers", "unicorn", "friendship", "money", "send", "send");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the data set.
|
|
/// </summary>
|
|
/// <param name="className">Name of the class.</param>
|
|
/// <param name="classProbability">The class probability.</param>
|
|
/// <param name="token">The token.</param>
|
|
/// <param name="additionalTokens">The additional tokens.</param>
|
|
/// <returns>IDataSet<StringClass, StringToken>.</returns>
|
|
private static IDataSet BuildDataSet(string className, double classProbability, string token, params string[] additionalTokens)
|
|
{
|
|
var @class = new StringClass(className, classProbability);
|
|
var dataSet = new DataSet(@class);
|
|
|
|
dataSet.AddToken(new StringToken(token));
|
|
dataSet.AddToken(additionalTokens.Select(t => new StringToken(t)));
|
|
|
|
return dataSet;
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CalculateProbabilityReturnsOneHundredPercentForAKnownSpamWord()
|
|
{
|
|
var token = new StringToken("rolex");
|
|
|
|
var probability = _classifier.CalculateProbability(_spamClass, token);
|
|
//probability.Should().BeApproximately(1.0D, 0.0001D, "because the word is known the be a spam word");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CalculateProbabilityReturnsOneHundredPercentForAKnownHamWord()
|
|
{
|
|
var token = new StringToken("unicorn");
|
|
|
|
var probability = _classifier.CalculateProbability(_hamClass, token);
|
|
//probability.Should().BeApproximately(1.0D, 0.0001D, "because the word is known the be a ham word");
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CalculateProbabilitiesWithHamWordReturnsProbabilitiesForAllClasses()
|
|
{
|
|
var token = new StringToken("unicorn");
|
|
|
|
var probabilities = _classifier.CalculateProbabilities(token).ToList();
|
|
/*probabilities.Single(p => p.Class.Equals(_spamClass))
|
|
.Probability.Should()
|
|
.BeApproximately(0D, 0.000001D, "because the token is known to be a ham word");
|
|
|
|
probabilities.Single(p => p.Class.Equals(_hamClass))
|
|
.Probability.Should()
|
|
.BeApproximately(1D, 0.000001D, "because the token is known to be a ham word");*/
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CalculateProbabilitiesWithMixedWordReturnsProbabilitiesForAllClasses()
|
|
{
|
|
var token = new StringToken("money");
|
|
|
|
var probabilities = _classifier.CalculateProbabilities(token).ToList();
|
|
/*probabilities.Single(p => p.Class.Equals(_spamClass))
|
|
.Probability.Should()
|
|
.BeApproximately(0.5D, 0.000001D, "because the token is known to be a ham and spam word");
|
|
|
|
probabilities.Single(p => p.Class.Equals(_hamClass))
|
|
.Probability.Should()
|
|
.BeApproximately(0.5D, 0.000001D, "because the token is known to be a ham and spam word");*/
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CalculateProbabilitiesWithMixedWordThatIsMoreLikelyHamThanSpamReturnsProbabilitiesForAllClasses()
|
|
{
|
|
var token = new StringToken("send");
|
|
|
|
var probabilities = _classifier.CalculateProbabilities(token).ToList();
|
|
/*probabilities.Single(p => p.Class.Equals(_spamClass))
|
|
.Probability.Should()
|
|
.BeApproximately(1 / 3D, 0.000001D, "because the token is more likely to be a ham than spam word");
|
|
|
|
probabilities.Single(p => p.Class.Equals(_hamClass))
|
|
.Probability.Should()
|
|
.BeApproximately(2 / 3D, 0.000001D, "because the token is more likely to be a ham than spam word");*/
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CalculateProbabilitiesWithRareTokensAndSmoothingAlphaIsUnambiguous()
|
|
{
|
|
var token1 = new StringToken("rolex");
|
|
var token2 = new StringToken("unicorn");
|
|
var token3 = new StringToken("send");
|
|
|
|
const double smoothingAlpha = 1.0D;
|
|
var probabilities = _classifier.CalculateProbabilities(new IToken[] { token1, token2, token3 }, smoothingAlpha).ToList();
|
|
|
|
/*probabilities.Single(p => p.Class.Equals(_spamClass))
|
|
.Probability.Should()
|
|
.BeLessThan(0.5D, "because we used more ham than spam tokens");
|
|
|
|
probabilities.Single(p => p.Class.Equals(_hamClass))
|
|
.Probability.Should()
|
|
.BeGreaterThan(0.5D, "because we used more ham than spam tokens");*/
|
|
}
|
|
}
|
|
}
|