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}";
}
}
}