39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
|
|
||
|
|
||
|
class BayesNet:
|
||
|
|
||
|
def __init__(self, ldep=None): # Why not ldep={}? See footnote 1.
|
||
|
if not ldep:
|
||
|
ldep = {}
|
||
|
self.dependencies = ldep
|
||
|
|
||
|
# The network data is stored in a dictionary that
|
||
|
# associates the dependencies to each variable:
|
||
|
# { v1:deps1, v2:deps2, ... }
|
||
|
# These dependencies are themselves given
|
||
|
# by another dictionary that associates conditional
|
||
|
# probabilities to conjunctions of mother variables:
|
||
|
# { mothers1:cp1, mothers2:cp2, ... }
|
||
|
# The conjunctions are frozensets of pairs (mothervar,boolvalue)
|
||
|
def add(self,var,mothers,prob):
|
||
|
self.dependencies.setdefault(var,{})[frozenset(mothers)] = prob
|
||
|
|
||
|
# Joint probability for a given conjunction of
|
||
|
# all variables of the network
|
||
|
def jointProb(self,conjunction):
|
||
|
prob = 1.0
|
||
|
for (var,val) in conjunction:
|
||
|
for (mothers,p) in self.dependencies[var].items():
|
||
|
if mothers.issubset(conjunction):
|
||
|
prob*=(p if val else 1-p)
|
||
|
return prob
|
||
|
|
||
|
|
||
|
# Footnote 1:
|
||
|
# Default arguments are evaluated on function definition,
|
||
|
# not on function evaluation.
|
||
|
# This creates surprising behaviour when the default argument is mutable.
|
||
|
# See:
|
||
|
# http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments
|
||
|
|