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_01_hoeffding_inequality_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: Building Intuition about Hoeffding Inequality¶
Cell 1.1: Basic Bernoulli sampling code¶
Goal:
- Walk through the mechanics of Bernoulli sampling in plain code, before any interactive widget: draw samples, compute the empirical mean , and compare it against the true mean
Implementation: cell1_1_basic_bernoulli_sampling(mu=0.6, N=10, seed=42)
- Draws
NBernoulli(mu) samples with_generate_bernoulli_samples() - Prints the raw samples, the count of successes and failures, and the empirical mean next to the true mean
# Demonstrate basic Bernoulli sampling.
utils.cell1_1_basic_bernoulli_sampling()Cell 1.2: Samples over time and empirical PDF¶
Goal:
- Visualize samples from a Bernoulli distribution as a sequence over time and as an empirical probability distribution function (PDF), side by side
Implementation: cell1_2_samples_over_time_and_pdf()
- Draws
NBernoulli(mu) samples with_generate_bernoulli_samples() - Plots the samples over time, then the same samples as an empirical PDF
next to the theoretical Bernoulli PDF, in
_plot_bernoulli_sample2()
hintros.print_obj_info(utils.cell1_2_samples_over_time_and_pdf)Usage
Inputs
mu: true probability of success, 0.1-0.9N: number of samples drawn, 10-500seed: random seed for the draw
Panels
Bernoulli samples over time: each sample plotted by index, colored by outcome, with the truemumarked as a dashed lineEmpirical PDF: bar comparison of the empirical outcome frequencies against the theoretical Bernoulli PDFComments: currentmu,N,seed, and the counts of successes/failures
# Display N samples over time and their empirical PDF.
utils.cell1_2_samples_over_time_and_pdf()Guided usage
- Raise
Nfrom 10 toward 500, leavingmufixed- Observe the empirical PDF bars converge toward the theoretical Bernoulli PDF
- Change
seeda few times at a smallN- Observe the empirical PDF swing further from the theoretical one than
it does at large
N
- Observe the empirical PDF swing further from the theoretical one than
it does at large
Cell 1.3: Distribution of empirical mean¶
Goal:
- Show the distribution of the empirical mean over many repeated trials, and compare it with the Central Limit Theorem prediction
Implementation: cell1_3_distribution_empirical_mean()
- Repeats sampling
n_samplestimes in_plot_bernoulli_sample4(), each trial drawingNBernoulli(mu) samples and recording its own - Overlays the empirical histogram of with the density predicted by the Central Limit Theorem
hintros.print_obj_info(utils.cell1_3_distribution_empirical_mean)Usage
Inputs
mu: true probability of success, 0.1-0.9N: samples per trial, 10-500log10(n_samples): number of trials, log-scaled from 100 to 10000seed: random seed for the trials
Panels
Distribution of empirical mean nu: histogram of across trials, with the CLT-predicted normal density overlaid and the truemumarkedComments: current parameters, empirical mean/std of , and the CLT-predicted mean/std
# Display the distribution of empirical mean nu from repeated sampling.
utils.cell1_3_distribution_empirical_mean()Guided usage
- Raise
Nfrom 10 toward 500, leavingn_samplesfixed- Observe the histogram narrow around
mu, matching the shrinking predicted spread
- Observe the histogram narrow around
- Raise
log10(n_samples)toward its maximum- Observe the histogram fill in and match the CLT curve more closely, since more trials means a smoother empirical distribution
- By the Law of Large Numbers, converges to as increases, which the previous experiment already shows as the narrowing histogram
Part 2: Hoeffding Inequality: Theoretical Bounds¶
- The Hoeffding inequality provides a concentration bound
- It quantifies how quickly the sample mean converges to the true mean as increases
Cell 2.1: Hoeffding inequality statement¶
Goal:
State the Hoeffding inequality precisely, and name every symbol in it, so the interactive cells that follow can be read against a fixed reference
For independent Bernoulli random variables with probability
Let be the sample mean
The Hoeffding inequality states:
- Where:
- is the sample mean (empirical probability)
- is the true probability
- is the deviation threshold
- is the number of samples
- The bound decreases exponentially with
- The bound is independent of (distribution-free)
- Larger requires larger for the same confidence
- The factor of 2 accounts for both tails:
Cell 2.2: Interactive Hoeffding inequality demonstration¶
Goal:
- Demonstrate that the Hoeffding inequality is distribution-free: watch it hold across five different bounded distributions on , not only the Bernoulli one
Implementation: cell2_2_hoeffding_inequality_demo()
- Draws
Nsamples from the chosenDistributionwith_generate_samples_from_distribution(), repeats it to build the empirical distribution of - Computes the Hoeffding bound , capped at 1.0, and
the empirical tail probability ,
then plots both in
_plot_hoeffding_inequality_demo()
hintros.print_obj_info(utils.cell2_2_hoeffding_inequality_demo)Usage
Inputs
Distribution: Bernoulli, Uniform, Binomial, Truncated Gaussian, or Truncated Exponentialmu: distribution parameter, interpretation depends onDistributionN(log scale): number of samples per trial, powers of 2 from 8 to 1024epsilon: deviation thresholdseed: random seed
Panels
<Distribution> distribution: the PDF/PMF of the selected distributionDistribution of sample mean: histogram of across trials, with the tail beyondepsilonshaded redBound vs empirical: bar comparison of the Hoeffding bound against the measured tail probabilityComments: current distribution, parameters, and both probabilities
# Demonstrate the Hoeffding inequality with multiple distributions.
utils.cell2_2_hoeffding_inequality_demo()Guided usage
- Switch
Distributionthrough all five options, leavingmu,N,epsilonfixed- Observe the empirical probability stays at or below the Hoeffding bound every time, even though the underlying shape changes completely
- Raise
Nfrom small to large- Observe both the bound and the empirical probability shrink, and the histogram narrow around the true mean
Cell 2.3: Empirical probability vs Hoeffding bound¶
Goal:
- Compare the Hoeffding bound against the empirical tail probability as a single parameter, or , sweeps across its range
Implementation: cell2_3_empirical_vs_bound()
- Sweeps
Scan variable(Norepsilon) over a fixed range with the other one held atfixed_N/fixed_epsilon, in_plot_hoeffding_inequality_demo2() - At each sweep point, computes the theoretical bound and estimates the
empirical tail probability over
n_trialsresamples
hintros.print_obj_info(utils.cell2_3_empirical_vs_bound)Usage
Inputs
Distribution: distribution the samples are drawn fromScan variable: sweepN(fix epsilon) or sweepepsilon(fix N)mu: distribution parameterfixed_N:Nused while scanningepsilonfixed_epsilon:epsilonused while scanningNseed: random seed for the resamplesUse log scale for y-axis: toggle a log y-axis on the scan plot
Panels
Hoeffding bound vs empirical: bound and empirical probability plotted against the scanned variableComments: current scan variable, fixed value, and distribution
# Visualize how bound and empirical probability change with N or epsilon.
utils.cell2_3_empirical_vs_bound()Guided usage
- Scan
Nwithepsilonfixed- Observe both curves decay exponentially, and the empirical curve stay at or below the bound at every point
- Switch to scanning
epsilonwithNfixed- Observe the same exponential-decay shape, now driven by instead of
Cell 2.4: Hoeffding bound as a function of and ¶
Goal:
- Explore the two-parameter shape of the Hoeffding bound as a function of both and at once
Implementation: cell2_4_bound_surface_heatmap()
- Evaluates the bound over a grid of
Nandepsilonvalues up toN_max/epsilon_max, in_plot_hoeffding_bound_surface() - Renders the grid as a heatmap, a contour plot, or a 1D slice at a fixed
Norepsilon, depending onView mode
hintros.print_obj_info(utils.cell2_4_bound_surface_heatmap)Usage
Inputs
View mode: heatmap, fixNand varyepsilon, fixepsilonand varyN, or contour plotN_max: upper end of theNrange plottedepsilon_max: upper end of theepsilonrange plottedfixed_N:Nheld fixed inFix N, vary epsilonmodefixed_epsilon:epsilonheld fixed inFix epsilon, vary Nmode
Panels
Bound surface: heatmap, contour, or line view of the bound, depending onView modeComments: current view mode and range
# Explore the Hoeffding bound as a function of N and epsilon.
utils.cell2_4_bound_surface_heatmap()Guided usage
- Switch
View modefromHeatmaptoContour plot- Observe the same bound surface, now read off as curves of constant probability instead of color
- Raise
fixed_NinFix N, vary epsilonmode- Observe the bound-vs-epsilon curve drop faster, since a larger
Nmakes the bound more sensitive toepsilon
- Observe the bound-vs-epsilon curve drop faster, since a larger
Cell 2.5: 3D surface visualization of Hoeffding bound¶
Goal:
- View the Hoeffding bound as a 3D surface over and , to see the exponential decay in both dimensions at once
Implementation: cell2_5_bound_3d_surface()
- Evaluates the bound over the same grid as Cell 2.4, in
_plot_hoeffding_bound_3d() - Renders it as a 3D surface, with the viewing angle set by
elevation/azimuth, optionally with a log-scaled -axis
hintros.print_obj_info(utils.cell2_5_bound_3d_surface)Usage
Inputs
N_max: upper end of theNrange plottedepsilon_max: upper end of theepsilonrange plottedelevation: viewing angle from above, 0 (horizontal) to 90 (top-down)azimuth: rotation angle around the vertical axis, 0-360Use log scale for Z-axis: toggle a log-scaled bound axis
Panels
Bound surface (3D): the bound plotted as a surface over andComments: current range and viewing angle
# Visualize the Hoeffding bound as a 3D surface.
utils.cell2_5_bound_3d_surface()Guided usage
- Rotate
azimuththrough a full sweep from 0 to 360- Observe the same “valley” shape from every side: the bound is
smallest at large
Nand largeepsilon
- Observe the same “valley” shape from every side: the bound is
smallest at large
- Turn on
Use log scale for Z-axis- Observe the surface’s flat-looking tail resolve into visible structure, since the bound spans several orders of magnitude