Skip to content

Commit 022b3af

Browse files
committed
update
1 parent 8990570 commit 022b3af

2 files changed

Lines changed: 90 additions & 172 deletions

File tree

‎notebooks/Notebook_1/Notebook_1b_Noise_and_Modeling_Data.ipynb‎

Lines changed: 75 additions & 119 deletions
Large diffs are not rendered by default.

‎notebooks/Notebook_1/Notebook_1b_Noise_and_Modeling_Data.py‎

Lines changed: 15 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -418,41 +418,22 @@ def plot_pdf_cdf_accumulation_gif(
418418
print("standard deviation:", np.std(v))
419419

420420
# %% [markdown] id="nb1b-summaries-are-lossy"
421-
# #### What the Mean and Variance Miss
422-
#
423-
# The mean says *where* the data sits, the variance *how far it spreads*. Both are
424-
# useful, and neither pins down the distribution. Three samples make the point:
425-
#
426-
# - **narrow**: normal, $\mu = 0$, $\sigma = 1$
427-
# - **wide**: normal, $\mu = 0$, $\sigma = 2.5$ — same center, different spread, so the mean alone cannot tell it from *narrow*
428-
# - **bimodal**: half the samples near $-2.4$, half near $+2.4$, each with spread $0.7$
429-
#
430-
# The bimodal one is the counterexample. By symmetry its mean is $0$, and its
431-
# variance splits into the spread *of* the modes plus the spread *within* a mode:
432-
#
433-
# $$\sigma^2 = \underbrace{2.4^2}_{\text{between modes}} + \underbrace{0.7^2}_{\text{within a mode}} = 5.76 + 0.49 = 6.25 = 2.5^2$$
434-
#
435-
# So it matches *wide* on **both** statistics (up to sampling noise) while looking
436-
# nothing like it: for the normal, $0$ is the most common value; for the bimodal, $0$
437-
# is one of the *rarest*. The last column below makes that concrete.
421+
# These two numbers are a useful summary, but only a summary. Data with the same mean
422+
# can be tightly clustered or wildly spread out, and — less obviously — two samples
423+
# can agree on *both* the mean and the variance and still look nothing alike. All
424+
# three samples below are centered at $0$; the last two even share a spread, yet the
425+
# bimodal one almost never takes values near its own mean. Plot the distribution
426+
# before trusting its summary.
438427

439428
# %% id="nb1b-summaries-are-lossy-data"
440-
narrow = rng.normal(loc=0.0, scale=1.0, size=5000) # sigma = 1
441-
wide = rng.normal(loc=0.0, scale=2.5, size=5000) # sigma = 2.5
442-
443-
# Bimodal mixture built to match `wide` on mean AND variance.
444-
centers = np.repeat([-2.4, 2.4], 2500) # exactly half the samples in each mode
445-
bimodal = centers + rng.normal(loc=0.0, scale=0.7, size=5000)
429+
narrow = rng.normal(loc=0.0, scale=1.0, size=5000)
430+
wide = rng.normal(loc=0.0, scale=2.5, size=5000)
431+
# Two lumps instead of one, tuned to match `wide`'s mean and spread.
432+
bimodal = np.repeat([-2.4, 2.4], 2500) + rng.normal(loc=0.0, scale=0.7, size=5000)
446433

447434
samples = [("narrow", narrow), ("wide", wide), ("bimodal", bimodal)]
448435
for name, sample in samples:
449-
mu, sd = np.mean(sample), np.std(sample)
450-
# A shape probe the two statistics cannot see: how much mass sits near the mean.
451-
near_mean = np.mean(np.abs(sample - mu) <= 0.5)
452-
print(
453-
f"{name:>7}: mean = {mu:5.2f} std = {sd:5.2f}"
454-
f" within 0.5 of mean = {100 * near_mean:4.1f}%"
455-
)
436+
print(f"{name:>7}: mean = {np.mean(sample):5.2f} std = {np.std(sample):5.2f}")
456437

457438
# %%
458439
#| code-fold: true
@@ -463,17 +444,13 @@ def plot_pdf_cdf_accumulation_gif(
463444

464445
for a, (_, sample), color, title in zip(ax, samples, colors, titles):
465446
sns.histplot(sample, bins=40, stat="density", kde=True, color=color, ax=a)
466-
mu, sd = np.mean(sample), np.std(sample)
467-
a.axvline(mu, color="red", linewidth=1.5, label="Mean")
468-
for edge, lbl in [(mu - sd, "Mean $\\pm$ 1 std"), (mu + sd, None)]:
469-
a.axvline(edge, color="gray", linestyle="--", linewidth=1, label=lbl)
470-
a.set_title(f"{title}\n(mean {mu:.2f}, std {sd:.2f})")
447+
a.axvline(np.mean(sample), color="red", linewidth=1.5, label="Mean")
448+
a.set_title(f"{title}\n(mean {np.mean(sample):.2f}, std {np.std(sample):.2f})")
471449
a.set_xlabel("Value")
472450

473451
ax[0].legend(fontsize=8)
474452

475-
# Overlay the wide Gaussian on the bimodal panel: identical mean and variance,
476-
# completely different shape.
453+
# Overlay the wide normal on the bimodal panel: same mean and spread, different shape.
477454
sns.kdeplot(
478455
wide,
479456
color="darkorange",
@@ -484,25 +461,10 @@ def plot_pdf_cdf_accumulation_gif(
484461
)
485462
ax[2].legend(fontsize=8)
486463

487-
plt.suptitle("Mean and Variance Do Not Determine the Distribution")
464+
plt.suptitle("Same Summary Statistics, Different Distributions")
488465
plt.tight_layout()
489466
plt.show()
490467

491-
# %% [markdown] id="nb1b-summary-stats-lossy"
492-
# ::: {.callout-important title="Key concept: summary statistics are lossy"}
493-
# The mean and variance are a *compression* of the data, not a substitute for it.
494-
# Panels 1 and 2 share a mean; panels 2 and 3 share a mean *and* a variance. Plot the
495-
# distribution before trusting its summary — a two-lump histogram usually means the
496-
# data mixes two populations or regimes, and the "average" describes a value that
497-
# almost never occurs.
498-
# :::
499-
#
500-
# **Quick discussion.**
501-
#
502-
# 1. For the bimodal sample, is the mean a good prediction of a typical value? What would a better one-number summary be?
503-
# 2. If a model is trained with mean squared error on the bimodal data, what value will it be pulled toward, and why is that a problem?
504-
#
505-
506468
# %% [markdown] id="Uri-wUVZniM9"
507469
# ### Why This Matters for Modeling (Now and Later)
508470
#

0 commit comments

Comments
 (0)