Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Bin Analogy ML

Imports

%load_ext autoreload
%autoreload 2

import logging

import matplotlib.pyplot as plt
import seaborn as sns

import helpers.hintrospection as hintros
import L05_01_02_bin_analogy_ml_utils as utils

# Set plotting style.
sns.set_style("whitegrid")
plt.rcParams["figure.figsize"] = (12, 6)
WARNING (pytensor.tensor.blas): Using NumPy C-API based implementation for BLAS functions.
import helpers.htutorial as ut

ut.config_notebook()

# Initialize logger.
logging.basicConfig(level=logging.INFO)
_LOG = logging.getLogger(__name__)
vim support installed: restart the notebook, if needed
Python 3.12.3
Linux 589569fe8102 6.12.67-linuxkit #1 SMP Sun Jan 25 02:26:28 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux

Part 1: Bin Analogy for Machine Learning

Cell 1.1: Visual bin: population of marbles

Goal:

  • Visualize an unknown population of marbles in a bin, and introduce μ\mu as the population’s true, unknown proportion of red marbles

Implementation: cell1_draw_bin_with_marbles_interactive()

  • Places a grid of marbles, colors a mu fraction of them red with _draw_bin_with_marbles(), and shuffles the colors with seed so the arrangement looks random while the proportion stays fixed
hintros.print_obj_info(utils.cell1_draw_bin_with_marbles_interactive)

Usage

  • Inputs

    • seed: random seed for the spatial arrangement of marbles
    • mu: true proportion of red marbles in the population, 0-1
  • Panels

    • Bin with marbles: the full population, red and green marbles laid out on a grid, with mu and the red count in the title
utils.cell1_draw_bin_with_marbles_interactive()
Loading...

Guided usage

  • Change seed several times, leaving mu fixed
    • Observe the marbles reshuffle into a new arrangement, but the total red count stays exactly μ×\mu \times total marbles every time
  • Raise mu from 0 toward 1
    • Observe the bin fill up with more red marbles, since μ\mu is the fixed population proportion, not something observed by sampling
  • In real-world scenarios, μ\mu is never known directly, only estimated from samples: the rest of this notebook builds that estimation problem

Cell 1.2: Single experiment: is ν\nu close to μ\mu?

Goal:

  • Draw one sample of N marbles from the bin, compute the sample proportion ν\nu, and see how close a single estimate lands to μ\mu

Implementation: cell2_plot_single_experiment_interactive()

  • Draws N Bernoulli(mu) samples with _plot_single_experiment(), and computes ν=1N∑i=1Nxi\nu = \frac{1}{N}\sum_{i=1}^{N} x_i
  • Colors the comparison bar chart green, yellow, or red by how far ν\nu landed from μ\mu
hintros.print_obj_info(utils.cell2_plot_single_experiment_interactive)

Usage

  • Inputs

    • seed: random seed for the sample drawn
    • mu: true proportion of red marbles in the population, 0-1
    • N: number of marbles sampled, 10-1000
  • Panels

    • Population vs sample: bar chart comparing μ\mu against ν\nu, colored by how close the two are
    • Interpretation: current parameters, the sampled ν\nu, and the error ∣ν−μ∣|\nu - \mu|
utils.cell2_plot_single_experiment_interactive()
Loading...

Guided usage

  • Change seed several times, leaving mu and N fixed
    • Observe ν\nu land in a different place each time, and the bar color flip between green, yellow, and red: one experiment is not reliable on its own
  • Raise N from 10 toward 1000, leaving seed fixed
    • Observe ν\nu settle closer to μ\mu and the bar turn green more often
  • A single experiment only gives a point estimate, never a sense of how reliable that estimate is
    • What is really needed is P(∣ν−μ∣>ϵ)P(|\nu - \mu| > \epsilon): the probability that an estimate this far off would happen at all
    • Repeating the experiment many times, next, is how that probability gets measured

Cell 1.3: Monte Carlo simulation: distribution of ν\nu

Goal:

  • Repeat the sampling experiment many times to see the full distribution of ν\nu, and empirically estimate P(∣ν−μ∣>ϵ)P(|\nu - \mu| > \epsilon)

Implementation: cell3_monte_carlo_simulation_interactive()

  • Runs n_experiments independent trials of N Bernoulli(mu) samples each in _plot_monte_carlo_simulation(), recording ν\nu per trial
  • Overlays a KDE on the ν\nu histogram, shades the region where ∣ν−μ∣>ϵ|\nu - \mu| > \epsilon, and reports the fraction of trials landing there
hintros.print_obj_info(utils.cell3_monte_carlo_simulation_interactive)

Usage

  • Inputs

    • seed: random seed for the experiments
    • mu: true proportion of red marbles in the population, 0-1
    • N: samples per experiment, 10-500
    • n_experiments: number of repeated experiments, 100-10000
    • eps: tolerance ϵ\epsilon defining “far from μ\mu”
  • Panels

    • Distribution of nu: histogram plus KDE of ν\nu across experiments, true mu marked, and the ∣ν−μ∣>ϵ|\nu - \mu| > \epsilon tails shaded red
    • Key insights: current parameters, mean(ν)\text{mean}(\nu), std(ν)\text{std}(\nu), and P(∣ν−μ∣>ϵ)P(|\nu - \mu| > \epsilon)
utils.cell3_monte_carlo_simulation_interactive()
Loading...

Guided usage

  • Raise N from 10 toward 500, leaving n_experiments fixed
    • Observe the histogram narrow around mu and P(∣ν−μ∣>ϵ)P(|\nu - \mu| > \epsilon) drop: this is the Law of Large Numbers, ν→Pμ\nu \xrightarrow{P} \mu as N→∞N \to \infty
  • Raise n_experiments toward 10000
    • Observe the histogram fill in and its shape approach the smooth normal curve predicted by the Central Limit Theorem
  • Replace “marbles in a bin” with “data points”, μ\mu with generalization error, and ν\nu with training error on N samples
    • The same result then reads: with enough training samples, training error is close to generalization error, the connection this bin analogy sets up for the rest of the course