{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Oliver's blood\n", "\n", "Copyright 2018 Allen B. Downey\n", "\n", "MIT License: https://opensource.org/licenses/MIT" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Configure Jupyter to display the assigned value after an assignment\n", "%config InteractiveShell.ast_node_interactivity='last_expr_or_assign'\n", "\n", "from thinkbayes2 import Pmf, Suite" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is another problem from MacKay’s *Information Theory, Inference, and Learning Algorithms*:\n", "\n", ">Two people have left traces of their own blood at the scene of a\n", "crime. A suspect, Oliver, is tested and found to have type ‘O’\n", "blood. The blood groups of the two traces are found to be of type\n", "‘O’ (a common type in the local population, having frequency 60%)\n", "and of type ‘AB’ (a rare type, with frequency 1%). Do these data\n", "(type ‘O’ and ‘AB’ blood were found at scene) give evidence in\n", "favour of the proposition that Oliver was one of the two people\n", "present at the crime?\n", "\n", "MacKay suggests formulating the problem like this:\n", "\n", ">Denote the proposition ‘the suspect and one unknown person were present’ by `S`. The alternative, `S̄`, states ‘two unknown people from the population were present’.\n", "\n", "And then he computes the conditional probabilities of the data under `S` and `S̄`.\n", "\n", "```\n", "P(D | S) = p(AB)\n", "\n", "P(D | S̄) = 2 p(O) p(AB)\n", "```\n", "\n", "Some people are initially unsure why there is a factor of two in the second equation. One way to convince yourself that it is correct is a verbal argument: \"If Oliver did not leave a blood trace at the scene, then the blood traces were left by two unknown people. If we consider these unknown people in order, the first might have left type ‘O’ blood and the second might have left type ‘AB’, or the other way around. Since there are two ways to account for the data, we have to add their probabilities.\"\n", "\n", "This is correct, but with probability it is easy for errors to hide in the words. I find it useful to express the idea computationally as well.\n", "\n", "I'll create a `Pmf` object with the distribution of blood types." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AB\t 0.01\n", "O\t 0.6\n", "other\t 0.39\n" ] } ], "source": [ "types = Pmf({'O\\t': 0.6, 'AB\\t':0.01, 'other\\t':0.39})\n", "types.Print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can compute `P(D | S) = p(AB)`" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "0.01" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "like_S = types['AB\\t']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Pmf` provides an addition operator that computes the distribution of all pairs of outcomes:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AB\tAB\t 0.0001\n", "AB\tO\t 0.006\n", "AB\tother\t 0.0039000000000000003\n", "O\tAB\t 0.006\n", "O\tO\t 0.36\n", "O\tother\t 0.23399999999999999\n", "other\tAB\t 0.0039000000000000003\n", "other\tO\t 0.23399999999999999\n", "other\tother\t 0.1521\n" ] } ], "source": [ "pairs = types + types\n", "pairs.Print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Reading this table, we can see more explicitly that there are two outcomes that account for the data, `AB O` and `O AB`.\n", "\n", "So we can compute `P(D | S̄)`:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.012" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "like_S̄ = pairs['O\\tAB\\t'] + pairs['AB\\tO\\t']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As MacKay points out, the data are more likely under `S̄` than under `S`, so they are evidence in favor of `S̄`; that is, they are exculpatory.\n", "\n", "Let's do the update, assuming that the prior is 50:50." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "S 0.5\n", "S̄ 0.5\n" ] } ], "source": [ "suite = Suite(['S', 'S̄'])\n", "suite.Print()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.011" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "suite['S'] *= like_S\n", "suite['S̄'] *= like_S̄\n", "suite.Normalize()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In light of this evidence, we are slightly more inclined to believe that Oliver is not guilty (or at least, did not leave a blood trace at the scene)." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "S 0.4545454545454546\n", "S̄ 0.5454545454545455\n" ] } ], "source": [ "suite.Print()" ] } ], "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.6.5" } }, "nbformat": 4, "nbformat_minor": 1 }