Skip to content

Instantly share code, notes, and snippets.

@Per48edjes
Last active July 1, 2024 04:34
Show Gist options
  • Save Per48edjes/b7c06c9a1fea1f99d6d47d24292e1416 to your computer and use it in GitHub Desktop.
Save Per48edjes/b7c06c9a1fea1f99d6d47d24292e1416 to your computer and use it in GitHub Desktop.
Fiddler on the Proof: Fiddler (06/07/2024)
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "6479454d-d434-4808-a73d-01255eed4844",
"metadata": {},
"source": [
"# Fiddler on the Proof\n",
"\n",
"Ravi Dayabhai & Conrad Warren 🏀 2024-06-07"
]
},
{
"cell_type": "markdown",
"id": "52b23e3c-c3d9-4a10-87b0-8f3910e19419",
"metadata": {
"jp-MarkdownHeadingCollapsed": true
},
"source": [
"## Problem\n",
"\n",
"If you follow the NBA, then you probably know Boston Celtics had several improbable comebacks against the Indiana Pacers in this year’s playoffs. But given that the Pacers had a “90 percent chance or higher” to win at some point in a game, did that mean their probability of winning that game was actually 90 percent?\n",
"\n",
"Let’s explore this with a toy (i.e., simplified) version of basketball.\n",
"\n",
"Suppose you’re playing a game in which there are five “possessions.” For each possession, there’s a 50 percent chance that your team scores one point. If you don’t score, then your opponent instead scores one point.\n",
"\n",
"After the game, ESPN reports that your opponent’s chances of winning were “75 percent chance or higher” at some point during the game (i.e., before the final possession is complete).\n",
"\n",
"Given this information, what was the probability that your team actually won the game? "
]
},
{
"cell_type": "markdown",
"id": "eaa13279-6073-4c6d-8fa7-e57145e55b49",
"metadata": {},
"source": [
"## Solution\n",
"\n",
"The probability that your team won the game, given the other team's winning chances at some point during the game was 75% or more, is $\\frac{3}{16}$."
]
},
{
"cell_type": "markdown",
"id": "75277d57-d547-41e9-9813-88d90e03dc12",
"metadata": {},
"source": [
"### Rationale"
]
},
{
"cell_type": "markdown",
"id": "b7c609da-0f88-4740-b830-187c26c846bd",
"metadata": {},
"source": [
"Not even going to lie, we were lazy (and short on time), so we just brute-forced this (see below)."
]
},
{
"cell_type": "markdown",
"id": "55b45dbc-2223-47b4-9678-a7ce765e6c91",
"metadata": {},
"source": [
"### Numerical Approach"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "f3706ff0-f309-4985-8fe6-3ea37f8f6ddb",
"metadata": {},
"outputs": [],
"source": [
"import itertools as it\n",
"import math\n",
"\n",
"\n",
"def cond_prob_B_wins(possessions: int, b_wins: int) -> float:\n",
" if b_wins >= 3: \n",
" return 1\n",
" possessions_left = 5 - possessions\n",
" return sum(\n",
" math.comb(possessions_left, k) * (0.5)**possessions_left if k + b_wins >= 3 else 0\n",
" for k in range(possessions_left+1)\n",
" )\n",
" \n",
"def outcome_has_B_winning_75_pct_more(outcome: tuple[str]) -> bool:\n",
" for possession in range(1, 5):\n",
" b_wins = outcome[:possession].count('B')\n",
" if cond_prob_B_wins(possession, b_wins) >= 0.75:\n",
" return True\n",
" return False"
]
},
{
"cell_type": "markdown",
"id": "cac2f4bc-5cbf-4c71-9180-526e2e8a10cd",
"metadata": {},
"source": [
"We can approach this directly given the limited size of the sample space (i.e., $2^{5} = 32$ possible outcomes)."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "270336de-3908-4421-bdb4-672366b1632f",
"metadata": {},
"outputs": [],
"source": [
"# Let's enumerate the entire sample space\n",
"SAMPLE_SPACE = list(it.product(['A', 'B'], repeat=5))\n",
"\n",
"denom_outcomes = list(filter(outcome_has_B_winning_75_pct_more, SAMPLE_SPACE))\n",
"num_outcomes = list(filter(lambda o: o.count('A') >= 3, denom_outcomes))"
]
},
{
"cell_type": "markdown",
"id": "b42273fa-5f7e-4a58-896d-0cfef4ba0436",
"metadata": {},
"source": [
"Interestingly, the only time \"A\" (our team) wins when \"B\" (the other team) has at least a $75\\%$ chance of winning at some point during the game, is when \"A\" scores exactly once for the first $3$ possessions."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "b69a3131-f189-4fa0-922f-5463fff7654f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[('A', 'B', 'B', 'A', 'A'),\n",
" ('B', 'A', 'B', 'A', 'A'),\n",
" ('B', 'B', 'A', 'A', 'A')]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"num_outcomes"
]
},
{
"cell_type": "markdown",
"id": "b0d7f248-f48a-45e5-9af6-30797b99af00",
"metadata": {},
"source": [
"Overall, the probability we seek is:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "91b45192-160d-4783-92fa-fcd811be383a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.1875"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(num_outcomes) / len(denom_outcomes)"
]
}
],
"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.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment