Bayesian Belief Networks

H
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bayesian Belief Network"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Bayesian Belief Network is a graphical representation of different probabilistic relationships among random variables in a particular set. It is a classifier with no dependency on attributes i.e it is condition independent. Due to its feature of joint probability, the probability in Bayesian Belief Network is derived, based on a condition — P(attribute/parent) i.e probability of an attribute, true over parent attribute.\n",
    "\n",
    "![Example](https://media.geeksforgeeks.org/wp-content/uploads/20200816124850/BBN.png)\n",
    "\n",
    "-  In the above figure, we have an alarm ‘A’ – a node, say installed in a house of a person ‘gfg’, which rings upon two probabilities i.e burglary ‘B’ and fire ‘F’, which are – parent nodes of the alarm node. The alarm is the parent node of two probabilities P1 calls  ‘P1’ & P2 calls ‘P2’ person nodes.\n",
    "-  Upon the instance of burglary and fire, ‘P1’ and ‘P2’ call person ‘gfg’, respectively. But, there are few drawbacks in this case, as sometimes ‘P1’ may forget to call the person ‘gfg’, even after hearing the alarm, as he has a tendency to forget things, quick.  Similarly, ‘P2’, sometimes fails to call the person ‘gfg’, as he is only able to hear the alarm, from a certain distance.\n",
    "\n",
    "Source: [basic-understanding-of-bayesian-belief-networks](https://www.geeksforgeeks.org/basic-understanding-of-bayesian-belief-networks/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pgmpy.models import BayesianNetwork\n",
    "\n",
    "# Create a Bayesian Network Model\n",
    "model = BayesianNetwork([('Fever', 'Flu'), ('Cough', 'Flu'), ('Flu', 'Cold')])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pgmpy.factors.discrete import TabularCPD\n",
    "\"\"\"\n",
    "CPT stands for Conditional Probability Table. \n",
    "In the context of Bayesian Belief Networks (BBNs) or Bayesian Networks, \n",
    "CPTs play a crucial role in modeling the probabilistic relationships between random variables. \n",
    "They are used to define the conditional probabilities of a node's values given the values of its parent nodes. \n",
    "In pgmpy, CPTs are represented using the TabularCPD class.\n",
    "\"\"\"\n",
    "# Fever CPT\n",
    "cpt_fever = TabularCPD(variable='Fever', variable_card=2, values=[[0.95], [0.05]])\n",
    "model.add_cpds(cpt_fever)\n",
    "\n",
    "# Cough CPT\n",
    "cpt_cough = TabularCPD(variable='Cough', variable_card=2, values=[[0.85], [0.15]])\n",
    "model.add_cpds(cpt_cough)\n",
    "\n",
    "# Flu CPT\n",
    "cpt_flu = TabularCPD(variable='Flu', variable_card=2, values=[[0.99, 0.40, 0.20, 0.01],\n",
    "                                                              [0.01, 0.60, 0.80, 0.99]],\n",
    "                     evidence=['Fever', 'Cough'], evidence_card=[2, 2])\n",
    "model.add_cpds(cpt_flu)\n",
    "\n",
    "# Cold CPT\n",
    "cpt_cold = TabularCPD(variable='Cold', variable_card=2, values=[[0.90, 0.40], \n",
    "                                                                [0.10, 0.60]],\n",
    "                      evidence=['Flu'], evidence_card=[2])\n",
    "model.add_cpds(cpt_cold)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "+--------+---------+-----------------+\n",
      "| Flu    | Cold    |   phi(Flu,Cold) |\n",
      "+========+=========+=================+\n",
      "| Flu(0) | Cold(0) |          0.1800 |\n",
      "+--------+---------+-----------------+\n",
      "| Flu(0) | Cold(1) |          0.0200 |\n",
      "+--------+---------+-----------------+\n",
      "| Flu(1) | Cold(0) |          0.3200 |\n",
      "+--------+---------+-----------------+\n",
      "| Flu(1) | Cold(1) |          0.4800 |\n",
      "+--------+---------+-----------------+\n"
     ]
    }
   ],
   "source": [
    "from pgmpy.inference import VariableElimination\n",
    "\"\"\"\n",
    "Inference in a BBN refers to the process of using the network to make \n",
    "probabilistic predictions or to answer queries about specific random variables based on available evidence.\n",
    "Inference helps us compute the posterior probabilities of variables of interest given observations or evidence. \n",
    "It's a central component of BBNs and allows us to reason under uncertainty.\n",
    "In pgmpy, the VariableElimination class is used to perform inference in a BBN.\n",
    "\"\"\"\n",
    "\n",
    "# Create an inference object\n",
    "inference = VariableElimination(model)\n",
    "\n",
    "# Query the network for probabilities\n",
    "result = inference.query(variables=['Flu', 'Cold'], \n",
    "                         evidence={'Fever': 1, 'Cough': 0})\n",
    "print(result)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# Convert the model to a networkx graph for visualization\n",
    "nx_graph = model.to_markov_model()\n",
    "\n",
    "# Visualize the network\n",
    "plt.figure(figsize=(10, 5))\n",
    "\n",
    "pos = nx.kamada_kawai_layout(nx_graph)\n",
    "\n",
    "nx.draw(nx_graph, pos, with_labels=True, node_size=1600, node_color=\"skyblue\", \n",
    "        node_shape=\"s\", alpha=0.5, linewidths=40)\n",
    "\n",
    "plt.margins(0.1)\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
About this Algorithm

Bayesian Belief Network

Bayesian Belief Network is a graphical representation of different probabilistic relationships among random variables in a particular set. It is a classifier with no dependency on attributes i.e it is condition independent. Due to its feature of joint probability, the probability in Bayesian Belief Network is derived, based on a condition — P(attribute/parent) i.e probability of an attribute, true over parent attribute.

Example

  • In the above figure, we have an alarm ‘A’ – a node, say installed in a house of a person ‘gfg’, which rings upon two probabilities i.e burglary ‘B’ and fire ‘F’, which are – parent nodes of the alarm node. The alarm is the parent node of two probabilities P1 calls ‘P1’ & P2 calls ‘P2’ person nodes.
  • Upon the instance of burglary and fire, ‘P1’ and ‘P2’ call person ‘gfg’, respectively. But, there are few drawbacks in this case, as sometimes ‘P1’ may forget to call the person ‘gfg’, even after hearing the alarm, as he has a tendency to forget things, quick. Similarly, ‘P2’, sometimes fails to call the person ‘gfg’, as he is only able to hear the alarm, from a certain distance.

Source: basic-understanding-of-bayesian-belief-networks

from pgmpy.models import BayesianNetwork

# Create a Bayesian Network Model
model = BayesianNetwork([('Fever', 'Flu'), ('Cough', 'Flu'), ('Flu', 'Cold')])
from pgmpy.factors.discrete import TabularCPD
"""
CPT stands for Conditional Probability Table. 
In the context of Bayesian Belief Networks (BBNs) or Bayesian Networks, 
CPTs play a crucial role in modeling the probabilistic relationships between random variables. 
They are used to define the conditional probabilities of a node's values given the values of its parent nodes. 
In pgmpy, CPTs are represented using the TabularCPD class.
"""
# Fever CPT
cpt_fever = TabularCPD(variable='Fever', variable_card=2, values=[[0.95], [0.05]])
model.add_cpds(cpt_fever)

# Cough CPT
cpt_cough = TabularCPD(variable='Cough', variable_card=2, values=[[0.85], [0.15]])
model.add_cpds(cpt_cough)

# Flu CPT
cpt_flu = TabularCPD(variable='Flu', variable_card=2, values=[[0.99, 0.40, 0.20, 0.01],
                                                              [0.01, 0.60, 0.80, 0.99]],
                     evidence=['Fever', 'Cough'], evidence_card=[2, 2])
model.add_cpds(cpt_flu)

# Cold CPT
cpt_cold = TabularCPD(variable='Cold', variable_card=2, values=[[0.90, 0.40], 
                                                                [0.10, 0.60]],
                      evidence=['Flu'], evidence_card=[2])
model.add_cpds(cpt_cold)

from pgmpy.inference import VariableElimination
"""
Inference in a BBN refers to the process of using the network to make 
probabilistic predictions or to answer queries about specific random variables based on available evidence.
Inference helps us compute the posterior probabilities of variables of interest given observations or evidence. 
It's a central component of BBNs and allows us to reason under uncertainty.
In pgmpy, the VariableElimination class is used to perform inference in a BBN.
"""

# Create an inference object
inference = VariableElimination(model)

# Query the network for probabilities
result = inference.query(variables=['Flu', 'Cold'], 
                         evidence={'Fever': 1, 'Cough': 0})
print(result)
+--------+---------+-----------------+
| Flu    | Cold    |   phi(Flu,Cold) |
+========+=========+=================+
| Flu(0) | Cold(0) |          0.1800 |
+--------+---------+-----------------+
| Flu(0) | Cold(1) |          0.0200 |
+--------+---------+-----------------+
| Flu(1) | Cold(0) |          0.3200 |
+--------+---------+-----------------+
| Flu(1) | Cold(1) |          0.4800 |
+--------+---------+-----------------+
import networkx as nx
import matplotlib.pyplot as plt

# Convert the model to a networkx graph for visualization
nx_graph = model.to_markov_model()

# Visualize the network
plt.figure(figsize=(10, 5))

pos = nx.kamada_kawai_layout(nx_graph)

nx.draw(nx_graph, pos, with_labels=True, node_size=1600, node_color="skyblue", 
        node_shape="s", alpha=0.5, linewidths=40)

plt.margins(0.1)
plt.show()