exercise 12
This commit is contained in:
parent
0e7f8d2273
commit
a737cb8e3f
|
@ -0,0 +1,875 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "3325951a33e219b4018ec2a3d92da174",
|
||||
"grade": false,
|
||||
"grade_id": "cell-5e22290104c842b6",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# You must run this cell, but you can ignore its contents.\n",
|
||||
"\n",
|
||||
"import hashlib\n",
|
||||
"\n",
|
||||
"def ads_hash(ty):\n",
|
||||
" \"\"\"Return a unique string for input\"\"\"\n",
|
||||
" ty_str = str(ty).encode()\n",
|
||||
" m = hashlib.sha256()\n",
|
||||
" m.update(ty_str)\n",
|
||||
" return m.hexdigest()[:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "a5067aaf2a99b7decbc8c17d9ebd280e",
|
||||
"grade": false,
|
||||
"grade_id": "cell-9f70118929cfc07a",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"# Bayesian Statistics: Interactive Bayesian updating\n",
|
||||
"\n",
|
||||
"From https://github.com/NuclearTalent/Bayes2019/blob/master/topics/basics-of-bayesian-statistics/Bayesian_updating_coinflip_interactive.ipynb"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "ca64a684f3ba03b196e9255ca7592b89",
|
||||
"grade": false,
|
||||
"grade_id": "cell-f4d886aaea957b85",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## <a name=\"Python\">Python/Jupyter set up</a>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "143499ed0f4a1d70035ac46a55a0f3ab",
|
||||
"grade": false,
|
||||
"grade_id": "cell-8a69051f2683cc79",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"\n",
|
||||
"import scipy.stats as stats\n",
|
||||
"from scipy.stats import norm, uniform\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"from ipywidgets import HBox, VBox, Layout, Tab, Label, Checkbox, Button\n",
|
||||
"from ipywidgets import FloatSlider, IntSlider, Play, Dropdown, HTMLMath \n",
|
||||
"\n",
|
||||
"from IPython.display import display\n",
|
||||
"\n",
|
||||
"import seaborn as sns\n",
|
||||
"sns.set()\n",
|
||||
"sns.set_context(\"talk\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "ee94303da91208f884b725bcdd5becf6",
|
||||
"grade": false,
|
||||
"grade_id": "cell-ef87f464e37e4cca",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## <a name=\"Updating\">Bayesian updating examples</a>\n",
|
||||
"\n",
|
||||
"$ \\newcommand{\\thetavec}{\\boldsymbol{\\theta}} \\newcommand{\\pr}{\\textrm{p}}$\n",
|
||||
"Recall Bayes' theorem with $\\thetavec$ the vector of parameters we seek and information $I$ is kept implicit.\n",
|
||||
"\n",
|
||||
"$$\n",
|
||||
" \\overbrace{\\pr(\\thetavec \\mid \\textrm{data},I)}^{\\textrm{posterior}} =\n",
|
||||
" \\frac{\\color{red}{\\overbrace{\\pr(\\textrm{data} \\mid \\thetavec,I)}^{\\textrm{likelihood}}} \\times\n",
|
||||
" \\color{blue}{\\overbrace{\\pr(\\thetavec \\mid I)}^{\\textrm{prior}}}}\n",
|
||||
" {\\color{darkgreen}{\\underbrace{\\pr(\\textrm{data} \\mid I)}_{\\textrm{evidence}}}}\n",
|
||||
"$$\n",
|
||||
"\n",
|
||||
"If we view the prior as the initial information we have about $\\thetavec$, summarized as a probability density function, then Bayes' theorem tells us how to <em>update</em> that information after observing some data: this is the posterior pdf. Here we will give some examples of how this plays out when tossing coins.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "bc0be5ceec85b10c29143e1ad87f5ceb",
|
||||
"grade": false,
|
||||
"grade_id": "cell-4f86b9c7f450dfdc",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Determining the bias of a coin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "0e80c93cb3e2872a51c58fa678e7990f",
|
||||
"grade": false,
|
||||
"grade_id": "cell-f277b01772407ee0",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"The idea here is that we are observing successive flips of a coin, which is a proxy for any process that has a binary outcome. There is a definite true probability for getting heads, which we'll label $p_h$, but we don't know what it is. We start with a preconceived notion of the probability expressed in terms of a prior pdf for $p_h$, i.e., $\\pr(p_h)$. With each flip of the coin, we have more information, so our goal is to <em>update</em> our expectation of $p_h$, meaning we want the posterior $\\pr(p_h \\mid \\mbox{ num tosses, num heads})$. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "c28b79b238bba84152b9e54b41ed109a",
|
||||
"grade": false,
|
||||
"grade_id": "cell-404c8f0599a0960c",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"#### Main code for coin-flipping UI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"code_folding": [],
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "6d07721a47fc47504f2987268924f940",
|
||||
"grade": false,
|
||||
"grade_id": "cell-87f9a4135ca5602b",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initial values (can be changed by widgets)\n",
|
||||
"n_trials_max = 5000 # maximum number of coin tosses\n",
|
||||
"prob_heads = 0.4 # p_h, the true probability of a heads\n",
|
||||
"x = np.linspace(0, 1, 301) # mesh for posterior plots (enough so smooth)\n",
|
||||
"\n",
|
||||
"class Data():\n",
|
||||
" \"\"\"Class to hold the array of heads and tails (1s and 0s) outcomes.\"\"\"\n",
|
||||
" def __init__(self, prob_heads=0.5, n_trials_max=5000):\n",
|
||||
" self._data = self.generate_data(prob_heads, n_trials_max)\n",
|
||||
" \n",
|
||||
" def generate_data(self, prob_heads, n_trials_max):\n",
|
||||
" \"\"\"Generate an array of heads or tails, 1 or 0, for n_trials_max\n",
|
||||
" independent tosses according to the Bernoulli distribution.\"\"\"\n",
|
||||
" self._data = stats.bernoulli.rvs(prob_heads, size=n_trials_max)\n",
|
||||
" \n",
|
||||
" def heads_in_data_to_N(self, N):\n",
|
||||
" \"\"\"Count how many heads in the first N elements of the data.\"\"\"\n",
|
||||
" return self._data[:N].sum()\n",
|
||||
"\n",
|
||||
"coin_data = Data(prob_heads, n_trials_max) \n",
|
||||
" \n",
|
||||
"def update_plot(N=0, jump=1, recalculate_data=True, \n",
|
||||
" prob_heads=0.5, n_trials_max=5000,\n",
|
||||
" alpha_1=1., beta_1=1.,\n",
|
||||
" alpha_2=30., beta_2=30.,\n",
|
||||
" alpha_3=0.2, beta_3=0.3\n",
|
||||
" ):\n",
|
||||
" \"\"\"\n",
|
||||
" Make a new plot based on the current widget settings for the input\n",
|
||||
" parameters.\n",
|
||||
" \"\"\" \n",
|
||||
" \n",
|
||||
" font_size = 18\n",
|
||||
" plt.rcParams.update({'font.size': font_size})\n",
|
||||
" \n",
|
||||
" fig = plt.figure(figsize=(12,5))\n",
|
||||
" ax = fig.add_subplot(1, 1, 1)\n",
|
||||
"\n",
|
||||
" if recalculate_data:\n",
|
||||
" coin_data.generate_data(prob_heads, n_trials_max)\n",
|
||||
" recalculate_data_w.value = False\n",
|
||||
"\n",
|
||||
" heads = coin_data.heads_in_data_to_N(N) # add up the 1s (= # of heads)\n",
|
||||
" # update using the conjugate prior, which is a beta pdf\n",
|
||||
" y_1 = stats.beta.pdf(x, alpha_1 + heads, beta_1 + N - heads) \n",
|
||||
" y_2 = stats.beta.pdf(x, alpha_2 + heads, beta_2 + N - heads) \n",
|
||||
" y_3 = stats.beta.pdf(x, alpha_3 + heads, beta_3 + N - heads) \n",
|
||||
"\n",
|
||||
" # default y_3 distribution has two high max at endpoints for plot\n",
|
||||
" y_max = np.max([y_1.max(), y_2.max()]) \n",
|
||||
" \n",
|
||||
" line1, = ax.plot(x, y_1, label=\"uniform prior\", color=\"blue\")\n",
|
||||
" ax.fill_between(x, 0, y_1, color=\"blue\", alpha=0.1)\n",
|
||||
" line2, = ax.plot(x, y_2, label=\"informative prior\", color=\"red\")\n",
|
||||
" ax.fill_between(x, 0, y_2, color=\"red\", alpha=0.1)\n",
|
||||
" line3, = ax.plot(x, y_3, label=\"anti prior\", color=\"green\")\n",
|
||||
" ax.fill_between(x, 0, y_3, color=\"green\", alpha=0.1)\n",
|
||||
" \n",
|
||||
" ax.set_xlabel(\"$p_h$, probability of heads\") \n",
|
||||
" ax.set_yticks([]) # turn off the plotting of ticks on the y-axis\n",
|
||||
" ax.axvline(prob_heads, 0, 1.1*y_max, color=\"k\", linestyle=\"--\", lw=2)\n",
|
||||
" ax.annotate(f'observe {N:d} tosses,\\n {heads:d} heads', \n",
|
||||
" xy=(0.05,0.85), xycoords='axes fraction', \n",
|
||||
" horizontalalignment='left',verticalalignment='top')\n",
|
||||
" leg = ax.legend(loc='upper right')\n",
|
||||
" leg.get_frame().set_alpha(0.4)\n",
|
||||
" ax.autoscale(tight=True)\n",
|
||||
"\n",
|
||||
" \n",
|
||||
"################### begin: text for help tabs ##################\n",
|
||||
"# In HTML (could move this to an external file!)\n",
|
||||
"overview_text = \\\n",
|
||||
" r\"\"\"<p>Here we explore Bayesian updating for a coin flip. There is help \n",
|
||||
" available under the other tabs.</p> \n",
|
||||
" <ul>\n",
|
||||
" <li>Bayes theorem tab: find out about Bayesian updating.\n",
|
||||
" <li>Toss coin tab: find out what the controls do.\n",
|
||||
" <li>Priors tab: change the three initial priors.\n",
|
||||
" <li>Setup tab: change how the plots are made.\n",
|
||||
" </ul> \n",
|
||||
" \"\"\" \n",
|
||||
"Bayes_text = \\\n",
|
||||
" r\"\"\"\n",
|
||||
" <p>Recall Bayes' theorem with $\\thetavec$ the vector of parameters \n",
|
||||
" we seek and information $I$ is kept implicit.</p>\n",
|
||||
"\n",
|
||||
" $$\n",
|
||||
" \\newcommand{\\thetavec}{\\boldsymbol{\\theta}}\n",
|
||||
" \\overbrace{p(\\thetavec \\mid \\textrm{data},I)}^{\\textrm{posterior}} =\n",
|
||||
" \\frac{\\color{red}{\\overbrace{p(\\textrm{data} \n",
|
||||
" \\mid \\thetavec,I)}^{\\textrm{likelihood}}} \\times\n",
|
||||
" \\color{blue}{\\overbrace{p(\\thetavec \\mid I)}^{\\textrm{prior}}}}\n",
|
||||
" {\\color{darkgreen}{\\underbrace{p(\\textrm{data} \n",
|
||||
" \\mid I)}_{\\textrm{evidence}}}}\n",
|
||||
" $$\n",
|
||||
"\n",
|
||||
" <p>If we view the prior as the initial information we have about \n",
|
||||
" $\\thetavec$, summarized as a probability density function, \n",
|
||||
" then Bayes' theorem tells us how to <em>update</em> that \n",
|
||||
" information after observing some data: this is the posterior pdf. \n",
|
||||
" Here we will look at an example of how this plays out in practice:\n",
|
||||
" flipping a (biased) coin.</p> \n",
|
||||
"\n",
|
||||
" <br>\n",
|
||||
"\n",
|
||||
" <p>The idea here is that we are observing successive flips of a coin, \n",
|
||||
" which is a proxy for any process that has a binary outcome. \n",
|
||||
" There is a definite true probability for getting heads, \n",
|
||||
" which we'll label $p_h$, but we don't know what it is. \n",
|
||||
" We start with a preconceived notion of the probability expressed \n",
|
||||
" in terms of a prior pdf for $p_h$, i.e., $p(p_h)$. \n",
|
||||
" With each flip of the coin, we have more information, so our goal is \n",
|
||||
" to <em>update</em> our expectation of $p_h$, meaning we want the \n",
|
||||
" posterior $p(p_h\\mid \\mbox{# tosses, # heads})$.</p> \n",
|
||||
"\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"toss_coin_text = \\\n",
|
||||
" r\"\"\"\n",
|
||||
" The graph shows three posteriors that result from three choices for\n",
|
||||
" the prior (see the \"Priors\" tab for details) for the number of coin\n",
|
||||
" tosses and observed heads shown at the upper left. The true probability\n",
|
||||
" of a heads, $p_h$, is indicated by a dashed vertical line.\n",
|
||||
" <ul>\n",
|
||||
" <li>The \"Next\" button advances the number of coin tosses by the\n",
|
||||
" amount shown after \"Jump\".\n",
|
||||
" <li>The \"Jump\" pulldown is used to set how many observations are\n",
|
||||
" made with each press of the \"Next\" button.\n",
|
||||
" <li>The \"Reset\" button sets the number of observations back to zero.\n",
|
||||
" <li>The probability of heads $p_h$ can be adjusted between 0 and\n",
|
||||
" 1 using the slider.\n",
|
||||
" </ul>\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"setup_text = \\\n",
|
||||
" r\"\"\"\n",
|
||||
" Select the maximum number of trials possible. The calculations will\n",
|
||||
" simply stop if you try to go higher.\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
"initial_text = \\\n",
|
||||
" r\"\"\"\n",
|
||||
" The graph shows three posteriors that result from three choices for\n",
|
||||
" the prior (set under the \"Priors\" tab) for the number of coin\n",
|
||||
" tosses and observed heads shown at the upper left. The true probability\n",
|
||||
" of a heads, $p_h$, is indicated by a dashed vertical line.\n",
|
||||
" Press \"Next\" to make observations, \"Reset\" to go back to zero.\n",
|
||||
" \"\"\"\n",
|
||||
"initial_text_w = HTMLMath(value=initial_text)\n",
|
||||
"\n",
|
||||
"priors_text = \\\n",
|
||||
" r\"\"\"\n",
|
||||
" Hyperparameters for several different priors (all beta distributions).\n",
|
||||
" Default prior 1 ($\\alpha_1 = 1$, $\\beta_1 = 1$) is uniform in [0,1].\n",
|
||||
" Default prior 2 ($\\alpha_2 = 30$, $\\beta_2 = 30$) is concentrated \n",
|
||||
" near 0.5 with very small tails.\n",
|
||||
" Defalt prior 3 ($\\alpha_3 = .2$, $\\beta_3 = .2$) is peaked at the ends, \n",
|
||||
" but allows for probability everywhere.\n",
|
||||
" \"\"\"\n",
|
||||
"priors_text_w = HTMLMath(value=priors_text)\n",
|
||||
"################### end: text for help tabs ##################\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" \n",
|
||||
" \n",
|
||||
"################### begin: definitions of widgets ##################\n",
|
||||
"recalculate_data_w = Checkbox(value=True) \n",
|
||||
"prob_heads_w = FloatSlider(value=prob_heads, min=0., max=1., step=0.05,\n",
|
||||
" description=r'true $p_h$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"n_trials_max_w = IntSlider(value=n_trials_max, min=100, max=10000, step=100,\n",
|
||||
" description='max # trials:',\n",
|
||||
" continuous_update=False)\n",
|
||||
" \n",
|
||||
"N_w = IntSlider(value=0, min=0, max=n_trials_max, step=1,\n",
|
||||
" continuous_update=False)\n",
|
||||
"next_button_w = Button(description='Next', disabled=False,\n",
|
||||
" layout=Layout(width='80px'), button_style='', \n",
|
||||
" tooltip='Increment number of trials by jump')\n",
|
||||
"reset_button_w = Button(description='Reset', disabled=False,\n",
|
||||
" layout=Layout(width='80px'), button_style='', \n",
|
||||
" tooltip='Reset number of trials to zero')\n",
|
||||
"\n",
|
||||
"jump_w = Dropdown(description='Jump:',\n",
|
||||
" layout=Layout(width='150px'),\n",
|
||||
" options=['1', '10', '100', '1000'],\n",
|
||||
" value='1',\n",
|
||||
" continuos_update=False,\n",
|
||||
" disabled=False,)\n",
|
||||
"\n",
|
||||
"alpha_1_w = FloatSlider(value=1., min=0., max=2., step=0.1,\n",
|
||||
" description=r'$\\alpha_1$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"alpha_1_w.style.handle_color = 'blue'\n",
|
||||
"\n",
|
||||
"alpha_2_w = FloatSlider(value=30., min=5., max=200., step=5.,\n",
|
||||
" description=r'$\\alpha_2$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"alpha_2_w.style.handle_color = 'red'\n",
|
||||
"alpha_3_w = FloatSlider(value=0.2, min=0., max=1., step=0.1,\n",
|
||||
" description=r'$\\alpha_3$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"alpha_3_w.style.handle_color = 'green'\n",
|
||||
"beta_1_w = FloatSlider(value=1., min=0.1, max=2., step=0.1,\n",
|
||||
" description=r'$\\beta_1$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"beta_1_w.style.handle_color = 'blue'\n",
|
||||
"beta_2_w = FloatSlider(value=30., min=5., max=200., step=5.,\n",
|
||||
" description=r'$\\beta_2$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"beta_2_w.style.handle_color = 'red'\n",
|
||||
"beta_3_w = FloatSlider(value=0.2, min=0., max=1., step=0.1,\n",
|
||||
" description=r'$\\beta_3$:',\n",
|
||||
" continuous_update=False)\n",
|
||||
"beta_3_w.style.handle_color = 'green'\n",
|
||||
"\n",
|
||||
"# Widgets for the help section, which are HTMLMath boxes in a Tab widget\n",
|
||||
"help_overview_w = HTMLMath(value=overview_text)\n",
|
||||
"help_Bayes_w = HTMLMath(value=Bayes_text)\n",
|
||||
"help_toss_coin_w = HTMLMath(value=toss_coin_text)\n",
|
||||
"help_priors_w = HTMLMath(value=priors_text)\n",
|
||||
"help_setup_w = HTMLMath(value=setup_text)\n",
|
||||
"\n",
|
||||
"################### end: definitions of widgets ##################\n",
|
||||
"\n",
|
||||
"################### begin: explicit widget callbacks ##################\n",
|
||||
"def update_N(b):\n",
|
||||
" \"\"\"Increment the number of trials N by the Jump value\"\"\"\n",
|
||||
" N_w.value += int(jump_w.value)\n",
|
||||
" \n",
|
||||
"def reset_N(b):\n",
|
||||
" \"\"\"Reset the number of trials N to zero\"\"\"\n",
|
||||
" N_w.value = 0\n",
|
||||
" \n",
|
||||
"def update_prob_heads(b):\n",
|
||||
" \"\"\"Change the value of prob_heads and regenerate data.\"\"\"\n",
|
||||
" recalculate_data_w.value = True\n",
|
||||
" N_w.max = n_trials_max_w.value\n",
|
||||
"\n",
|
||||
"next_button_w.on_click(update_N)\n",
|
||||
"reset_button_w.on_click(reset_N)\n",
|
||||
" \n",
|
||||
"prob_heads_w.observe(update_prob_heads, 'value') \n",
|
||||
"n_trials_max_w.observe(update_prob_heads, 'value') \n",
|
||||
"\n",
|
||||
"################### end: explicit widget callbacks ##################\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Organize the help as Tabs (which will be itself under the Help Tab)\n",
|
||||
"help_max_height = '500px'\n",
|
||||
"help_tab = Tab(children=[help_overview_w, help_Bayes_w, help_toss_coin_w, \n",
|
||||
" help_priors_w, help_setup_w], \n",
|
||||
" layout=Layout(width='95%', max_height=help_max_height))\n",
|
||||
"help_tab.set_title(0, 'Overview')\n",
|
||||
"help_tab.set_title(1, 'Bayes Theorem')\n",
|
||||
"help_tab.set_title(2, 'Toss Coin')\n",
|
||||
"help_tab.set_title(3, 'Priors')\n",
|
||||
"help_tab.set_title(4, 'Set-up')\n",
|
||||
" \n",
|
||||
"# Boxes of widgets that will go into the top-level tabs\n",
|
||||
"textbox0 = HBox([initial_text_w])\n",
|
||||
"hbox0 = HBox([next_button_w, jump_w, reset_button_w, prob_heads_w])\n",
|
||||
"textbox1 = HBox([priors_text_w])\n",
|
||||
"hbox1a = HBox([alpha_1_w, alpha_2_w, alpha_3_w])\n",
|
||||
"hbox1b = HBox([beta_1_w, beta_2_w, beta_3_w])\n",
|
||||
"hbox2 = HBox([n_trials_max_w])\n",
|
||||
"hbox3 = HBox([help_tab])\n",
|
||||
"\n",
|
||||
"# We'll set up Tabs to organize the controls. The Tab contents are declared\n",
|
||||
"# as tab0, tab1, ... (probably should make this a list) and the overall Tab\n",
|
||||
"# is called tab (so its children are tab0, tab1, ...).\n",
|
||||
"tab_height = '70px' # Fixed minimum height for all tabs. Specify another way?\n",
|
||||
"tab0 = VBox([textbox0, hbox0], layout=Layout(min_height=tab_height))\n",
|
||||
"tab1 = VBox([textbox1, hbox1a, hbox1b], layout=Layout(min_height=tab_height))\n",
|
||||
"tab2 = VBox([hbox2], layout=Layout(min_height=tab_height))\n",
|
||||
"tab3 = VBox([hbox3], layout=Layout(min_height=tab_height))\n",
|
||||
"\n",
|
||||
"tab = Tab(children=[tab0, tab1, tab2, tab3])\n",
|
||||
"tab.set_title(0, 'Toss Coin')\n",
|
||||
"tab.set_title(1, 'Priors')\n",
|
||||
"tab.set_title(2, 'Set-up')\n",
|
||||
"tab.set_title(3, 'Help')\n",
|
||||
"\n",
|
||||
"plot_out = widgets.interactive_output(update_plot,\n",
|
||||
" dict(\n",
|
||||
" N=N_w,\n",
|
||||
" jump=jump_w,\n",
|
||||
" recalculate_data=recalculate_data_w,\n",
|
||||
" prob_heads=prob_heads_w,\n",
|
||||
" n_trials_max=n_trials_max_w,\n",
|
||||
" alpha_1=alpha_1_w, beta_1=beta_1_w,\n",
|
||||
" alpha_2=alpha_2_w, beta_2=beta_2_w,\n",
|
||||
" alpha_3=alpha_3_w, beta_3=beta_3_w,\n",
|
||||
" )\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"UI_box = VBox([tab, plot_out]);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "b9da5467093dc4eeb39025b393179ea9",
|
||||
"grade": false,
|
||||
"grade_id": "cell-a1fc76cad29d324e",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"#### User-interface for coin-flipping \n",
|
||||
"\n",
|
||||
"Take a look at the information under the `Help` tab to find out about what the controls do, what the priors are, etc. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "99d9d53aff8a703be280467ce78bbf82",
|
||||
"grade": false,
|
||||
"grade_id": "cell-0f08b3f96e873a87",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"display(UI_box);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "b29383ee67d53b63c4cbb69abe47af98",
|
||||
"grade": false,
|
||||
"grade_id": "cell-9fa43fdc4a161ce2",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"Questions and tasks relating to priors and dealing with uncertainty: \n",
|
||||
"* *What prior would you choose? How does this affect how long it takes you to arrive at the correct conclusion?* Note that the answer to this question may be $p_H$ dependent.\n",
|
||||
"* *What would your standard be for deciding the coin was so unfair that you would walk away? That you'd call the police? That you'd try and publish the fact that you found an unfair coin in a scientific journal?* Hint: for the last one try thinking in terms of a \"p value\". If you don't know what that mean google \"hypothesis testing\".\n",
|
||||
"* *What if you were **sure** the coin was unfair before you started? (E.g. you saw the person doctoring it.) What prior would you choose then? What happens to the posterior in this case?* This one may be best answered without any hitting of shift-return.....\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "c36a35795f81d0b713eb41195a27dcfe",
|
||||
"grade": false,
|
||||
"grade_id": "cell-6481ce022b1d1783",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Q1 With the informative prior and no coin tosses, what is the mode of the posterior distribution? Put this in the variable `posterior_informative_0_0`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "21d73d3e155ed22a4c467afbd07c8b72",
|
||||
"grade": false,
|
||||
"grade_id": "cell-998c8286b5041f52",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "062137cf6cecb5065a2ed78fb13669c1",
|
||||
"grade": true,
|
||||
"grade_id": "cell-11199ecf37da5d78",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This is a test of the above, do not change this code.\n",
|
||||
"assert ads_hash(int(np.round(posterior_informative_0_0*1000)))=='0604cd3138'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "08a9885dade942dbc73d994acbb3541c",
|
||||
"grade": false,
|
||||
"grade_id": "cell-8c2f2035bb2dc08d",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Q2 After one toss but 0 heads and with a uniform prior distribution, what is the mode of the posterior distribution?\n",
|
||||
"\n",
|
||||
"Put this in the variable `uniform_informative_0_1`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "5187bbe185d9286aca9e797df50fc956",
|
||||
"grade": false,
|
||||
"grade_id": "cell-6f48bd0fc37a2c47",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "d11e74c40fbbcb325a0ed85e23a2fe48",
|
||||
"grade": true,
|
||||
"grade_id": "cell-ae2d2a33c719a214",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This is a test of the above, do not change this code.\n",
|
||||
"assert ads_hash(int(np.round(uniform_informative_0_1*1000)))=='5feceb66ff'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "5e0f03f057c975d6851b32a5546322ba",
|
||||
"grade": false,
|
||||
"grade_id": "cell-c716c72bac26cd85",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Q3 After one toss but 0 heads and with the \"anti\" prior distribution, what is the mode of the posterior distribution?\n",
|
||||
"\n",
|
||||
"Put this in the variable `anti_informative_0_1`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "649ebce89cea73418a2b352c47c16f4f",
|
||||
"grade": false,
|
||||
"grade_id": "cell-169a6bd947a7285e",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "3c7d52214605fe66a0a6f01124d84661",
|
||||
"grade": true,
|
||||
"grade_id": "cell-9eb8a9dbc2f2b809",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This is a test of the above, do not change this code.\n",
|
||||
"assert ads_hash(int(np.round(anti_informative_0_1*1000))-42)=='fec80006df'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "6a37b994d6eefa0e0cdc237e728994ef",
|
||||
"grade": false,
|
||||
"grade_id": "cell-bad4ca51b288966b",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Q4 How many tosses does it take for the posterior distributions to be approximately centered around the true value of $p_h$ for all prior distributions?\n",
|
||||
"\n",
|
||||
"Put this into the variable `n_to_converge`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "76c8e0cbfe5575221e2caa0216e2619d",
|
||||
"grade": true,
|
||||
"grade_id": "cell-a48da985862a2d34",
|
||||
"locked": false,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
|
@ -0,0 +1,880 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "6c0d0187eb229d0e2e1ba0158281b58b",
|
||||
"grade": false,
|
||||
"grade_id": "cell-2d19f0af5c5a585e",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# You must run this cell, but you can ignore its contents.\n",
|
||||
"\n",
|
||||
"import hashlib\n",
|
||||
"\n",
|
||||
"def ads_hash(ty):\n",
|
||||
" \"\"\"Return a unique string for input\"\"\"\n",
|
||||
" ty_str = str(ty).encode()\n",
|
||||
" m = hashlib.sha256()\n",
|
||||
" m.update(ty_str)\n",
|
||||
" return m.hexdigest()[:10]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "e6a2d44fd134a7ce5a461a752d6be4fa",
|
||||
"grade": false,
|
||||
"grade_id": "cell-75699939c3ce2503",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "342402564abf6b2c2bfcab3cc7378746",
|
||||
"grade": false,
|
||||
"grade_id": "cell-5d4bc0aa520da66e",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
" ## Disease diagnosis with Bayes' theorem\n",
|
||||
"\n",
|
||||
"Let's say that you know the prevalence of a disease (it could be a viral infection with SARS-CoV-2 or COVID-19) is 1% in a population of people. We have a test for the virus, which, given a person has the disease, will have a positive result 90% of the time. This is called the *true positive rate* (*TPR*), or *sensitivity*, of a test (and also called *recall* and *hit rate* in machine learning contexts). Unfortunately the test also gives a false positive (a positive result with no disease) 5% of the time. This is called the *false positive rate* (*FPR*). (The *specificity* of a test is `1-FPR`, so this test would have a 95% specificity.)\n",
|
||||
"\n",
|
||||
"See the [Wikipedia page on Sensitivity and specificity](https://en.wikipedia.org/wiki/Sensitivity_and_specificity) for more details about the definitions of these names and the relations between them.\n",
|
||||
"\n",
|
||||
"It is standard practice to report sensitivity and specificity when characterizing a test. For example, the European Commission published [this list of SARS-CoV-2 antigen rapid tests](https://health.ec.europa.eu/system/files/2022-12/covid-19_eu-common-list-antigen-tests_en_0.pdf).\n",
|
||||
"\n",
|
||||
"We are going to work through the probability that a person in this population has the disease given a positive test result. We will write a positive test result as $\\rm{T}$. So, mathematically, we want to solve for $P(\\rm{disease}|\\rm{T})$. We will use Bayes' theorem to calculate this.\n",
|
||||
"\n",
|
||||
"Remember that Bayes' theorem is\n",
|
||||
"\n",
|
||||
"$P(A|B)=\\frac{P(B|A)P(A)}{P(B)}$\n",
|
||||
"\n",
|
||||
"Let's use variable names suited for our problem here. `A` will be `disease`, `B` will be `T` which means positive test result. So, rewriting Bayes' theorem with these new names, we have:\n",
|
||||
"\n",
|
||||
"$P(\\rm{disease}|\\rm{T})=\\frac{P(\\rm{T}|\\rm{disease})P(\\rm{disease})}{P(\\rm{T})}$\n",
|
||||
"\n",
|
||||
"In Bayesian terms, we can understand this as follows. Our *prior* belief is $P(\\rm{disease})$. This is our belief about the chances of having the disease prior to knowing the test results, and we take the population prevalence as our prior for this individual. We want to update our beliefs to compute our *posterior* belief $P(\\rm{disease}|\\rm{T})$. In other words, we want to update our belief of disease probability state given a positive test result. In Bayesian terms, our *likelhood function* is $P(\\rm{T}|\\rm{disease})$. In words, this is the chance of a positive test result given the presence of the disease. As discussed above, this is the test sensitivity, or true positive rate (TPR).\n",
|
||||
"\n",
|
||||
"Below, you will need to make use of the fact that the probability of a positive result is the sum of the true and false positive probabilities:\n",
|
||||
"\n",
|
||||
"$P(\\rm{T})=P(\\rm{T}|\\rm{disease})P(\\rm{disease}) + P(\\rm{T}|\\rm{healthy})P(\\rm{healthy})$\n",
|
||||
"\n",
|
||||
"$P(\\rm{T}) = (\\rm{true\\;positive\\;rate})P(\\rm{disease}) + (\\rm{false\\;positive\\;rate})P(\\rm{healthy}) = (TPR)P(\\rm{disease}) + (FPR)P(\\rm{healthy})$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "1203d40fb1ec0ec0366a3a8ccef3a090",
|
||||
"grade": false,
|
||||
"grade_id": "cell-8a9f79b7a6d31d5d",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q1 Given the disease, what is the probability of obtaining a positive result with this test?\n",
|
||||
"\n",
|
||||
"Mathematically, we write this as `P(T|disease)`. As described above, this is the *sensitivity* of a test, also called the *true positive rate* (*TPR*).\n",
|
||||
"\n",
|
||||
"Put your answer in the variable `prob_positive_given_disease`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "eb9b195a47f1b9895169077220b60f38",
|
||||
"grade": false,
|
||||
"grade_id": "cell-bd5795e644219a5f",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "c5bdd2f91509d3ef1bb6e5363c1f8cc8",
|
||||
"grade": true,
|
||||
"grade_id": "cell-794f6ea4cc254f13",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert ads_hash(int(np.round(prob_positive_given_disease*1000)))=='bdc5d8a48c'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "453d4f0a08acd28c2c8058e3edfdba20",
|
||||
"grade": false,
|
||||
"grade_id": "cell-0358735cabc9c677",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q2 What is the probability of having the disease in the population?\n",
|
||||
"\n",
|
||||
"Mathematically, we write this as `P(disease)`.\n",
|
||||
"\n",
|
||||
"Put your answer in the variable `prob_disease`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "92591a94781f72590c4f0b396208e26e",
|
||||
"grade": false,
|
||||
"grade_id": "cell-14c9780bc2381875",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "7b706052339ea83c2cf0fcb04ecf575e",
|
||||
"grade": true,
|
||||
"grade_id": "cell-1458d1dd7685458a",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert ads_hash(int(np.round(prob_disease*1000)))=='4a44dc1536'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "299aeac1ae4308ac21e25443a0eb5bcb",
|
||||
"grade": false,
|
||||
"grade_id": "cell-37ba1ce7923155cb",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q3 What is the probability of obtaining a positive result *in this population* due to actual disease?\n",
|
||||
"\n",
|
||||
"(This is the probability of a positive result given the disease and the probability of the disease.)\n",
|
||||
"\n",
|
||||
"Mathematically, this would be written as `P(T|disease)*P(disease)`.\n",
|
||||
"\n",
|
||||
"Put your answer in the variable `prob_pos_disease`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "1d5f2d8f47f44a3b4968c515321d9e81",
|
||||
"grade": false,
|
||||
"grade_id": "cell-a2795deffa3c89c7",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "d70ee2671fd2b335ae2fcc3a81c6de73",
|
||||
"grade": true,
|
||||
"grade_id": "cell-667a1db97c8f798e",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert ads_hash(int(np.round(prob_pos_disease*1000)))=='19581e27de'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "1e9e1685219652bc0cc104adaa2c4cfa",
|
||||
"grade": false,
|
||||
"grade_id": "cell-e060e20a197869ac",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q4 What is the prevalence of healthy (no disease) people in the population?\n",
|
||||
"\n",
|
||||
"In our model, a person is either healthy or has the disease. Thus, `P(healthy) + P(disease) = 1`. Based on this, `P(healthy) = 1-P(disease)`.\n",
|
||||
"\n",
|
||||
"Mathematically, we want to know `P(healthy)`.\n",
|
||||
"\n",
|
||||
"Put your answer in the variable `prob_healthy`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "3ef0951ee47f1405d24c143346737d13",
|
||||
"grade": false,
|
||||
"grade_id": "cell-c51a246f7cbdf86a",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "1f9a8c570afda57f499939465823f450",
|
||||
"grade": true,
|
||||
"grade_id": "cell-0899b61c455701f1",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert ads_hash(int(np.round(prob_healthy*1000)))=='fe50b64954'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "9946ddf12d9a7778e4230a35f068e8d8",
|
||||
"grade": false,
|
||||
"grade_id": "cell-bfee709770a2f9e4",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q5 What is the probability of obtaining a positive result in this population due to false positive?\n",
|
||||
"\n",
|
||||
"(This is the probability of a - false - positive result given no disease and the probability being healthy.)\n",
|
||||
"\n",
|
||||
"Mathematically, we write this as `P(T|healthy)*P(healthy)`.\n",
|
||||
"\n",
|
||||
"Put your answer in the variable `prob_pos_healthy`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "4088f687038ffcd4aae0ddf59f521250",
|
||||
"grade": false,
|
||||
"grade_id": "cell-e499af19d0992d30",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "93ce775768a60fbe3f609c62ff3ba94b",
|
||||
"grade": true,
|
||||
"grade_id": "cell-afd9c756a3c77813",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert ads_hash(int(np.round(prob_pos_healthy*1000)))=='1a6562590e'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "7effb410c4bf5f38a283781b0cfddb23",
|
||||
"grade": false,
|
||||
"grade_id": "cell-c91b0aa17e5d9752",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q6 What is the probability of obtaining a positive result in this population?\n",
|
||||
"\n",
|
||||
"(This is the probability of obtaining a positive result, no matter the underlying disease or healthy state. Therefore, it is the sum of the probability of a postive result for all possible states.)\n",
|
||||
"\n",
|
||||
"Mathemetically, this would be `P(T) = P(T|disease)*P(disease) + P(T|healthy)*P(healthy)`.\n",
|
||||
"\n",
|
||||
"Put your answer in the variable `prob_positive`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "f68f4ee388785186a875106b737eb956",
|
||||
"grade": false,
|
||||
"grade_id": "cell-f21ea6c9a3bff85a",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "605f848a978b60026dbbe2d5019e7055",
|
||||
"grade": true,
|
||||
"grade_id": "cell-b0648a81e8391d34",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assert ads_hash(int(np.round(prob_positive*1000))) == '6208ef0f77'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "e2cb82d7534f304106ff60305cd57374",
|
||||
"grade": false,
|
||||
"grade_id": "cell-1905d16b125a46d3",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q7 Given a positive result, what is the probability of having the disease?\n",
|
||||
"\n",
|
||||
"Finally, here is where we use Bayes' theorem to tell us how likely is it that there is disease given a positive result.\n",
|
||||
"\n",
|
||||
"`P(disease|T)=P(T|disease)*P(disease)/P(T)`\n",
|
||||
"\n",
|
||||
"Put the result in the variable `prob_disease_given_positive`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "d72b76dda71e359824f48b2e4f47a4f9",
|
||||
"grade": false,
|
||||
"grade_id": "cell-a0cc2998aca0717b",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "bd810979c72203397f4a39cb3f1f63a3",
|
||||
"grade": true,
|
||||
"grade_id": "cell-91fcc1b6c157fce2",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"print(prob_disease_given_positive)\n",
|
||||
"assert ads_hash(int(np.round(prob_disease_given_positive*1000)))=='1d0ebea552'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "4d12c8c2e19b64cb749d554e96e2ea40",
|
||||
"grade": false,
|
||||
"grade_id": "cell-be559c154ea45ba3",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Conclusion\n",
|
||||
"\n",
|
||||
"Perhaps surprisingly, in a low prevalence of disease (1%), a positive result from test with sensitivity of 90% and specificity of 95% indicates only an approximately 15% chance that the person has the disease.\n",
|
||||
"\n",
|
||||
"**Real world note:** this analysis was done assuming the test was administered randomly and not, for example, on whether the person was experiencing symptoms or had another reason to believe they may have the disease. These additional factors would need to be included to make predictions about such a situation."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "bb7c4ed86a59168711fad4ac408987ae",
|
||||
"grade": false,
|
||||
"grade_id": "cell-9ca150f6b141fc98",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Extra credit\n",
|
||||
"\n",
|
||||
"Now assume a second *independent* test is done. What would the chance be that a person has the disease after two independent positive results? Work out the steps. The correct result is about 77%.\n",
|
||||
"\n",
|
||||
"(It is important that the tests are independent because errors with one should not influence errors with the other.)\n",
|
||||
"\n",
|
||||
"Here we use $\\rm{TT}$ to indicate two positive test results. This is the probability of a first positive result and a second positive result, so the probability of a single positive result times the probability of a single positive result.\n",
|
||||
"\n",
|
||||
"$P(\\rm{disease}|\\rm{TT})=\\frac{P(\\rm{TT}|\\rm{disease})P(\\rm{disease})}{P(\\rm{TT})}$\n",
|
||||
"\n",
|
||||
"Remember using basic probability logic:\n",
|
||||
"\n",
|
||||
"$P(\\rm{positive\\;result})=P(\\rm{true\\;positive})P(\\rm{disease}) + P(\\rm{false\\;positive})P(\\rm{healthy})$\n",
|
||||
"\n",
|
||||
"We can work out the following relation for $P(\\rm{TT})$, the probability of two positive test results.\n",
|
||||
"\n",
|
||||
"Keep in mind the following relations:\n",
|
||||
"\n",
|
||||
"$P(\\rm{TT}) = P(\\rm{TT}|\\rm{disease})P(\\rm{disease}) + P(\\rm{TT}|\\rm{healthy})P(\\rm{healthy})$\n",
|
||||
"\n",
|
||||
"Also:\n",
|
||||
"\n",
|
||||
"$P(\\rm{TT}|\\rm{disease}) = P(\\rm{positive\\;result}|\\rm{disease})P(\\rm{positive\\;result}|\\rm{disease}) = P(\\rm{positive\\;result}|\\rm{disease})^2$\n",
|
||||
"\n",
|
||||
"**Real world note:** a second independent test would need to test something different and perhaps be performed at a separate time and perhaps place by a seperate tester to acheive true independence. This is because an antigen test, for example, may give a false positive due to another cause - say presense of a rare but unrelated bacteria strain. Thus, using the same test again may again result in another positive for the same reason and is thus not truly independent."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "7e9783da7359bcdef1b247fd1c70f258",
|
||||
"grade": true,
|
||||
"grade_id": "cell-abdcc7bbaea9194d",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "3f874010e2f1b47124bb7d8242221228",
|
||||
"grade": true,
|
||||
"grade_id": "cell-0250d322805d7fd7",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "a057b18a8d70b5c2f13980d706d70aa1",
|
||||
"grade": true,
|
||||
"grade_id": "cell-7986416dfa056d9a",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "ee67ce04eafdfbd35a2a73838e36a891",
|
||||
"grade": true,
|
||||
"grade_id": "cell-fb540ee826540863",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "bffc5c71257454cf4d89e73d205cc41f",
|
||||
"grade": true,
|
||||
"grade_id": "cell-c1e4844321baf0be",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "40c2f8d1203d8b218c37cfc8cfcd327b",
|
||||
"grade": true,
|
||||
"grade_id": "cell-4e87df82fd6b4259",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "188ad324bdf444dccb520b32fb8ad02a",
|
||||
"grade": true,
|
||||
"grade_id": "cell-636758ec522a9a91",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "7d6f0915a558825df33a5ea48cbaef4a",
|
||||
"grade": true,
|
||||
"grade_id": "cell-ff65799f1a88e304",
|
||||
"locked": false,
|
||||
"points": 0,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
384
exercises/release/exercise-12/3__Monty_Hall_problem.ipynb
Normal file
384
exercises/release/exercise-12/3__Monty_Hall_problem.ipynb
Normal file
|
@ -0,0 +1,384 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "f3bfc18d7d3126bb2bc86f70298b0eca",
|
||||
"grade": false,
|
||||
"grade_id": "cell-25e346adccbfbbd1",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"# The Monty Hall problem (Deutsch: Ziegenproblem)\n",
|
||||
"\n",
|
||||
"Read about it [on Wikipedia](https://en.wikipedia.org/wiki/Monty_Hall_problem) or [in German as the Ziegenproblem](https://de.wikipedia.org/wiki/Ziegenproblem) and come back. I'll wait.\n",
|
||||
"\n",
|
||||
"In this notebook, you will write a program to simulated the Monty Hall problem.\n",
|
||||
"\n",
|
||||
"We are going to make extensive use of the function `random.randint(a, b)`. From its docstring, it returns a `random integer in range [a, b], including both end points.`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "aaf57ca23f25194de3aed50f5671d7f9",
|
||||
"grade": false,
|
||||
"grade_id": "cell-b19b617da52a3bc6",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import random"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "5080a90ced63235419068f94c7ff0a1f",
|
||||
"grade": false,
|
||||
"grade_id": "cell-8d3e7b29ddec3069",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"for i in range(10):\n",
|
||||
" print(random.randint(0,2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "3eeedae0c60f10a8521a250c65e21e19",
|
||||
"grade": false,
|
||||
"grade_id": "cell-474fcacf28983b26",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Q1\n",
|
||||
"\n",
|
||||
"For your first task, create a function called `sample_not` which takes two positional arguments (call them `not1` and `not2`) and will return a random integer between 0 and 2 (endpoints included) but which is not either of the arguments. The positional arguments will always be integers between 0 and 2 (inclusive)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "9797d3745174cd03506e52e2599c87b1",
|
||||
"grade": false,
|
||||
"grade_id": "cell-f0ca4e3187e53217",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "c31b214732c7f43f93e8308cfe9403e4",
|
||||
"grade": true,
|
||||
"grade_id": "cell-50feeabd1f4f7d07",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This is a test of the above, do not change this code.\n",
|
||||
"assert sample_not(0,1)==2\n",
|
||||
"assert sample_not(0,2)==1\n",
|
||||
"assert sample_not(1,0)==2\n",
|
||||
"assert sample_not(1,2)==0\n",
|
||||
"assert sample_not(2,0)==1\n",
|
||||
"assert sample_not(2,1)==0\n",
|
||||
"assert sample_not(0,1)==2\n",
|
||||
"assert sample_not(0,0) in (1,2)\n",
|
||||
"assert sample_not(1,1) in (0,2)\n",
|
||||
"assert sample_not(2,2) in (0,1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "bece62fea06aaeb9d022fcd6e0a23032",
|
||||
"grade": false,
|
||||
"grade_id": "cell-8fdbeafabef55703",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"### Q2\n",
|
||||
"\n",
|
||||
"For your next task, consider the following code:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"\n",
|
||||
"# generate what is behind the doors\n",
|
||||
"doors = ['goat', 'goat', 'goat']\n",
|
||||
"car_door = random.randint(0,2)\n",
|
||||
"doors[car_door] = 'car'\n",
|
||||
"\n",
|
||||
"# Now, the guest makes a first guess.\n",
|
||||
"guess1 = random.randint(0,2)\n",
|
||||
"\n",
|
||||
"# Now, the host opens a door, which is not the guess or the car.\n",
|
||||
"host_open_door = sample_not(guess1,car_door)\n",
|
||||
"\n",
|
||||
"# Based on the variable `do_switch` (which is not set here), the guess will either make a new choice or stay with the original guess.\n",
|
||||
"if do_switch:\n",
|
||||
" guess2 = sample_not(guess1,host_open_door)\n",
|
||||
" final_guess = guess2\n",
|
||||
"else:\n",
|
||||
" final_guess = guess1\n",
|
||||
"\n",
|
||||
"# Finally, determine what was behind the door for the final guess.\n",
|
||||
"result = doors[final_guess]\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Put this code in a function called `run_game` which takes a single argument, `do_switch`, and returns a boolean, indicating a win with `True` or a loss with `False`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "7db500d5fbe4e3b7b017452c31d07cb2",
|
||||
"grade": false,
|
||||
"grade_id": "cell-c087e3c1a6e2d2dd",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "36aefb4d0a8ad8dbeeeac485d2bd9afe",
|
||||
"grade": true,
|
||||
"grade_id": "cell-a3750cd0c13cf6c0",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This is a test of the above, do not change this code.\n",
|
||||
"count = 300\n",
|
||||
"for do_switch in (True, False):\n",
|
||||
" wins = 0\n",
|
||||
" for i in range(count):\n",
|
||||
" this_run_win = run_game(do_switch)\n",
|
||||
" assert(type(this_run_win)==bool)\n",
|
||||
" wins += int(this_run_win)\n",
|
||||
" print('do_switch: %s, wins: %d, count: %d'%(do_switch, wins, count))\n",
|
||||
" if do_switch:\n",
|
||||
" assert abs(wins/count - 2/3) < 0.1\n",
|
||||
" else:\n",
|
||||
" assert abs(wins/count - 1/3) < 0.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "1d2182a4b2f5530d0df89019ed8f524e",
|
||||
"grade": false,
|
||||
"grade_id": "cell-5626ba67e0f6f701",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"Note the above results. You have numerically simulated the Monty Hall problem."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "markdown",
|
||||
"checksum": "8448c5d8a31c617b3e8889a0f066412d",
|
||||
"grade": false,
|
||||
"grade_id": "cell-054774247e7bc87a",
|
||||
"locked": true,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
},
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"## Q3\n",
|
||||
"\n",
|
||||
"Make a new game where there are 100 doors and the host opens 98 of them after the initial guess. Make a new function called `run_game_100`, and any other functions you need, which plays a single round of this game. Again, this function should take an argument `do_switch`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "507b4cfa66e9812169df2e7e6f19d787",
|
||||
"grade": false,
|
||||
"grade_id": "cell-718f81e609214623",
|
||||
"locked": false,
|
||||
"schema_version": 3,
|
||||
"solution": true,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# YOUR CODE HERE\n",
|
||||
"raise NotImplementedError()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"deletable": false,
|
||||
"editable": false,
|
||||
"nbgrader": {
|
||||
"cell_type": "code",
|
||||
"checksum": "02dd189fb97c5291858f05eb56d3e022",
|
||||
"grade": true,
|
||||
"grade_id": "cell-0b76bb5440f73c22",
|
||||
"locked": true,
|
||||
"points": 1,
|
||||
"schema_version": 3,
|
||||
"solution": false,
|
||||
"task": false
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This is a test of the above, do not change this code.\n",
|
||||
"count = 1000\n",
|
||||
"for do_switch in (True, False):\n",
|
||||
" wins = 0\n",
|
||||
" for i in range(count):\n",
|
||||
" this_run_win = run_game_100(do_switch)\n",
|
||||
" assert(type(this_run_win)==bool)\n",
|
||||
" wins += int(this_run_win)\n",
|
||||
" print('do_switch: %s, wins: %d, count: %d'%(do_switch, wins, count))\n",
|
||||
" if do_switch:\n",
|
||||
" assert abs(wins/count - 0.99) < 0.02\n",
|
||||
" else:\n",
|
||||
" assert abs(wins/count - 0.01) < 0.02"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.10"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
Loading…
Reference in a new issue