{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Exercise 5.3: Bootstrapping \"theory\" with hacker stats\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Say we have a data set with $n$ unique measurements. It can be shown that on average a fraction of $(1-1/n)^n$ of the measurements do not appear in a bootstrap sample. Note that for large samples, this is approximately $1/e \\approx 1/2.7$, since\n", "\n", "\\begin{align}\n", "\\lim_{n\\to\\infty} (1-1/n)^n = 1/e.\n", "\\end{align}\n", "\n", "Use hacker stats to show that this is, indeed true. *Hint*: Think about a convenient \"data set\" to use for drawing samples.\n", "\n", "This is kind of fun; you're investigating some theory behind hacker stats *with hacker stats*!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " \n", " Loading BokehJS ...\n", "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "\n", "(function(root) {\n", " function now() {\n", " return new Date();\n", " }\n", "\n", " const force = true;\n", "\n", " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", " root._bokeh_onload_callbacks = [];\n", " root._bokeh_is_loading = undefined;\n", " }\n", "\n", " const JS_MIME_TYPE = 'application/javascript';\n", " const HTML_MIME_TYPE = 'text/html';\n", " const EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", " const CLASS_NAME = 'output_bokeh rendered_html';\n", "\n", " /**\n", " * Render data to the DOM node\n", " */\n", " function render(props, node) {\n", " const script = document.createElement(\"script\");\n", " node.appendChild(script);\n", " }\n", "\n", " /**\n", " * Handle when an output is cleared or removed\n", " */\n", " function handleClearOutput(event, handle) {\n", " const cell = handle.cell;\n", "\n", " const id = cell.output_area._bokeh_element_id;\n", " const server_id = cell.output_area._bokeh_server_id;\n", " // Clean up Bokeh references\n", " if (id != null && id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", "\n", " if (server_id !== undefined) {\n", " // Clean up Bokeh references\n", " const cmd_clean = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", " cell.notebook.kernel.execute(cmd_clean, {\n", " iopub: {\n", " output: function(msg) {\n", " const id = msg.content.text.trim();\n", " if (id in Bokeh.index) {\n", " Bokeh.index[id].model.document.clear();\n", " delete Bokeh.index[id];\n", " }\n", " }\n", " }\n", " });\n", " // Destroy server and session\n", " const cmd_destroy = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", " cell.notebook.kernel.execute(cmd_destroy);\n", " }\n", " }\n", "\n", " /**\n", " * Handle when a new output is added\n", " */\n", " function handleAddOutput(event, handle) {\n", " const output_area = handle.output_area;\n", " const output = handle.output;\n", "\n", " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", " if ((output.output_type != \"display_data\") || (!Object.prototype.hasOwnProperty.call(output.data, EXEC_MIME_TYPE))) {\n", " return\n", " }\n", "\n", " const toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", "\n", " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", " // store reference to embed id on output_area\n", " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", " }\n", " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", " const bk_div = document.createElement(\"div\");\n", " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", " const script_attrs = bk_div.children[0].attributes;\n", " for (let i = 0; i < script_attrs.length; i++) {\n", " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", " toinsert[toinsert.length - 1].firstChild.textContent = bk_div.children[0].textContent\n", " }\n", " // store reference to server id on output_area\n", " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", " }\n", " }\n", "\n", " function register_renderer(events, OutputArea) {\n", "\n", " function append_mime(data, metadata, element) {\n", " // create a DOM node to render to\n", " const toinsert = this.create_output_subarea(\n", " metadata,\n", " CLASS_NAME,\n", " EXEC_MIME_TYPE\n", " );\n", " this.keyboard_manager.register_events(toinsert);\n", " // Render to node\n", " const props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", " render(props, toinsert[toinsert.length - 1]);\n", " element.append(toinsert);\n", " return toinsert\n", " }\n", "\n", " /* Handle when an output is cleared or removed */\n", " events.on('clear_output.CodeCell', handleClearOutput);\n", " events.on('delete.Cell', handleClearOutput);\n", "\n", " /* Handle when a new output is added */\n", " events.on('output_added.OutputArea', handleAddOutput);\n", "\n", " /**\n", " * Register the mime type and append_mime function with output_area\n", " */\n", " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", " /* Is output safe? */\n", " safe: true,\n", " /* Index of renderer in `output_area.display_order` */\n", " index: 0\n", " });\n", " }\n", "\n", " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", " if (root.Jupyter !== undefined) {\n", " const events = require('base/js/events');\n", " const OutputArea = require('notebook/js/outputarea').OutputArea;\n", "\n", " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", " register_renderer(events, OutputArea);\n", " }\n", " }\n", "\n", " \n", " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", " root._bokeh_timeout = Date.now() + 5000;\n", " root._bokeh_failed_load = false;\n", " }\n", "\n", " const NB_LOAD_WARNING = {'data': {'text/html':\n", " \"
\\n\"+\n", " \"

\\n\"+\n", " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", " \"

\\n\"+\n", " \"\\n\"+\n", " \"\\n\"+\n", " \"from bokeh.resources import INLINE\\n\"+\n", " \"output_notebook(resources=INLINE)\\n\"+\n", " \"\\n\"+\n", " \"
\"}};\n", "\n", " function display_loaded() {\n", " const el = document.getElementById(\"1002\");\n", " if (el != null) {\n", " el.textContent = \"BokehJS is loading...\";\n", " }\n", " if (root.Bokeh !== undefined) {\n", " if (el != null) {\n", " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", " }\n", " } else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(display_loaded, 100)\n", " }\n", " }\n", "\n", "\n", " function run_callbacks() {\n", " try {\n", " root._bokeh_onload_callbacks.forEach(function(callback) {\n", " if (callback != null)\n", " callback();\n", " });\n", " } finally {\n", " delete root._bokeh_onload_callbacks\n", " }\n", " console.debug(\"Bokeh: all callbacks have finished\");\n", " }\n", "\n", " function load_libs(css_urls, js_urls, callback) {\n", " if (css_urls == null) css_urls = [];\n", " if (js_urls == null) js_urls = [];\n", "\n", " root._bokeh_onload_callbacks.push(callback);\n", " if (root._bokeh_is_loading > 0) {\n", " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", " return null;\n", " }\n", " if (js_urls == null || js_urls.length === 0) {\n", " run_callbacks();\n", " return null;\n", " }\n", " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", "\n", " function on_load() {\n", " root._bokeh_is_loading--;\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", " run_callbacks()\n", " }\n", " }\n", "\n", " function on_error(url) {\n", " console.error(\"failed to load \" + url);\n", " }\n", "\n", " for (let i = 0; i < css_urls.length; i++) {\n", " const url = css_urls[i];\n", " const element = document.createElement(\"link\");\n", " element.onload = on_load;\n", " element.onerror = on_error.bind(null, url);\n", " element.rel = \"stylesheet\";\n", " element.type = \"text/css\";\n", " element.href = url;\n", " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", " document.body.appendChild(element);\n", " }\n", "\n", " for (let i = 0; i < js_urls.length; i++) {\n", " const url = js_urls[i];\n", " const element = document.createElement('script');\n", " element.onload = on_load;\n", " element.onerror = on_error.bind(null, url);\n", " element.async = false;\n", " element.src = url;\n", " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", " document.head.appendChild(element);\n", " }\n", " };\n", "\n", " function inject_raw_css(css) {\n", " const element = document.createElement(\"style\");\n", " element.appendChild(document.createTextNode(css));\n", " document.body.appendChild(element);\n", " }\n", "\n", " \n", " const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js\"];\n", " const css_urls = [];\n", " \n", "\n", " const inline_js = [\n", " function(Bokeh) {\n", " Bokeh.set_log_level(\"info\");\n", " },\n", " function(Bokeh) {\n", " \n", " \n", " }\n", " ];\n", "\n", " function run_inline_js() {\n", " \n", " if (root.Bokeh !== undefined || force === true) {\n", " \n", " for (let i = 0; i < inline_js.length; i++) {\n", " inline_js[i].call(root, root.Bokeh);\n", " }\n", " if (force === true) {\n", " display_loaded();\n", " }} else if (Date.now() < root._bokeh_timeout) {\n", " setTimeout(run_inline_js, 100);\n", " } else if (!root._bokeh_failed_load) {\n", " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", " root._bokeh_failed_load = true;\n", " } else if (force !== true) {\n", " const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n", " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", " }\n", "\n", " }\n", "\n", " if (root._bokeh_is_loading === 0) {\n", " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", " run_inline_js();\n", " } else {\n", " load_libs(css_urls, js_urls, function() {\n", " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", " run_inline_js();\n", " });\n", " }\n", "}(window));" ], "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n const force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n const NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n const el = document.getElementById(\"1002\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error(url) {\n console.error(\"failed to load \" + url);\n }\n\n for (let i = 0; i < css_urls.length; i++) {\n const url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (let i = 0; i < js_urls.length; i++) {\n const url = js_urls[i];\n const element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error.bind(null, url);\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n \n const js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js\"];\n const css_urls = [];\n \n\n const inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {\n \n \n }\n ];\n\n function run_inline_js() {\n \n if (root.Bokeh !== undefined || force === true) {\n \n for (let i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }\n if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n const cell = $(document.getElementById(\"1002\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "\n", "import bokeh.io\n", "import bokeh.plotting\n", "\n", "bokeh.io.output_notebook()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will generate a data set that is just $n$ consecutive integers. Our statistic from our bootstrap sample is then\n", "\n", "\\begin{align}\n", "\\text{fraction omitted} = 1 - \\frac{\\text{number of unique entries in the bootstrap sample}}{n}.\n", "\\end{align}" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def frac_omitted(data):\n", " return 1 - len(np.unique(data)) / len(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will draw a few thousand bootstrap replicates of this for several values of $n$ and make a plot of the mean. To facilitate, we will use the `draw_bs_reps()` function we wrote in [Exercise 8.1](exercise_8.1.ipynb)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "rg = np.random.default_rng()\n", "\n", "def draw_bs_reps(data, func, rg, size=1, args=()):\n", " return np.array(\n", " [\n", " func(rg.choice(data, replace=True, size=len(data)), *args)\n", " for _ in range(size)\n", " ]\n", " )\n", "\n", "\n", "def mean_frac_omitted(n, n_bs_reps=10000):\n", " data = np.arange(n)\n", " bs_reps = draw_bs_reps(data, frac_omitted, rg, size=n_bs_reps)\n", "\n", " return np.mean(bs_reps)\n", "\n", "\n", "n = np.unique(np.logspace(0, 3).astype(int))\n", "mean_f = np.array([mean_frac_omitted(n_val) for n_val in n])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have the mean fraction omitted for each value of $n$, we can plot it, together with the theoretical curve." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "
\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/javascript": [ "(function(root) {\n", " function embed_document(root) {\n", " \n", " const docs_json = {\"d154ec69-61b2-4bb5-9b6c-628898c3ef65\":{\"defs\":[],\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1012\"}],\"center\":[{\"id\":\"1015\"},{\"id\":\"1019\"}],\"frame_height\":250,\"frame_width\":350,\"left\":[{\"id\":\"1016\"}],\"renderers\":[{\"id\":\"1038\"},{\"id\":\"1044\"},{\"id\":\"1050\"}],\"title\":{\"id\":\"1052\"},\"toolbar\":{\"id\":\"1027\"},\"x_range\":{\"id\":\"1004\"},\"x_scale\":{\"id\":\"1008\"},\"y_range\":{\"id\":\"1006\"},\"y_scale\":{\"id\":\"1010\"}},\"id\":\"1003\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{},\"id\":\"1056\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1025\",\"type\":\"HelpTool\"},{\"attributes\":{},\"id\":\"1060\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1064\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"end\":1100,\"start\":0.9},\"id\":\"1004\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"1024\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"1065\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1021\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1035\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1046\"}},\"id\":\"1051\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1061\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1055\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"LogScale\"},{\"attributes\":{\"tools\":[{\"id\":\"1020\"},{\"id\":\"1021\"},{\"id\":\"1022\"},{\"id\":\"1023\"},{\"id\":\"1024\"},{\"id\":\"1025\"}]},\"id\":\"1027\",\"type\":\"Toolbar\"},{\"attributes\":{\"fill_color\":{\"value\":\"orange\"},\"hatch_color\":{\"value\":\"orange\"},\"line_color\":{\"value\":\"orange\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1047\",\"type\":\"Circle\"},{\"attributes\":{\"axis_label\":\"mean fraction omitted\",\"coordinates\":null,\"formatter\":{\"id\":\"1055\"},\"group\":null,\"major_label_policy\":{\"id\":\"1056\"},\"ticker\":{\"id\":\"1017\"}},\"id\":\"1016\",\"type\":\"LinearAxis\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"gray\",\"line_dash\":[6],\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1043\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1020\",\"type\":\"PanTool\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"gray\",\"line_dash\":[6],\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1042\",\"type\":\"Line\"},{\"attributes\":{},\"id\":\"1063\",\"type\":\"Selection\"},{\"attributes\":{\"overlay\":{\"id\":\"1026\"}},\"id\":\"1022\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"1023\",\"type\":\"SaveTool\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1040\"},\"glyph\":{\"id\":\"1041\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1043\"},\"nonselection_glyph\":{\"id\":\"1042\"},\"view\":{\"id\":\"1045\"}},\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"num_minor_ticks\":10},\"id\":\"1013\",\"type\":\"LogTicker\"},{\"attributes\":{\"data\":{\"x\":[0.9,1100],\"y\":[0.36787944117144233,0.36787944117144233]},\"selected\":{\"id\":\"1063\"},\"selection_policy\":{\"id\":\"1062\"}},\"id\":\"1040\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data\":{\"x\":{\"__ndarray__\":\"AAAAAAAA8D932Hq0h0fwP7tw1jFPkPA/NHS2DVza8D8k8rX2syXxPzX71rRccvE/BDL0KVzA8T9eVzRSuA/yPxDbf0R3YPI/UXr4Mp+y8j/x9HJrNgbzP6Pi8ldDW/M/4LEof8yx8z8d2vGE2An0PxFL2ypuY/Q/KCOmUJS+9D87t870URv1P/j1FTWuefU/hDENT7DZ9T8GWqSgXzv2Pw60uqjDnvY/+hWyB+QD9z+KtwSAyGr3P0mf3fZ40/c/VLmzdP09+D+No+clXqr4PzA7ZFujGPk/PfhBi9WI+T8mI21R/fr5P5jxTnAjb/o/QJd50VDl+j/dV1eGjl37P/On3Mjl1/s/32k9/F9U/D8iVaWtBtP8PxmW85TjU/0/g7R5lQDX/T9xz72+Z1z+P5Q9QE0j5P4/EqFEqz1u/z9Gfp5xwfr/P5SyQLTcRABAp14qRJiNAEBqokX9mNcAQFIpP43kIgFAeHYmu4BvAUCLYt9nc70BQB+VlY7CDAJANAIyRXRdAkALddK8jq8CQFsxQ0IYAwNAVrR6PhdYA0Dmnhc3kq4DQNzS4M6PBgRA2cxHxhZgBEABRe37LbsEQI4gKG3cFwVAvL6ONil2BUB5q4KUG9YFQKbCvuO6NwZAx87noQ6bBkBDrh9uHgAHQG4KmwnyZgdA9as5WJHPB0A+eCFhBDoIQLcjXE9TpghAI6V3coYUCUA4dik/poQJQBqu9E+79glAWwLTZc5qCkCdu+Bo6OAKQPCqC2kSWQtAUi3FnlXTC0AGS7dru08MQLMAfVtNzgxAXcBdJBVPDUCaOAyoHNINQKxwaPRtVw5AcUhFRBPfDkBFazEAF2kPQDjFQ7+D9Q9AKsX1IzJCEED372HI4YoQQB+ctWDW1BBAWTivmRUgEUDw4Ws5pWwRQBbQ2B+LuhFAS7omR80JEkCkQj/EcVoSQANtPMd+rBJAXyzim/r/EkCEDxqq61QTQK4WcXZYqxNAr7uXokcDFECINuTtv1wUQFUI1zXItxRA0NahdmcUFUCrorDLpHIVQGVjNXCH0hVAQhO2vxY0FkBHNp02WpcWQFDnzHJZ/BZAoXY0NBxjF0BTpWhdqssXQFCJPvQLNhhAxiVpIkmiGEAqxBk2ahAZQBoao6J3gBlAmEgfAXryGUBcwRgRemYaQEQfNrmA3BpAB//oB5dUG0CL5R80xs4bQItB+50XSxxAgZaFz5TJHEDn3m59R0odQCU0y4c5zR1A3crU+nRSHkCAUrEPBNoeQDjHOi3xYx9Ap8XL6EbwH0AGuIcDiD8gQHZ6ar4riCBArGPzNxTSIECtzPIbRx0hQK2Uky/KaSFAz3nMUaO3IUCgbNN72AYiQCDnksFvVyJAZFAhUm+pIkD4dTp43fwiQFQku5rAUSNA2ecePR+oI0AAAAAAAAAkQJKOmaFpWSRA6AxM/mK0JEBAESQR8xAlQK1uY/QgbyVAA7oM4vPOJUCEPnE0czAmQDVtwWamkyZA09GfFZX4JkDjmLb/Rl8nQCyyTwbExydAS5vvLRQyKEBY3vKeP54oQKVQLqZODClA1B2StUl8KUDxq89kOe4pQAllAnImYipAc3NbwhnYKkDjfdBiHFArQIZwzYg3yitAEmHpknRGLEB5m54J3cQsQGvlBaB6RS1AGgeVNFfILUCpp+DRfE0uQG2MYa/11C5A+kk9MsxeL0BLdhLuCusvQPg15FLePDBA/1YxJnaFMECH/uuCUs8wQOmW9hN5GjFA+OiJne9mMUApYqb9u7QxQDRVhyzkAzJAzz0YPW5UMkDSEGxdYKYyQKehNtfA+TJAeyZIEJZOM0Cr5AqL5qQzQOwOA+e4/DNANt9Q4RNWNEBP9jRV/rA0QAQLlzx/DTVApvOOsJ1rNUAWFPDpYMs1QC0710HQLDZAZvo6MvOPNkDCgn5W0fQ2QEsSB2xyWzdAsP3TUt7DN0BrYRkOHS44QKCG3cQ2mjhAlAeZwjMIOUAOwNl3HHg5QECW6Hr56TlAsihyiNNdOkBpbjKEs9M6QFZWo3miSztAT3OunKnFO0B5wmFK0kE8QNSZpwkmwDxACM0BjK5APUDyFkiudcM9QE7WaXmFSD5AoiwzI+jPPkBqjhUPqFk/QMbT887P5T9A0Oz4ETU6QEB54aP/wIJAQEF1jEGRzEBA1kqngasXQUBTPDuDFWRBQOGOUiPVsUFAbyAuWfAAQkA6mLo2bVFCQGCjB+lRo0JAa0bBuKT2QkBFTasKbEtDQAvjHmCuoUNAQ1uKV3L5Q0ByNvOsvlJEQPNrejqarURAJwPj+AsKRUBvBhsAG2hFQGzaxofOx0VAGgTP5y0pRkDdaPCYQIxGQE0TTzUO8UZAQIgLeZ5XR0B1t9pC+b9HQGWToJQmKkhAWVwNlC6WSECbqj2LGQRJQChEXenvc0lAaspMQ7rlSUCETEpUgVlKQFLLnP5Nz0pAPLxCTClHS0ATmKNvHMFLQNmDRMQwPUxAJCGAz2+7TEBHlEFB4ztNQKfOwvSUvk1ApCtO8Y5DTkAybwNr28pOQDI1oMOEVE9AoeBLi5XgT0BfjbNAjDdQQNl4r0oMgFBAidPBc9DJUEBln/Fk3hRRQHfvk+A7YVFA9Ai9wu6uUUAQfrMB/f1RQFBLZa5sTlJAlwDf9EOgUkDK/sQcifNSQI7TzolCSFNAg7xEvHaeU0CIW39RLPZTQAWmaQRqT1RAEhkFrjaqVECXPPBFmQZVQNh/7+KYZFVA2Hl4uzzEVUBBmD8mjCVWQMhHyJqOiFZA6aD3sUvtVkB6pKkmy1NXQHQTSdYUvFdAae1pwTAmWEDPoWYMJ5JYQAAAAAAAAFlANvL/CcRvWUAfEN+9e+FZQJAVbdUvVVpAVEp8MenKWkCE6I/asEJbQCWOjQGQvFtAfshxAJA4XEBIxgdburZcQBs/pL8YN11Au57jB7W5XUAdgms5mT5eQOqVr4bPxV5AzuS5T2JPX0BJpfYiXNtfQHXLAd/jNGBAJn9BB1h9YEAoKHkZEMdgQKxOwr0REmFAVGaAtWJeYUCp3NHbCKxhQCwhAyYK+2FAY68DpGxLYkBtJN2ANp1iQMpoLANu8GJAxPecjRlFY0A/TmafP5tjQO+Jy9Tm8mNAc0Od5xVMZEC/rL2v06ZkQCj+piMnA2VAoDz0WBdhZUA2Y+yEq8BlQLT6D/3qIWZAfSqpN92EZkBDTV7MielmQAMVx3T4T2dAEUoEDTG4Z0AaMFqUOyJoQNKdzS0gjmhAp9LDIOf7aEAEF6XZmGtpQOYzguo93WlAxc28C99QakCMsLIchcZqQBwZbCQ5PmtA+AlNUgS4a0D8uMn+7zNsQHIjHqwFsmxA3tYIB08ybUAY/Yjn1bRtQMW5n1GkOW5AQ+gUdsTAbkB5ST+zQEpvQBEw0JUj1m9A5l3R7DsycEBvWUc1pHpwQAGFnzJQxHBA+BUGjEUPcUARCO0BiltxQIkZfW4jqXFAJcAIxhf4cUAlIIEXbUhyQFQO7YwpmnJA8SXia1PtckDl+/8V8UFzQP94bQkJmHNAXGRY4aHvc0ABKHdWwkh0QNfZjD9xo3RAkZLvkbX/dECJHRFill11QGgLCuQavXVAmTInbEoedkCNqHlvLIF2QEk+aYTI5XZANYxJYyZMd0AGmPHmTbR3QJcgVg1HHnhAypsm+BmKeEAU8mztzvd4QA4EMFhuZ3lA7AYZyQDZeUDwwxv3jkx6QAfIIcAhwnpAB5G4KcI5e0AgxcJhebN7QBGDLL9QL3xAIdiiwlGtfEBQak4Xhi19QFZlkZP3r31AP7jIObA0fkBrsxA5urt+QEIVDe4fRX9AMpW04+vQf0CA/g9qlC+AQNNvrtTwd4BAE/8hv5DBgECjtanPeQyBQAw/xsWxWIFAZdKqej6mgUC2FLDhJfWBQKz8yAhuRYJAJsH5GB2XgkBG29BWOeqCQIAl4iLJPoNAQiFE+tKUg0BlbA93XeyDQLRw4FBvRYRAEFdbXQ+ghEBsSLKQRPyEQDsHLv4VWoVAVeu42Iq5hUAxS2xzqhqGQJBdIEJ8fYZAJZ7+2QfihkC5wBbyVEiHQH0+9mNrsIdAcohCLFMaiECg61VrFIaIQGoy32W384hAhg+EhURjiUBaX4ZZxNSJQL1LbJc/SIpAyl+rG7+9ikBOmFbqSzWLQFJ+zy/vrotAtll6QbIqjEAjiXWenqiMQJkNVPC9KI1ATVjbCxqrjUDDaMTxvC+OQD5KgM+wto5AAAAAAABAj0A=\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[400]},\"y\":{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[400]}},\"selected\":{\"id\":\"1061\"},\"selection_policy\":{\"id\":\"1060\"}},\"id\":\"1034\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"bottom_units\":\"screen\",\"coordinates\":null,\"fill_alpha\":0.5,\"fill_color\":\"lightgrey\",\"group\":null,\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":1.0,\"line_color\":\"black\",\"line_dash\":[4,4],\"line_width\":2,\"right_units\":\"screen\",\"syncable\":false,\"top_units\":\"screen\"},\"id\":\"1026\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1034\"},\"glyph\":{\"id\":\"1035\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1037\"},\"nonselection_glyph\":{\"id\":\"1036\"},\"view\":{\"id\":\"1039\"}},\"id\":\"1038\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"line_alpha\":0.2,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1037\",\"type\":\"Line\"},{\"attributes\":{\"coordinates\":null,\"data_source\":{\"id\":\"1046\"},\"glyph\":{\"id\":\"1047\"},\"group\":null,\"hover_glyph\":null,\"muted_glyph\":{\"id\":\"1049\"},\"nonselection_glyph\":{\"id\":\"1048\"},\"view\":{\"id\":\"1051\"}},\"id\":\"1050\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"orange\"},\"hatch_alpha\":{\"value\":0.1},\"hatch_color\":{\"value\":\"orange\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"orange\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1048\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"1059\",\"type\":\"AllLabels\"},{\"attributes\":{},\"id\":\"1062\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.2},\"fill_color\":{\"value\":\"orange\"},\"hatch_alpha\":{\"value\":0.2},\"hatch_color\":{\"value\":\"orange\"},\"line_alpha\":{\"value\":0.2},\"line_color\":{\"value\":\"orange\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1049\",\"type\":\"Circle\"},{\"attributes\":{\"axis_label\":\"n\",\"coordinates\":null,\"formatter\":{\"id\":\"1058\"},\"group\":null,\"major_label_policy\":{\"id\":\"1059\"},\"ticker\":{\"id\":\"1013\"}},\"id\":\"1012\",\"type\":\"LogAxis\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"line_width\":2,\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1036\",\"type\":\"Line\"},{\"attributes\":{\"data\":{\"x\":[1,2,3,4,5,6,7,8,9,10,12,14,16,19,22,25,29,33,39,44,51,59,68,79,91,104,120,138,159,184,212,244,281,323,372,429,494,568,655,754,868,1000],\"y\":{\"__ndarray__\":\"AAAAAAAAAACGONbFbTTQP54zorQ3+NI/l/+Qfvs61D8vxVVl3xXVPw5Pr5RliNU/ujNUR8vC1T9+jLlrCfnVP0tWWIMKIdY/Iuo+AKlN1j8YJlMFo5LWP00f/8gzrdY/ArwFEhS/1j9qIeaPb+PWP2aWe+ukCdc/Ft7lIr4T1z8gGKQWsR7XPzuRG6N7J9c/B8AMzgtE1z9AuQOUO0DXP+OQ2Lk0Sdc/ncR9NMVe1z8g2iMwMl3XP8WqqLP7Ytc/L6vT6h9n1z+si9toAG/XP84kxG8ddtc/Qc1TDwJx1z8t0yVrKW7XP/D7e4I3ddc//fOppfR41z9dBI6q6H7XP/tql+omhtc/l9hcANaE1z9tu14nKYDXP9EN2EVAh9c/VTubMSqE1z8phRpt4IbXP4wzGeyOhtc/59Qh1R+F1z/5cRI01YjXP0BbGDPTh9c/\",\"dtype\":\"float64\",\"order\":\"little\",\"shape\":[42]}},\"selected\":{\"id\":\"1065\"},\"selection_policy\":{\"id\":\"1064\"}},\"id\":\"1046\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"coordinates\":null,\"group\":null},\"id\":\"1052\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"1010\",\"type\":\"LinearScale\"},{\"attributes\":{\"source\":{\"id\":\"1040\"}},\"id\":\"1045\",\"type\":\"CDSView\"},{\"attributes\":{\"axis\":{\"id\":\"1012\"},\"coordinates\":null,\"group\":null,\"ticker\":null},\"id\":\"1015\",\"type\":\"Grid\"},{\"attributes\":{\"line_color\":\"gray\",\"line_dash\":[6],\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1041\",\"type\":\"Line\"},{\"attributes\":{\"source\":{\"id\":\"1034\"}},\"id\":\"1039\",\"type\":\"CDSView\"},{\"attributes\":{\"ticker\":null},\"id\":\"1058\",\"type\":\"LogTickFormatter\"},{\"attributes\":{},\"id\":\"1006\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1017\",\"type\":\"BasicTicker\"},{\"attributes\":{\"axis\":{\"id\":\"1016\"},\"coordinates\":null,\"dimension\":1,\"group\":null,\"ticker\":null},\"id\":\"1019\",\"type\":\"Grid\"}],\"root_ids\":[\"1003\"]},\"title\":\"Bokeh Application\",\"version\":\"2.4.2\"}};\n", " const render_items = [{\"docid\":\"d154ec69-61b2-4bb5-9b6c-628898c3ef65\",\"root_ids\":[\"1003\"],\"roots\":{\"1003\":\"3ae7d31d-1b9f-4bc6-979b-612ba4a626a8\"}}];\n", " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", "\n", " }\n", " if (root.Bokeh !== undefined) {\n", " embed_document(root);\n", " } else {\n", " let attempts = 0;\n", " const timer = setInterval(function(root) {\n", " if (root.Bokeh !== undefined) {\n", " clearInterval(timer);\n", " embed_document(root);\n", " } else {\n", " attempts++;\n", " if (attempts > 100) {\n", " clearInterval(timer);\n", " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", " }\n", " }\n", " }, 10, root)\n", " }\n", "})(window);" ], "application/vnd.bokehjs_exec.v0+json": "" }, "metadata": { "application/vnd.bokehjs_exec.v0+json": { "id": "1003" } }, "output_type": "display_data" } ], "source": [ "# Compute theoretical curve\n", "n_theor = np.logspace(0, 3, 400)\n", "mean_f_theor = (1 - 1/n_theor)**n_theor\n", "\n", "# Set up figure\n", "p = bokeh.plotting.figure(\n", " frame_height=250,\n", " frame_width=350,\n", " x_axis_label='n',\n", " y_axis_label='mean fraction omitted',\n", " x_axis_type='log',\n", " x_range=[0.9, 1100],\n", ")\n", "\n", "# Theoretical curve\n", "p.line(\n", " x=n_theor,\n", " y=mean_f_theor,\n", " line_width=2\n", ")\n", "\n", "# Asymptotic result\n", "p.line(\n", " x=[0.9, 1100],\n", " y=[1 / np.exp(1)] * 2,\n", " line_dash='dashed',\n", " line_color='gray',\n", ")\n", "\n", "# Result from hacker stats\n", "p.circle(\n", " x=n,\n", " y=mean_f,\n", " color='orange'\n", ")\n", "\n", "bokeh.io.show(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result closely matches theory!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Computing environment" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "hide-input" ] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Python implementation: CPython\n", "Python version : 3.9.12\n", "IPython version : 8.3.0\n", "\n", "numpy : 1.21.5\n", "bokeh : 2.4.2\n", "jupyterlab: 3.3.2\n", "\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -v -p numpy,bokeh,jupyterlab" ] } ], "metadata": { "anaconda-cloud": {}, "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.9.12" } }, "nbformat": 4, "nbformat_minor": 4 }