Skip to content

Commit 981adad

Browse files
committed
probability notebook: add the car-insurance (Insurance) case-study section
A demonstrative section (after Variable Elimination) showing multi-valued discrete Bayesian networks: a tiny hand-built DiscreteBayesNet, then loading the 27-variable Insurance network via insurance()/read_bif and running exact inference on it (prior over Age, a query with evidence). Illustrates that enumeration_ask / elimination_ask work unchanged on multi-valued nets (#1285).
1 parent fe83281 commit 981adad

2 files changed

Lines changed: 136 additions & 0 deletions

File tree

notebooks/probability.ipynb

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,6 +3016,99 @@
30163016
"Of course, for more complicated networks, variable elimination will be significantly faster and runtime will drop not just by a constant factor, but by a polynomial factor proportional to the number of nodes, due to the reduction in repeated calculations."
30173017
]
30183018
},
3019+
{
3020+
"cell_type": "markdown",
3021+
"metadata": {},
3022+
"source": [
3023+
"## MULTI-VALUED NETWORKS: THE CAR-INSURANCE CASE STUDY\n",
3024+
"\n",
3025+
"The Bayesian networks above all use **boolean** variables. Many real models have variables with more than two values. AIMA's car-insurance case study (Section 16) is the classic example: the *Insurance* network of Binder, Koller, Russell & Kanazawa (1997), with 27 discrete variables.\n",
3026+
"\n",
3027+
"aima-python represents such networks with `DiscreteBayesNode` / `DiscreteBayesNet`. These expose the same `node.p(value, event)` / `variable_values` interface that inference relies on, so the very same `enumeration_ask` and `elimination_ask` used above work **unchanged** on multi-valued networks. Here is a tiny one built by hand:"
3028+
]
3029+
},
3030+
{
3031+
"cell_type": "code",
3032+
"execution_count": null,
3033+
"metadata": {},
3034+
"outputs": [],
3035+
"source": [
3036+
"rain_net = DiscreteBayesNet([\n",
3037+
" ('Rain', '', ['none', 'light', 'heavy'], {(): [0.6, 0.3, 0.1]}),\n",
3038+
" ('Traffic', 'Rain', ['low', 'high'],\n",
3039+
" {('none',): [0.9, 0.1], ('light',): [0.6, 0.4], ('heavy',): [0.2, 0.8]}),\n",
3040+
"])\n",
3041+
"\n",
3042+
"enumeration_ask('Rain', {'Traffic': 'high'}, rain_net).show_approx()"
3043+
]
3044+
},
3045+
{
3046+
"cell_type": "markdown",
3047+
"metadata": {},
3048+
"source": [
3049+
"### Loading the Insurance network\n",
3050+
"\n",
3051+
"Networks in the standard **BIF** (Bayesian Interchange Format) of the [bnlearn Bayesian Network Repository](https://www.bnlearn.com/bnrepository/) can be read with `read_bif`. The Insurance network ships in `aima-data`, so `insurance()` returns it directly — these are the discrete conditional distributions the book refers to:"
3052+
]
3053+
},
3054+
{
3055+
"cell_type": "code",
3056+
"execution_count": null,
3057+
"metadata": {},
3058+
"outputs": [],
3059+
"source": [
3060+
"insurance_net = insurance()\n",
3061+
"len(insurance_net.variables), insurance_net.variables[:8]"
3062+
]
3063+
},
3064+
{
3065+
"cell_type": "markdown",
3066+
"metadata": {},
3067+
"source": [
3068+
"Its variables are multi-valued, e.g. the driver's `Age` and the medical-cost outcome `MedCost`:"
3069+
]
3070+
},
3071+
{
3072+
"cell_type": "code",
3073+
"execution_count": null,
3074+
"metadata": {},
3075+
"outputs": [],
3076+
"source": [
3077+
"insurance_net.variable_values('Age'), insurance_net.variable_values('MedCost')"
3078+
]
3079+
},
3080+
{
3081+
"cell_type": "markdown",
3082+
"metadata": {},
3083+
"source": [
3084+
"Exact inference runs on the full 27-node network. The prior over the driver's age:"
3085+
]
3086+
},
3087+
{
3088+
"cell_type": "code",
3089+
"execution_count": null,
3090+
"metadata": {},
3091+
"outputs": [],
3092+
"source": [
3093+
"elimination_ask('Age', dict(), insurance_net).show_approx()"
3094+
]
3095+
},
3096+
{
3097+
"cell_type": "markdown",
3098+
"metadata": {},
3099+
"source": [
3100+
"And a query with evidence — the good-student probability for a wealthy adolescent (both of `GoodStudent`'s parents are observed here, so this reads straight off its CPT):"
3101+
]
3102+
},
3103+
{
3104+
"cell_type": "code",
3105+
"execution_count": null,
3106+
"metadata": {},
3107+
"outputs": [],
3108+
"source": [
3109+
"elimination_ask('GoodStudent', dict(Age='Adolescent', SocioEcon='Wealthy'), insurance_net).show_approx()"
3110+
]
3111+
},
30193112
{
30203113
"cell_type": "markdown",
30213114
"metadata": {},

notebooks/probability.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,49 @@
476476
# <br>
477477
# Of course, for more complicated networks, variable elimination will be significantly faster and runtime will drop not just by a constant factor, but by a polynomial factor proportional to the number of nodes, due to the reduction in repeated calculations.
478478

479+
# %% [markdown]
480+
# ## MULTI-VALUED NETWORKS: THE CAR-INSURANCE CASE STUDY
481+
#
482+
# The Bayesian networks above all use **boolean** variables. Many real models have variables with more than two values. AIMA's car-insurance case study (Section 16) is the classic example: the *Insurance* network of Binder, Koller, Russell & Kanazawa (1997), with 27 discrete variables.
483+
#
484+
# aima-python represents such networks with `DiscreteBayesNode` / `DiscreteBayesNet`. These expose the same `node.p(value, event)` / `variable_values` interface that inference relies on, so the very same `enumeration_ask` and `elimination_ask` used above work **unchanged** on multi-valued networks. Here is a tiny one built by hand:
485+
486+
# %%
487+
rain_net = DiscreteBayesNet([
488+
('Rain', '', ['none', 'light', 'heavy'], {(): [0.6, 0.3, 0.1]}),
489+
('Traffic', 'Rain', ['low', 'high'],
490+
{('none',): [0.9, 0.1], ('light',): [0.6, 0.4], ('heavy',): [0.2, 0.8]}),
491+
])
492+
493+
enumeration_ask('Rain', {'Traffic': 'high'}, rain_net).show_approx()
494+
495+
# %% [markdown]
496+
# ### Loading the Insurance network
497+
#
498+
# Networks in the standard **BIF** (Bayesian Interchange Format) of the [bnlearn Bayesian Network Repository](https://www.bnlearn.com/bnrepository/) can be read with `read_bif`. The Insurance network ships in `aima-data`, so `insurance()` returns it directly — these are the discrete conditional distributions the book refers to:
499+
500+
# %%
501+
insurance_net = insurance()
502+
len(insurance_net.variables), insurance_net.variables[:8]
503+
504+
# %% [markdown]
505+
# Its variables are multi-valued, e.g. the driver's `Age` and the medical-cost outcome `MedCost`:
506+
507+
# %%
508+
insurance_net.variable_values('Age'), insurance_net.variable_values('MedCost')
509+
510+
# %% [markdown]
511+
# Exact inference runs on the full 27-node network. The prior over the driver's age:
512+
513+
# %%
514+
elimination_ask('Age', dict(), insurance_net).show_approx()
515+
516+
# %% [markdown]
517+
# And a query with evidence — the good-student probability for a wealthy adolescent (both of `GoodStudent`'s parents are observed here, so this reads straight off its CPT):
518+
519+
# %%
520+
elimination_ask('GoodStudent', dict(Age='Adolescent', SocioEcon='Wealthy'), insurance_net).show_approx()
521+
479522
# %% [markdown]
480523
# ## Approximate Inference in Bayesian Networks
481524
#

0 commit comments

Comments
 (0)