Skip to main content

Batch query C#

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

namespace BayesServer.HelpSamples
{
using System;
using System.Collections.Generic;
using System.Text;
using BayesServer.Data;
using System.Data;
using BayesServer.Inference.RelevanceTree;

public static class BatchQueryExample
{
public static void Main()
{
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");

// discrete
var burningRegimen = network.Variables["Burning Regimen"];
var wasteType = network.Variables["Waste type", true];
var filterState = network.Variables["Filter state", true];

var burningRegimenStable = burningRegimen.States["Stable", true];

// continuous
var filterEfficiency = network.Variables["Filter efficiency", true];
var dustEmission = network.Variables["Dust emission", true];
var metalsInWaste = network.Variables["Metals in waste", true];
var co2Concentration = network.Variables["CO2 concentration", true];
var lightPenetrability = network.Variables["Light penetrability", true];
var metalsEmission = network.Variables["Metals emission", true];

// Create an inference engine to calculate the queries.
// The same inference engine can be re-used for multiple rows of data.
// Although not shown here, you can also create multiple inference engines,
// to take advantage of multiple threads.

var factory = new RelevanceTreeInferenceFactory();
var inference = factory.CreateInferenceEngine(network);
var queryOptions = factory.CreateQueryOptions();
var queryOutput = factory.CreateQueryOutput();

// add some marginal queries
var queryBurningRegimen = new Table(burningRegimen);
inference.QueryDistributions.Add(queryBurningRegimen);
var queryLightPenetrability = new CLGaussian(lightPenetrability);
inference.QueryDistributions.Add(queryLightPenetrability);
// You can also add joint queries over > 1 variable
var queryJoint = new CLGaussian(new Variable[] { filterEfficiency, burningRegimen });
inference.QueryDistributions.Add(queryJoint);

// we will also query the log-likelihood
queryOptions.LogLikelihood = true;


var evidenceReaderCommand = CreateEvidenceReaderCommand(network);

var readOptions = new ReadOptions();

// Iterate through the data, perform queries for each row.
// In this example, the output is simply written to the console, but the output
// could be streamed into a database or another data store or endpoint.

using (var evidenceReader = evidenceReaderCommand.ExecuteReader())
{
while (evidenceReader.Read(inference.Evidence, readOptions))
{
inference.Query(queryOptions, queryOutput);

var logLikelihood = queryOutput.LogLikelihood.Value;
var probStable = queryBurningRegimen[burningRegimenStable];
var meanLightPenetrability = queryLightPenetrability.GetMean(lightPenetrability);
var varianceLightPenetrability = queryLightPenetrability.GetVariance(lightPenetrability);
var jointElement = queryJoint.GetMean(filterEfficiency, burningRegimenStable);


Console.WriteLine($"{logLikelihood}\t{probStable}\t{meanLightPenetrability}\t{varianceLightPenetrability}\t{jointElement}");
}
}
}

/// <summary>
/// Create an evidence reader command, than maps data to variables.
///
/// This can connect to a database, a DataTable or you can create a custom reader.
/// </summary>
private static IEvidenceReaderCommand CreateEvidenceReaderCommand(Network network)
{
var dataReaderCommand = CreateDataReaderCommand();

var wasteType = network.Variables["Waste type", true];
var co2Concentration = network.Variables["CO2 concentration", true];

return new EvidenceReaderCommand(
dataReaderCommand,
new VariableReference[]
{
new VariableReference(wasteType, ColumnValueType.Name, wasteType.Name),
new VariableReference(co2Concentration, ColumnValueType.Value, co2Concentration.Name),
},
new ReaderOptions()
);

}

/// <summary>
/// Manually create some data here to keep the example self contained.
/// This could also be queried from a database,
/// or another data source.
/// </summary>
private static IDataReaderCommand CreateDataReaderCommand()
{
var table = new DataTable();
var wasteType = table.Columns.Add("Waste type", typeof(string));
var co2Concentration = table.Columns.Add("CO2 concentration", typeof(double));

// you can use null for missing data

table.Rows.Add("Industrial", -1.7);
table.Rows.Add("Household", -2.0);
table.Rows.Add(null, -1.7);
table.Rows.Add("Industrial", null);
table.Rows.Add("Industrial", 0.5);

return new DataTableDataReaderCommand(table);
}

// Expected output ...
//-1.56469966974624 0.934046351645668 1.57952317582283 0.419529880001972 -3.725
//-0.247575914981347 0.98111967122024 1.52305983561012 0.351488920422928 -3.065
//-0.311935701250374 0.934046351645668 1.52238029582283 0.380432496848107 -3.25357124
//-1.25276396849587 0.85 1.5375 0.43747475 -3.725
//-7.21683608441226 1.11889682547702E-11 1.11250000000559 0.420474750002601 -3.725
}
}