Skip to main content

Data Sampling in C#

// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DataSampling.cs" company="Bayes Server">
// Copyright (C) Bayes Server. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace BayesServer.HelpSamples
{
using System;

using BayesServer.Data.Sampling;
using BayesServer.Inference;

public static class DataSampling
{
public static void Main()
{
// we manually construct the network here, but it could be loaded from a file
var network = CreateNetwork();
var gender = network.Variables["Gender"];
var height = network.Variables["Height"];
var hairLength = network.Variables["Hair Length"];

// You can set evidence on 'fixedEvidence' if you wish to fix
// certain variables. Here we fix Gender.
var fixedEvidence = new Evidence(network);
fixedEvidence.SetState(gender.States["Female", true]);

// prepare to sample data from the Bayesian network
var sampler = new DataSampler(network, fixedEvidence);
var options = new DataSamplingOptions();

// If you want to simulate missing data, you can use the following line of code...
// options.MissingDataProbability = 0.05; // set 5% of the data to missing

var random = new RandomDefault(0);
var evidence = new Evidence(network);

// output 100 samples

Console.WriteLine("Gender\tHeight\tHair Length");
Console.WriteLine("------------------------------");

for (int i = 0; i < 100; i++)
{
try
{
sampler.TakeSample(evidence, random, options);
Console.WriteLine("{0}\t{1}\t{2}",
ValueAsText(gender, evidence),
ValueAsText(height, evidence),
ValueAsText(hairLength, evidence));
}
catch (InconsistentEvidenceException)
{
Console.WriteLine("Inconsistent evidence exception was raised.");
}
}
}

private static string ValueAsText(Variable variable, IEvidence evidence)
{
if(evidence.GetEvidenceType(variable) == EvidenceType.None)
return "(null)";

if (variable.ValueType == VariableValueType.Continuous)
{
return evidence.Get(variable).Value.ToString("N2");
}
else
{
return variable.States[evidence.GetState(variable).Value].Name;
}
}

private static Network CreateNetwork()
{
var network = new Network();
var nodeGender = new Node("Gender", new string[] { "Female", "Male" });
network.Nodes.Add(nodeGender);

var nodeHeight = new Node("Height", VariableValueType.Continuous);
network.Nodes.Add(nodeHeight);

var nodeHairLength = new Node("Hair Length", new string[] { "Short", "Medium", "Long" });
network.Nodes.Add(nodeHairLength);

network.Links.Add(new Link(nodeGender, nodeHeight));
network.Links.Add(new Link(nodeGender, nodeHairLength));

// at this point the structure of the Bayesian network is fully specified

// now set the parameters

var tableGender = nodeGender.NewDistribution().Table;
tableGender.CopyFrom(new double[] { 0.51, 0.49 });
nodeGender.Distribution = tableGender;

var tableHairLength = nodeHairLength.NewDistribution().Table;
var iteratorHairLength = new TableIterator(tableHairLength, new Node[] { nodeGender, nodeHairLength });
iteratorHairLength.CopyFrom(new double[] { 0.1, 0.4, 0.5, 0.8, 0.15, 0.05 });
nodeHairLength.Distribution = tableHairLength;

var gaussianHeight = (CLGaussian)nodeHeight.NewDistribution();
// set the mean and variance for females
gaussianHeight.SetMean(0, 0, 162.56);
gaussianHeight.SetVariance(0, 0, 50.58);

// set the mean and variance for males
gaussianHeight.SetMean(1, 0, 176.022);
gaussianHeight.SetVariance(1, 0, 50.58);

nodeHeight.Distribution = gaussianHeight;

// check that the Bayesian network is specified correctly
network.Validate(new ValidationOptions());

return network;
}
}
}