Commit c3d90f16 authored by Hendrik Buschmeier's avatar Hendrik Buschmeier
Browse files

Added PRIMO ipython notebook tutorial.

parent 15b22174
# -*- coding: utf-8 -*-
import numpy
class NaiveBayesDS:
def __init__(self):
self.rootNode = None
self.featureNodes = []
self.evidence = []
def calcRootDistribution(self):
"""
Berechnung der Verteilung des Wurzelknotens.
P(A | B1, ... Bn) [für alle B mit Evidenz]
A: Wurzelknoten/self.rootNode
B: featureNode
"""
# Array für Verteilung anlegen und mit Nullen füllen
distributionOfA = numpy.zeros(len(self.rootNode[1]))
# Der Divisor für die Formel wird inkrementell aufsummiert
divisor = 0
# Summe über alle Zustände von A
for j in range(len(self.rootNode[2])):
# Produkt über alle Evidenzen gegebener Bs, multipliziert mit Aj
tmpprod = self.rootNode[2][j]
for i in range(len(self.evidence)):
tmpNode = self.evidence[i][0]
evIdx = self.evidence[i][1]
evIdx = self.getIndex(tmpNode, evIdx)
evConfidence = self.evidence[i][2]
# Confidence der Evidenz auf CPT rechnen
tmpCpt = numpy.copy(tmpNode[2])
ix = 0
for row in tmpCpt:
for ridx in range(len(row)):
row[ridx] *= evConfidence
remains = 1 - numpy.sum(row)
remains /= len(row)
for ridx in range(len(row)):
row[ridx] += remains
tmpCpt[ix] = row
ix += 1
tmpprod *= tmpCpt[j][evIdx]
# Achtung! Hier ist die Verteilung von A noch nicht feritg (s.u.)
distributionOfA[j] = tmpprod
divisor += tmpprod
# Abschließend die Verteilung von A durch den Divisor teilen
distributionOfA = numpy.array(distributionOfA) / divisor
return distributionOfA
def calcFeatureDistribution(self, featureNode):
"""
Berechnung der Verteilung eines Feature-Knoten:
P(B_i | B1, ... B_i-1, B_i+1, ... Bn) [für alle featureNode mit Evidenz]
A: Wurzelknoten/self.rootNode
B: featureNode
"""
# Array für Verteilung anlegen und mit Nullen füllen
distributionOfB = numpy.zeros(len(featureNode[1]))
# Die Verteilung von A kann aus Aufgabe 1 genutzt werden
distributionOfA = self.calcRootDistribution()
# Verteilung für featureNode iterativ berechnen
for i in range(len(featureNode[1])):
tmpsum = 0
# Multiplikationssatz:
for j in range(len(distributionOfA)):
# P(B_i|A_j) * PRODUKT über P(A_j|evidence)
tmpsum += featureNode[2][j][i] * distributionOfA[j]
distributionOfB[i] = tmpsum
return distributionOfB
def hasEvidence(self, node):
"""
Prüft, ob für einen Featureknoten Evidenz gesetzt ist.
"""
for e in self.evidence:
enode = e[0]
if node == enode:
return True
return False
def getIndex(self, node, value):
"""
Index für gegebenen Evidenz-Wert zurückgeben.
"""
for i in range(len(node[1])):
if node[1][i] == value:
return i
return -1
def getFeatureEntropy(self, featureNode):
"""
Entropie für einen Featureknoten berechnen.
"""
if self.hasEvidence(featureNode):
return 0
return self.getEntropy(self.calcFeatureDistribution(featureNode))
def getRootEntropy(self):
"""
Entropie für den Wurzelknoten berechnen.
"""
if self.hasEvidence(self.rootNode):
return 0
distribution = self.calcRootDistribution()
return self.getEntropy(distribution)
def getEntropy(self, distribution):
"""
Entropie für eine Verteilung berechnen.
SUMME über alle Werte der Verteilung mit P(B=b) * log2( P(B=b) )
"""
entropy = 0.0
for d in distribution:
if (d > 0):
entropy -= d * numpy.log2(d)
return entropy
def getConditionalEntropy(self, featureNode):
"""
Bedingte Entropie für den Wurzelknoten bei gegebenen Featureknoten
berechnen, für welchen noch keine Evidenz vorliegt.
SUMME über alle b aus B mit P(B=b) * H(A|B=b)
"""
entropy = 0.0
if self.hasEvidence(featureNode):
return 0
idx = 0
for value in featureNode[1]:
# P(B=b)
distB = self.calcFeatureDistribution(featureNode)
probValue = distB[idx]
# H(A|B=b)
evEntry = [featureNode, value, 1.0]
self.evidence.append(evEntry)
rootEntropy = self.getRootEntropy()
self.evidence = self.evidence[:-1]
# SUMME += P(B=b) * H(A|B=b)
entropy += probValue * rootEntropy
idx += 1
return entropy
{
"metadata": {
"name": "",
"signature": "sha256:5d6d1074166d83c785ce5c1c3faa78e5f5285c404ea2117b8d56e2bc402e5ff9"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1>Belief Networks - Approximierte Inferenz</h1>\n",
"Mittels MCMC-Verfahren kann in *PRIMO* auch approximierte Inferenz berechnet werden. Hier wird das gleiche Beispiel wie bei der exakten Inferenz verwendet:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline\n",
"from primo.networks import BayesianNetwork\n",
"from primo.nodes import DiscreteNode\n",
"import numpy\n",
"\n",
"# Netz initialisieren\n",
"bn = BayesianNetwork()\n",
"\n",
"# Knoten und deren m\u00f6gliche Zust\u00e4nde festlegen\n",
"burglary = DiscreteNode(\"Burglary\", [\"Intruder\",\"Safe\"])\n",
"alarm = DiscreteNode(\"Alarm\", [\"Ringing\", \"Silent\"])\n",
"earthquake = DiscreteNode(\"Earthquake\", [\"Shaking\", \"Calm\"])\n",
"john_calls = DiscreteNode(\"John calls\", [\"Calling\", \"Not Calling\"])\n",
"baum_calls = DiscreteNode(\"Baum calls\", [\"Calling\", \"Not Calling\"])\n",
"\n",
"# Knoten ins Netz hinzuf\u00fcgen\n",
"bn.add_node(burglary)\n",
"bn.add_node(alarm)\n",
"bn.add_node(earthquake)\n",
"bn.add_node(john_calls)\n",
"bn.add_node(baum_calls)\n",
"\n",
"# Kanten einf\u00fcgen\n",
"bn.add_edge(burglary,alarm)\n",
"bn.add_edge(earthquake, alarm)\n",
"bn.add_edge(alarm, john_calls)\n",
"bn.add_edge(alarm, baum_calls)\n",
"\n",
"# F\u00fcr Wurzelknoten (ohne Eltern) werden hier im Beispiel die CPTs direkt gesetzt\n",
"cpt_burglary = numpy.array([0.001,0.999])\n",
"burglary.set_probability_table(cpt_burglary,[burglary])\n",
"\n",
"cpt_earthquake = numpy.array([0.002,0.998])\n",
"earthquake.set_probability_table(cpt_earthquake,[earthquake])\n",
"\n",
"# Setzen der CPT-Werte f\u00fcr Knoten mit Eltern\n",
"alarm.set_probability(0.95,[(alarm,\"Ringing\"),(burglary,\"Intruder\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.05,[(alarm,\"Silent\"),(burglary,\"Intruder\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.29,[(alarm,\"Ringing\"),(burglary,\"Safe\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.71,[(alarm,\"Silent\"),(burglary,\"Safe\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.94,[(alarm,\"Ringing\"),(burglary,\"Intruder\"),(earthquake,\"Calm\")])\n",
"alarm.set_probability(0.06,[(alarm,\"Silent\"),(burglary,\"Intruder\"),(earthquake,\"Calm\")])\n",
"alarm.set_probability(0.001,[(alarm,\"Ringing\"),(burglary,\"Safe\"),(earthquake,\"Calm\")])\n",
"alarm.set_probability(0.999,[(alarm,\"Silent\"),(burglary,\"Safe\"),(earthquake,\"Calm\")])\n",
"\n",
"baum_calls.set_probability(0.9,[(alarm,\"Ringing\"),(baum_calls,\"Calling\")])\n",
"baum_calls.set_probability(0.1,[(alarm,\"Ringing\"),(baum_calls,\"Not Calling\")])\n",
"baum_calls.set_probability(0.05,[(alarm,\"Silent\"),(baum_calls,\"Calling\")])\n",
"baum_calls.set_probability(0.95,[(alarm,\"Silent\"),(baum_calls,\"Not Calling\")])\n",
"\n",
"john_calls.set_probability(0.7,[(alarm,\"Ringing\"),(john_calls,\"Calling\")])\n",
"john_calls.set_probability(0.3,[(alarm,\"Ringing\"),(john_calls,\"Not Calling\")])\n",
"john_calls.set_probability(0.01,[(alarm,\"Silent\"),(john_calls,\"Calling\")])\n",
"john_calls.set_probability(0.99,[(alarm,\"Silent\"),(john_calls,\"Not Calling\")])\n",
"\n",
"# Grafische Ausgabe des Netzes\n",
"bn.draw()"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>Funktionen</h2>\n",
"<p>\n",
"Um MCMC zu initialisieren sind mindestens zwei Parameter notwendig: Das Bayesnetz selbst und die Anzahl der Iterationen.\n",
"</p>\n",
"<p>Optional k\u00f6nnen auch das \u00dcbergangsmodell und das Limit f\u00fcr den Konvergenztest bei der Berechnung der Markov-Kette gesetzt werden.\n",
"Metropolis-Hastings:\n",
"```\n",
"mcmc = MCMC(bn, 5000, transition_model=MetropolisHastingsTransitionModel()) # DEFAULT\n",
"```\n",
"Gibbs-Sampling:\n",
"```\n",
"mcmc = MCMC(bn, 5000, transition_model=GibbsTransitionModel())\n",
"```\n",
"\n",
"Limt f\u00fcr den Konvergenztest:\n",
"```\n",
"mcmc = MCMC(bn, 5000, convergence_test=ConvergenceTestSimpleCounting(500)) # DEFAULT\n",
"mcmc = MCMC(bn, 5000, convergence_test=ConvergenceTestSimpleCounting(100))\n",
"```\n",
"\n",
"Im Beispiel wird gezeigt, wie mit MCMC a-priori und a-posteriori Wahrscheinlichkeiten, sowie die Evidenzwahrscheinlichkeit (<i>Probability of Evidence</i>) und die MAP-Hypothese berechnet werden k\u00f6nnen."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from primo.inference.mcmc import MCMC\n",
"from primo.inference.mcmc import GibbsTransitionModel\n",
"from primo.inference.mcmc import MetropolisHastingsTransitionModel\n",
"from primo.evidence import EvidenceEqual as EvEq\n",
"from primo.densities import ProbabilityTable\n",
"from primo.inference.mcmc import ConvergenceTestSimpleCounting\n",
"\n",
"# MCMC initialisieren: Bayesnetz, Iterationen, transition model\n",
"#mcmc = MCMC(bn, 5000, transition_model=GibbsTransitionModel())\n",
"#mcmc = MCMC(bn, 5000, transition_model=MetropolisHastingsTransitionModel())\n",
"mcmc = MCMC(bn, 5000, transition_model=GibbsTransitionModel(), convergence_test=ConvergenceTestSimpleCounting(500))\n",
"\n",
"\n",
"\n",
"print \"-------PriorMarginal:-------\"\n",
"pm = mcmc.calculate_PriorMarginal([alarm],ProbabilityTable)\n",
"print \"P(Alarm)= \" + str(pm)\n",
"print \"Ground truth=[0.0025 0.9975]\\n\"\n",
"\n",
"pm = mcmc.calculate_PriorMarginal([burglary],ProbabilityTable)\n",
"print \"P(Burglary)= \" + str(pm)\n",
"print \"Ground truth=[0.001 0.999]\\n\"\n",
"\n",
"# Evidenz setzen\n",
"evidence = {burglary:EvEq(\"Intruder\")}\n",
"\n",
"\n",
"\n",
"print \"-------ProbabilityOfEvidence:-------\" \n",
"poe = mcmc.calculate_PoE(evidence)\n",
"print \"p(evidence=Intruder)=\"+str(poe)\n",
"print \"Ground truth=0.001\\n\"\n",
"\n",
"print \"-------PosteriorMarginal:-------\"\n",
"pm = mcmc.calculate_PosteriorMarginal([alarm],evidence,ProbabilityTable)\n",
"print \"P(alarm|burglary=Intruder)=\"+str(pm)\n",
"print \"Ground truth=[0.94 0.06]\\n\"\n",
"\n",
"\n",
"\n",
"print \"-------MAP:-------\"\n",
"hyp = mcmc.calculate_MAP([alarm],evidence,ProbabilityTable)\n",
"print \"MAP(alarm|burglary=intruder)=\" + str(hyp)\n",
"print \"Ground truth=\\\"Ringing\\\"\\n\"\n",
"\n",
"hyp = mcmc.calculate_MAP([burglary,alarm],{},ProbabilityTable)\n",
"print \"MAP(burglary,alarm)=\"+str(hyp)\n",
"print \"Ground truth=\\\"Safe\\\",\\\"Silent\\\"\\n\"\n"
],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
\ No newline at end of file
{
"metadata": {
"name": "",
"signature": "sha256:b5510da9fa62058537da539fc44d713d34ed6b88e5a9a7acab0e555001879c5a"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1>Belief Networks - Kontinuierliche Variablen</h1>\n",
"<p>MCMC (siehe <a href=\"chapters/belief_approx.ipynb\">Belief Networks - Approximierte Inferenz</a>) kann neben diskreten auch mit kontinuierlichen Variablen Inferenzen ziehen. Allerdings kann ein Bayesnetz nur aus kontinuierlichen oder nur aus diskreten Variablen bestehen, eine Berechnung auf einem Netz, wo diese Typen vermischt sind, ist aktuell noch nicht m\u00f6glich.\n",
"</p>\n",
"<p>\n",
"Sowohl bei der Parametrisierung von Knoten als auch bei der Inferenz k\u00f6nnen Verteilungen angegeben werden. Diese sind in `primo.densities` implementiert, dort bereits enthalten sind: Beta-Verteilung, Exponential-Verteilung und Gauss-Verteilung.\n",
"</p>\n",
"<p>\n",
"Im folgenden Beispiel ist ein Bayesnetz modelliert, welches das lineare Verh\u00e4ltnis zwischen Alter und H\u00f6he einer Pflanze modelliert, zuz\u00fcglich Rauschen.\n",
"</p>"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline\n",
"from primo.networks import BayesianNetwork\n",
"from primo.nodes import ContinuousNodeFactory\n",
"from primo.densities import ExponentialParameters\n",
"from primo.densities import BetaParameters\n",
"from primo.densities import GaussParameters\n",
"\n",
"# Bayesnetz initialisieren\n",
"bn = BayesianNetwork()\n",
"\n",
"# Knoten erstellen und hinzuf\u00fcgen\n",
"cnf = ContinuousNodeFactory()\n",
"\n",
"age = cnf.createExponentialNode(\"Age\")\n",
"sun = cnf.createBetaNode(\"Sun\")\n",
"ground = cnf.createGaussNode(\"Ground\")\n",
"growth = cnf.createGaussNode(\"Growth\")\n",
"height = cnf.createBetaNode(\"Height\")\n",
"diameter = cnf.createExponentialNode(\"Diameter\")\n",
"children = cnf.createExponentialNode(\"Children\")\n",
"\n",
"bn.add_node(age)\n",
"bn.add_node(sun)\n",
"bn.add_node(ground)\n",
"bn.add_node(growth)\n",
"bn.add_node(height)\n",
"bn.add_node(diameter)\n",
"bn.add_node(children)\n",
"\n",
"# Kanten erstellen\n",
"bn.add_edge(age, growth)\n",
"bn.add_edge(ground, growth)\n",
"bn.add_edge(sun, growth)\n",
"bn.add_edge(growth, diameter)\n",
"bn.add_edge(growth, height)\n",
"bn.add_edge(height, children)\n",
"bn.add_edge(ground, children)\n",
"\n",
"# Parametrisierung\n",
"age.set_density_parameters(ExponentialParameters(0.1, {}))\n",
"sun.set_density_parameters(BetaParameters(2, {}, 2, {}))\n",
"ground.set_density_parameters(GaussParameters(2.0, {}, 1.5))\n",
"growth.set_density_parameters(GaussParameters(0.1, {age:5.0, ground:1.0, sun:4.0}, 2.5))\n",
"height.set_density_parameters(BetaParameters(0.1, {growth:1}, 0.5, {growth:0.5}))\n",
"diameter.set_density_parameters(ExponentialParameters(0.01, {growth:0.2}))\n",
"children.set_density_parameters(ExponentialParameters(0.1, {ground:1.0, height:1.0}))\n",
"\n",
"bn.draw()"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2>Funktionen</h2>\n",
"<p>\n",
"Zur Inferenz auf kontinuierlichen Netzen k\u00f6nnen die gleichen Funktionen wie auf diskreten Netzen verwendet werden. (F\u00fcr die Parameter des MCMC-Konstruktors siehe ebenfalls <a href=\"chapters/belief_approx.ipynb\">Belief Networks - Approximierte Inferenz</a>).\n",
"</p>\n",
"<p>\n",
"Bei den R\u00fcckgabewerten werden die Verteilungsparameter angegeben. Im Beispiel f\u00fcr die Gauss-Verteilung sind dies \"`mu`\" f\u00fcr den Erwartungswert $\\mu$ und \"`c`\" f\u00fcr die Standardabweichung $\\sigma$.\n",
"</p>\n"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from primo.inference.mcmc import MCMC\n",
"from primo.evidence import EvidenceEqual as EvEqual\n",
"from primo.densities import NDGauss\n",
"from primo.densities import Gauss\n",
"\n",
"# MCMC mit Standardwerten initialisieren\n",
"mcmc = MCMC(bn, 100)\n",
"\n",
"print \"PriorMarginal:\"\n",
"pm = mcmc.calculate_PriorMarginal([age], NDGauss)\n",
"print pm\n",
"pm = mcmc.calculate_PriorMarginal([height], NDGauss)\n",
"print pm\n",
"\n",
"# Evidenz setzen\n",
"evidence = {age:EvEqual(2)}\n",
"\n",
"print \"PosteriorMarginal:\"\n",
"pm = mcmc.calculate_PosteriorMarginal([age, height], evidence, NDGauss)\n",
"print pm"
],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
\ No newline at end of file
{
"metadata": {
"name": "",
"signature": "sha256:8d5da5c534ffd680f845f7a01f34a54839873823dcd8d641a54447577f16576a"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h1 id=\"inferenz\">Belief Networks - Exakte Inferenz</h1>\n",
"<ul>\n",
"<li><a href=\"#fe\">Factor Elimination</a></li>\n",
"<li><a href=\"#ftree\">Factor Tree</a></li>\n",
"</ul>\n",
"\n",
"Im Folgenden werden verschiedene Methoden f\u00fcr die exakte Inferenz vorgestellt. Daf\u00fcr soll das Beispiel aus *A. Darwiche - Modeling and Reasoning with Bayesian Networks, S. 54* dienen:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline\n",
"from primo.networks import BayesianNetwork\n",
"from primo.nodes import DiscreteNode\n",
"import numpy\n",
"\n",
"# Netz initialisieren\n",
"bn = BayesianNetwork()\n",
"\n",
"# Knoten und deren m\u00f6gliche Zust\u00e4nde festlegen\n",
"burglary = DiscreteNode(\"Burglary\", [\"Intruder\",\"Safe\"])\n",
"alarm = DiscreteNode(\"Alarm\", [\"Ringing\", \"Silent\"])\n",
"earthquake = DiscreteNode(\"Earthquake\", [\"Shaking\", \"Calm\"])\n",
"john_calls = DiscreteNode(\"John calls\", [\"Calling\", \"Not Calling\"])\n",
"baum_calls = DiscreteNode(\"Baum calls\", [\"Calling\", \"Not Calling\"])\n",
"\n",
"# Knoten ins Netz hinzuf\u00fcgen\n",
"bn.add_node(burglary)\n",
"bn.add_node(alarm)\n",
"bn.add_node(earthquake)\n",
"bn.add_node(john_calls)\n",
"bn.add_node(baum_calls)\n",
"\n",
"# Kanten einf\u00fcgen\n",
"bn.add_edge(burglary,alarm)\n",
"bn.add_edge(earthquake, alarm)\n",
"bn.add_edge(alarm, john_calls)\n",
"bn.add_edge(alarm, baum_calls)\n",
"\n",
"# F\u00fcr Wurzelknoten (ohne Eltern) werden hier im Beispiel die CPTs direkt gesetzt\n",
"cpt_burglary = numpy.array([0.001,0.999])\n",
"burglary.set_probability_table(cpt_burglary,[burglary])\n",
"\n",
"cpt_earthquake = numpy.array([0.002,0.998])\n",
"earthquake.set_probability_table(cpt_earthquake,[earthquake])\n",
"\n",
"# Setzen der CPT-Werte f\u00fcr Knoten mit Eltern\n",
"alarm.set_probability(0.95,[(alarm,\"Ringing\"),(burglary,\"Intruder\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.05,[(alarm,\"Silent\"),(burglary,\"Intruder\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.29,[(alarm,\"Ringing\"),(burglary,\"Safe\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.71,[(alarm,\"Silent\"),(burglary,\"Safe\"),(earthquake,\"Shaking\")])\n",
"alarm.set_probability(0.94,[(alarm,\"Ringing\"),(burglary,\"Intruder\"),(earthquake,\"Calm\")])\n",
"alarm.set_probability(0.06,[(alarm,\"Silent\"),(burglary,\"Intruder\"),(earthquake,\"Calm\")])\n",
"alarm.set_probability(0.001,[(alarm,\"Ringing\"),(burglary,\"Safe\"),(earthquake,\"Calm\")])\n",
"alarm.set_probability(0.999,[(alarm,\"Silent\"),(burglary,\"Safe\"),(earthquake,\"Calm\")])\n",
"\n",
"baum_calls.set_probability(0.9,[(alarm,\"Ringing\"),(baum_calls,\"Calling\")])\n",
"baum_calls.set_probability(0.1,[(alarm,\"Ringing\"),(baum_calls,\"Not Calling\")])\n",
"baum_calls.set_probability(0.05,[(alarm,\"Silent\"),(baum_calls,\"Calling\")])\n",
"baum_calls.set_probability(0.95,[(alarm,\"Silent\"),(baum_calls,\"Not Calling\")])\n",
"\n",
"john_calls.set_probability(0.7,[(alarm,\"Ringing\"),(john_calls,\"Calling\")])\n",
"john_calls.set_probability(0.3,[(alarm,\"Ringing\"),(john_calls,\"Not Calling\")])\n",
"john_calls.set_probability(0.01,[(alarm,\"Silent\"),(john_calls,\"Calling\")])\n",
"john_calls.set_probability(0.99,[(alarm,\"Silent\"),(john_calls,\"Not Calling\")])\n",
"\n",
"# Grafische Ausgabe des Netzes\n",
"bn.draw()"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 id=\"fe\">Exakte Inferenz - Factor Elimination</h2>\n",
"<i>(zuerst den Beispiel-Code aus <a href=\"#inferenz\">Exakte Inferenz</a> ausf\u00fchren)</i><br>\n",
"<i>EasiestFactorElimination</i> bildet zun\u00e4chst den Joint Probability Table (jpt), um anschlie\u00dfend auf die angefragten Variablen abzubilden:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline\n",
"from primo.inference.factor import EasiestFactorElimination\n",
"\n",
"# Initialisieren und Netz setzen\n",
"fe = EasiestFactorElimination(bn)\n",
"\n",
"# a-priori\n",
"print \"Prior Marginals:\"\n",
"print \"Prior Alarm: \" + str(fe.calculate_PriorMarginal([alarm]))\n",
"print \"Prior John_Calls: \" + str(fe.calculate_PriorMarginal([john_calls]))\n",
"print \"Prior Baum_Calls: \" + str(fe.calculate_PriorMarginal([baum_calls]))\n",
"print \"Prior Burglary: \" + str(fe.calculate_PriorMarginal([burglary]))\n",
"print \"Prior Earthquake: \" + str(fe.calculate_PriorMarginal([earthquake]))\n",
"\n",
"# Probability of Evidence f\u00fcr zwei Evidenz-Beispiele\n",
"print \"PoE Earthquake: \" + str(fe.calculate_PoE([(earthquake, \"Calm\")]))\n",
"print \"PoE BaumCalls is Calling: \" + str(fe.calculate_PoE([(baum_calls, \"Calling\")]))\n",
"\n",
"# a-posteriori (mit gegebener Evidenz f\u00fcr alarm und earthquake)\n",
"print \"Posterior of burglary : \" + str(fe.calculate_PosteriorMarginal([burglary],[(alarm, \"Ringing\"),(earthquake, \"Calm\")]))\n",
"print \"Posterior of alarm: \" + str(fe.calculate_PosteriorMarginal([alarm],[(burglary, \"Intruder\")]))\n"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<h2 id=\"ftree\">Exakte Inferenz - Factor Tree</h2>\n",
"<i>(zuerst den Beispiel-Code aus <a href=\"#inferenz\">Exakte Inferenz</a> ausf\u00fchren)</i><br>\n",
"<i>FactorTree</i> ist bei gro\u00dfen Netzen und/oder vielen Anfragen effizienter als <i>EasiestFactorElimination</i>. Die erste Anfrage ist zwar aufw\u00e4ndig, daf\u00fcr werden die folgenden Anfragen viel schneller verarbeitet.\n",
"Nach ver\u00e4nderter Evidenz m\u00fcssen zun\u00e4chst alle zwischengespeicherten Werte neu berechnet werden, was wieder relativ teuer ist, anschlie\u00dfend jedoch wieder zu schnellerer Verarbeitung f\u00fchrt.\n",
"\n",
"Im Beispiel werden die Berechungen f\u00fcr Marginals, sowohl a-priori sowie a-posteriori und die Berechnung der Evidenzwahrscheinlichkeit (<i>Probability of Evidence</i>) dargestellt."
]
},