Skip to main content

Online learning in C#

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


using BayesServer.Inference;
using BayesServer.Inference.RelevanceTree;
using BayesServer.Learning.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BayesServer.HelpSamples
{
public static class OnlineLearningExample
{
public static void Main()
{
// Manually construct a network. We could instead load from a file etc...
var network = CreateNetwork();

// Reference some variables and states
var a = network.Variables["A", true];
var b = network.Variables["B", true];
var a1 = a.States["A1", true];
var a2 = a.States["A2", true];
var b1 = b.States["B1", true];
var b2 = b.States["B2", true];

var inferenceFactory = new RelevanceTreeInferenceFactory();
var onlineLearning = new OnlineLearning(network, inferenceFactory);
var options = new OnlineLearningOptions();

// Now set some evidence...

var evidence = onlineLearning.Evidence;

// Note that we are using the 'Evidence' instance supplied by the OnlineLearning instance,
// however we could instead ...

// 1. Create our own evidence instance...
// var evidence = new Evidence(network);
// 2. Use one created by an inference engine...
// var inference = new RelevanceTreeInference();
// var evidence = inference.Evidence;

evidence.SetState(b1);

// Note that at this point we have missing data on A which is supported.
onlineLearning.Adapt(evidence, options);

// Note that the same onlineLearning instance should be re-used.

evidence.SetState(b2);
evidence.SetState(a1);

onlineLearning.Adapt(evidence, options);

// We have now performed online learning twice.
// Lets look at the distributions and experience tables

var tableA = a.Node.Distribution.Table;
Console.WriteLine("P(A) = [{0}, {1}]", tableA[a1], tableA[a2]);
var experienceA = a.Node.Distributions[NodeDistributionKind.Experience].Table;
Console.WriteLine("Experience (A) = [{0}]", experienceA[0]);

Console.WriteLine();

var tableB = b.Node.Distribution.Table;
Console.WriteLine("P(B|A1) = [{0}, {1}]", tableB[a1, b1], tableB[a1, b2]);
Console.WriteLine("P(B|A2) = [{0}, {1}]", tableB[a2, b1], tableB[a2, b2]);
var experienceB = b.Node.Distributions[NodeDistributionKind.Experience].Table;
Console.WriteLine("Experience (B) = [{0}, {1}]", experienceB[a1], experienceB[a2]);



}

private static Network CreateNetwork()
{
// Here we manually create a Bayesian network
// showing how you can set experience tables manually.

// Instead you can also use the following option with ParameterLearning
// to automatically create Experience tables from data

// var options = new ParameterLearningOptions();
// options.SaveHyperparameters = true;

var network = new Network();

var a1 = new State("A1");
var a2 = new State("A2");
var a = new Variable("A", a1, a2);
network.Nodes.Add(new Node(a));

var b1 = new State("B1");
var b2 = new State("B2");
var b = new Variable("B", b1, b2);
network.Nodes.Add(new Node(b));

network.Links.Add(new Link(a.Node, b.Node));

// Manually set the standard probability tables...
// Note that you could instead learn these from data.
var tableA = a.Node.NewDistribution().Table;
tableA[a1] = 0.2;
tableA[a2] = 0.8;
a.Node.Distribution = tableA;

var tableB = b.Node.NewDistribution().Table;
tableB[a1, b1] = 0.35;
tableB[a1, b2] = 0.65;
tableB[a2, b1] = 0.55;
tableB[a2, b2] = 0.45;
b.Node.Distribution = tableB;

// Now set some experience tables...
// You could instead learn these from data (see notes above).

var experienceA = a.Node.NewDistribution(NodeDistributionKind.Experience).Table;
experienceA[0] = 1000.0;
a.Node.Distributions[NodeDistributionKind.Experience] = experienceA;

// Note that we could chose to set experience tables on some but not all nodes,
// if we only want to update a subset of nodes.

var experienceB = b.Node.NewDistribution(NodeDistributionKind.Experience).Table;
experienceB[a1] = 300.0;
experienceB[a2] = 700.0;
b.Node.Distributions[NodeDistributionKind.Experience] = experienceB;

return network;


}
}
}