Skip to main content

Inference (discrete & continuous) with a Bayesian network in C#

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


using BayesServer.Inference.RelevanceTree;
using System;
using System.Collections.Generic;
using System.Text;

namespace BayesServer.HelpSamples
{
public static class InferenceHybrid
{
public static void Main()
{
// Uncomment the following line and change the license key, if you are using a licensed version
// License.Validate("xxx");

var network = new Network();

// TODO download the network from the Bayes Server User Interface (or Bayes Server Online)
// and adjust the following path
network.Load(@"Waste.bayes");

Console.WriteLine($"Network has {network.Variables.Count} variables.");

// Reference some variables
var wasteType = network.Variables["Waste type", true];
var co2Concentration = network.Variables["CO2 concentration", true];
var filterEfficiency = network.Variables["Filter efficiency", true];
var metalsInWaste = network.Variables["Metals in waste", true];
var metalsEmission = network.Variables["Metals emission", true];
var lightPenetrability = network.Variables["Light penetrability", true];

// Create an inference engine

var factory = new RelevanceTreeInferenceFactory();
var inference = factory.CreateInferenceEngine(network);
var queryOptions = factory.CreateQueryOptions();
queryOptions.LogLikelihood = true; // Only set this if you need the log-likelihood
var queryOutput = factory.CreateQueryOutput();

// Set some evidence
var evidence = inference.Evidence;
var industrial = wasteType.States["Industrial", true];
evidence.SetState(industrial); // set discrete evidence

// evidence.SetStates(wasteType, new double[] { 0.2, 0.8 }); // example of setting soft evidence

evidence.Set(co2Concentration, -1.0); // set continuous evidence

var queryDistributions = inference.QueryDistributions;

// How to add a discrete query
var filterState = network.Variables["Filter state", true];
var queryFilterState = new Table(filterState);
queryDistributions.Add(queryFilterState);

// How to add a continuous query
var queryFilterEfficiency = new CLGaussian(filterEfficiency);
queryDistributions.Add(queryFilterEfficiency);

// How to add a joint query

var queryJoint = new CLGaussian(new Variable[] { lightPenetrability, metalsEmission });
queryDistributions.Add(queryJoint);

// Calculate the queries/predictions
inference.Query(queryOptions, queryOutput);

// Output the results
Console.WriteLine($"Log-likelihood: {queryOutput.LogLikelihood}");

var filterEfficiencyMean = queryFilterEfficiency.GetMean(filterEfficiency);
var filterEfficiencyVariance = queryFilterEfficiency.GetVariance(filterEfficiency);

Console.WriteLine($"{filterEfficiencyMean}, {Math.Sqrt(filterEfficiencyVariance)}");

foreach (var state in filterState.States)
{
Console.WriteLine($"Filter state: {state.Name} {queryFilterState[state]}");
}

Console.WriteLine($"Joint covariance = {queryJoint.GetCovariance(lightPenetrability, metalsEmission)}");

// Expected output...
// Network has 9 variables.
// Log-likelihood: -3.40279833515147
// -3.725, 0.762823046322016
// Filter state: Intact 0.95
// Filter state: Defect 0.05
// Joint covariance = -0.36786975428679

}
}
}