diff --git a/probability.ipynb b/probability.ipynb
index 2fd1c9dae..365039874 100644
--- a/probability.ipynb
+++ b/probability.ipynb
@@ -11,21 +11,19 @@
},
{
"cell_type": "code",
- "execution_count": 1,
+ "execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from probability import *\n",
- "from notebook import psource"
+ "from notebook import *"
]
},
{
"cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"source": [
"## Probability Distribution\n",
"\n",
@@ -34,7 +32,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 34,
"metadata": {
"collapsed": true
},
@@ -45,7 +43,7 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 3,
"metadata": {},
"outputs": [
{
@@ -54,7 +52,7 @@
"0.75"
]
},
- "execution_count": 2,
+ "execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
@@ -255,9 +253,7 @@
},
{
"cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"source": [
"_A probability model is completely determined by the joint distribution for all of the random variables._ (**Section 13.3**) The probability module implements these as the class **JointProbDist** which inherits from the **ProbDist** class. This class specifies a discrete probability distribute over a set of variables. "
]
@@ -512,9 +508,124 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "def enumerate_joint_ask(X, e, P):\n",
+ " """Return a probability distribution over the values of the variable X,\n",
+ " given the {var:val} observations e, in the JointProbDist P. [Section 13.3]\n",
+ " >>> P = JointProbDist(['X', 'Y'])\n",
+ " >>> P[0,0] = 0.25; P[0,1] = 0.5; P[1,1] = P[2,1] = 0.125\n",
+ " >>> enumerate_joint_ask('X', dict(Y=1), P).show_approx()\n",
+ " '0: 0.667, 1: 0.167, 2: 0.167'\n",
+ " """\n",
+ " assert X not in e, "Query variable must be distinct from evidence"\n",
+ " Q = ProbDist(X) # probability distribution for X, initially empty\n",
+ " Y = [v for v in P.variables if v != X and v not in e] # hidden variables.\n",
+ " for xi in P.values(X):\n",
+ " Q[xi] = enumerate_joint(Y, extend(e, X, xi), P)\n",
+ " return Q.normalize()\n",
+ " \n",
+ "\n",
+ "\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"psource(enumerate_joint_ask)"
]
@@ -792,7 +903,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
@@ -1178,7 +1289,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 32,
"metadata": {
"collapsed": true
},
@@ -1418,21 +1529,8 @@
]
},
{
- "cell_type": "code",
- "execution_count": 45,
+ "cell_type": "markdown",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'False: 0.184, True: 0.816'"
- ]
- },
- "execution_count": 45,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
"source": [
"likelihood_weighting('Cloudy', dict(Rain=True), sprinkler, 200).show_approx()"
]
@@ -1450,7 +1548,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 27,
"metadata": {
"collapsed": true
},
@@ -1485,6 +1583,245 @@
"source": [
"gibbs_ask('Cloudy', dict(Rain=True), sprinkler, 200).show_approx()"
]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Inference in Temporal Models"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Before we start, it will be helpful to understand the structure of a temporal model. We will use the example of the book with the guard and the umbrella. In this example, the state $\\textbf{X}$ is whether it is a rainy day (`X = True`) or not (`X = False`) at Day $\\textbf{t}$. In the sensor or observation model, the observation or evidence $\\textbf{U}$ is whether the professor holds an umbrella (`U = True`) or not (`U = False`) on **Day** $\\textbf{t}$. Based on that, the transition model is \n",
+ "\n",
+ "| $X_{t-1}$ | $X_{t}$ | **P**$(X_{t}| X_{t-1})$| \n",
+ "| ------------- |------------- | ----------------------------------|\n",
+ "| ***${False}$*** | ***${False}$*** | 0.7 |\n",
+ "| ***${False}$*** | ***${True}$*** | 0.3 |\n",
+ "| ***${True}$*** | ***${False}$*** | 0.3 |\n",
+ "| ***${True}$*** | ***${True}$*** | 0.7 |\n",
+ "\n",
+ "And the the sensor model will be,\n",
+ "\n",
+ "| $X_{t}$ | $U_{t}$ | **P**$(U_{t}|X_{t})$| \n",
+ "| :-------------: |:-------------: | :------------------------:|\n",
+ "| ***${False}$*** | ***${True}$*** | 0.2 |\n",
+ "| ***${False}$*** | ***${False}$*** | 0.8 |\n",
+ "| ***${True}$*** | ***${True}$*** | 0.9 |\n",
+ "| ***${True}$*** | ***${False}$*** | 0.1 |\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In the filtering task we are given evidence **U** in each time **t** and we want to compute the belief $B_{t}(x)= P(X_{t}|U_{1:t})$. \n",
+ "We can think of it as a three step process:\n",
+ "1. In every step we start with the current belief $P(X_{t}|e_{1:t})$\n",
+ "2. We update it for time\n",
+ "3. We update it for evidence\n",
+ "\n",
+ "The forward algorithm performs the step 2 and 3 at once. It updates, or better say reweights, the initial belief using the transition and the sensor model. Let's see the umbrella example. On **Day 0** no observation is available, and for that reason we will assume that we have equal possibilities to rain or not. In the **`HiddenMarkovModel`** class, the prior probabilities for **Day 0** are by default [0.5, 0.5]. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "%psource HiddenMarkovModel"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We instantiate the object **`hmm`** of the class using a list of lists for both the transition and the sensor model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "umbrella_transition_model = [[0.7, 0.3], [0.3, 0.7]]\n",
+ "umbrella_sensor_model = [[0.9, 0.2], [0.1, 0.8]]\n",
+ "hmm = HiddenMarkovModel(umbrella_transition_model, umbrella_sensor_model)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The **`sensor_dist()`** method returns a list with the conditional probabilities of the sensor model."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[0.9, 0.2]"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "hmm.sensor_dist(ev=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The observation update is calculated with the **`forward()`** function. Basically, we update our belief using the observation model. The function returns a list with the probabilities of **raining or not** on **Day 1**."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "psource(forward)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The probability of raining on day 1 is 0.82\n"
+ ]
+ }
+ ],
+ "source": [
+ "belief_day_1 = forward(hmm, umbrella_prior, ev=True)\n",
+ "print ('The probability of raining on day 1 is {:.2f}'.format(belief_day_1[0]))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In **Day 2** our initial belief is the updated belief of **Day 1**. Again using the **`forward()`** function we can compute the probability of raining in **Day 2**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The probability of raining in day 2 is 0.88\n"
+ ]
+ }
+ ],
+ "source": [
+ "belief_day_2 = forward(hmm, belief_day_1, ev=True)\n",
+ "print ('The probability of raining in day 2 is {:.2f}'.format(belief_day_2[0]))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "In the smoothing part we are interested in computing the distribution over past states given evidence up to the present. Assume that we want to compute the distribution for the time **k**, for $0\\leq k