
That model can be build using following code piece:
Range range = new Range(ItemsCount);
VariableArray<bool> observedSex = Variable.Observed(observedResults, range).Named("observed sex");
VariableArray<Vector> trainingData = Variable.Observed(observedData, range).Named("observations");
Variable<Vector> weights = Variable.Random(
new VectorGaussian(new Vector(ParamCount),
PositiveDefiniteMatrix.Identity(ParamCount))).Named("weights");
observedSex[range] = Variable.InnerProduct(weights, trainingData[range]) > 0;
So, let's generate some observed data using "unknown" linear model:
const int ParamCount = 4;
Vector[] observedData = new Vector[ItemsCount];
bool[] observedResults = new bool[ItemsCount];
for (int i = 0; i < ItemsCount; ++i)
{
double sexuality = Math.Max(0, Math.Min(Gaussian.Sample(0.5, 1), 1));
double smartness = Math.Max(0, Math.Min(Gaussian.Sample(0.1, 0.5), 1));
double slutness = Math.Max(0, Math.Min(Gaussian.Sample(0.3, 1), 1));
bool haveSex = sexuality + 0.1 * smartness - slutness > 0.25;
observedData[i] = new Vector(sexuality, smartness, slutness, 1);
observedResults[i] = haveSex;
}
We can now infer weight vector posterior distribution using Expectation Propagation algorithm. Gaussian distribution is symmetric and unimodal, so we'll take it's mean as a result.
InferenceEngine engine = new InferenceEngine { Algorithm = new ExpectationPropagation()};
VectorGaussian weightDistribution = engine.Infer<VectorGaussian>(weights);
Vector mean = weightDistribution.GetMean();
Console.WriteLine(
"Model: ({0:0.00})*sexuality + ({1:0.00})*smartness + ({2:0.00})*slutness + ({3:0.00}) > 0",
1, mean[1] / mean[0], mean[2] / mean[0], mean[3] / mean[0]);
After running that sample we'll get the following output which confirms that we have reconstructed unknown linear model quite precise:Compiling model...done.
Initialising...done.
Iterating:
.........|.........|.........|.........|.........| 50
Model: (1.00)*sexuality + (0.10)*smartness + (-0.99)*slutness + (-0.26) > 0
0 comments:
Post a Comment