using BotSharp.Algorithm.Extensions; using BotSharp.Algorithm.Formulas; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BotSharp.Algorithm.Bayes { /// /// https://en.wikipedia.org/wiki/Bayes%27_theorem /// public class NaiveBayes where Smoother : ISmoother, new() { /// /// smoothing function /// private Smoother smoother; public List FeaturesDist { get; set; } public List LabelDist { get; set; } public NaiveBayes() { smoother = new Smoother(); } /// /// calculate posterior probability P(Y|X) /// X is feature set, Y is label /// P(X1,...,Xn|Y) = Sum(P(X1|Y) +...+ P(Xn|Y) /// P(X, Y) = P(Y|X)P(X) = P(X|Y)P(Y) => P(Y|X) = P(Y)P(X|Y)/P(X) /// /// label /// /// public double PosteriorProb(string Y, List features) { double prob = 0; // prior probability prob = Math.Log(smoother.Prob(LabelDist, Y), 2); // posterior probability P(X1,...,Xn|Y) = Sum(P(X1|Y) +...+ P(Xn|Y) var featuresIfY = FeaturesDist.Where(fd => fd.Label == Y).ToList(); // loop features for (int x = 0; x < features.Count; x++) { var Xn = features[x]; var fv = featuresIfY.First(fd => fd.FeatureName == Xn.Name).FeatureValues; // features are independent, so calculate every feature prob and sum them prob += Math.Log(smoother.Prob(fv, Xn.Value), 2); } return prob; } } public class Feature { public string Name { get; set; } public string Value { get; set; } public Feature(string name, string value) { Name = name; Value = value; } } public class FeaturesWithLabel { public List Features { get; set; } public string Label { get; set; } public FeaturesWithLabel() { this.Features = new List(); } } public class FeaturesDistribution { public string Label { get; set; } public string FeatureName { get; set; } public List FeatureValues { get; set; } public override string ToString() { return $"{Label} {FeatureName} {FeatureValues.Count}"; } } }