class Bayesnet::Graph

Acyclic graph

Attributes

nodes[R]

Public Class Methods

new() click to toggle source
# File lib/bayesnet/graph.rb, line 10
def initialize
  @nodes = {}
end

Public Instance Methods

chances(assignment, evidence:) click to toggle source
# File lib/bayesnet/graph.rb, line 46
def chances(assignment, evidence:)
  over_vars = assignment.slice(*var_names) # maintains order of vars
  posterior_distribution = distribution(over: over_vars.keys, evidence: evidence)
  posterior_distribution[*over_vars.values]
end
distribution(over: [], evidence: {}) click to toggle source
# File lib/bayesnet/graph.rb, line 32
def distribution(over: [], evidence: {})
  joint_distribution
    .reduce_to(evidence)
    .marginalize(over)
    .normalize
end
joint_distribution() click to toggle source
# File lib/bayesnet/graph.rb, line 52
def joint_distribution
  return @joint_distribution if @joint_distribution

  if @nodes.empty?
    @joint_distribution = Factor.new
    return @joint_distribution
  end

  factor = Factor.new
  @nodes.each do |node_name, node|
    factor.scope node_name => node.values
  end

  factor.contextes(*var_names).each do |context|
    val_by_name = var_names.zip(context).to_h
    val = nodes.values.reduce(1.0) do |prob, node|
      prob * node.factor[val_by_name]
    end
    factor.val context + [val]
  end
  @joint_distribution = factor.normalize
end
most_likely_value(var_name, evidence:) click to toggle source

This is MAP query, i.e. Maximum a Posteriory

# File lib/bayesnet/graph.rb, line 40
def most_likely_value(var_name, evidence:)
  posterior_distribution = distribution(over: [var_name], evidence: evidence)
  mode = posterior_distribution.contextes(var_name).zip(posterior_distribution.values).max_by(&:last)
  mode.first.first
end
node(name, parents: [], &block) click to toggle source
# File lib/bayesnet/graph.rb, line 18
def node(name, parents: [], &block)
  raise Error, "DSL error, #node requires a &block" unless block

  node = Node.new(name, parents)
  node.instance_eval(&block)
  @nodes[name] = node
end
parameters() click to toggle source
# File lib/bayesnet/graph.rb, line 75
def parameters
  nodes.values.map(&:parameters).sum
end
resolve_factors() click to toggle source
# File lib/bayesnet/graph.rb, line 26
def resolve_factors
  @nodes.values.each do |node|
    node.resolve_factor(@nodes.slice(*node.parent_nodes))
  end
end
var_names() click to toggle source
# File lib/bayesnet/graph.rb, line 14
def var_names
  nodes.keys
end