import numpy as np
import matplotlib.pyplot as plt
print('Ready')Lecture 4 — Beginner tutorial
Distribution function / CDF as pushforward of P
Lecture 4 Tutorial — Distribution of a random variable (Beginner)
Based on Lec 04.
Goal
See the formula
\[P_X(x) = P(\{\omega : X(\omega) \le x\})\]
on a tiny example (coin), then estimate a CDF from samples.
Run with Shift+Enter.
Step 0 — Imports
Step 1 — Abstract world: Omega, P, and X
Fair coin:
- Omega = {H, T}
- P({H}) = P({T}) = 1/2
- Random variable X: X(H)=1, X(T)=0
Omega = {"H", "T"}
def P(event):
event = set(event)
return sum(0.5 for o in event if o in Omega)
def X(omega):
return 1.0 if omega == "H" else 0.0
print("P({H}) =", P({"H"}))
print("X(H), X(T) =", X("H"), X("T"))Step 2 — Distribution function by inverse image
For a number x, look at the event {omega : X(omega) <= x}, then apply P.
That is exactly P_X(x) from the lecture.
def P_X(x):
"""CDF / distribution function of X at real number x."""
event = {omega for omega in Omega if X(omega) <= x}
return P(event)
for x in [-1, 0, 0.5, 1, 2]:
print(f"P_X({x}) = P(X <= {x}) = {P_X(x)}")What you should see
- For x < 0: nothing maps to <= x → probability 0
- For 0 <= x < 1: only T (value 0) → probability 1/2
- For x >= 1: both outcomes → probability 1
That step function is the pushforward / distribution of X.
Step 3 — Estimate the same CDF from samples
In ML we rarely know P. We observe many values of X (range samples) and estimate.
rng = np.random.default_rng(0)
n = 5000
# simulate abstract outcomes, push through X (like a sensor)
samples = np.array([X(o) for o in rng.choice(["H", "T"], size=n)])
xs = np.linspace(-0.5, 1.5, 200)
# empirical CDF: fraction of samples <= x
ecdf = np.array([(samples <= x).mean() for x in xs])
true = np.array([P_X(x) for x in xs])
plt.figure(figsize=(7, 4))
plt.step(xs, true, where="post", label="true P_X (from Omega)")
plt.plot(xs, ecdf, label="empirical CDF from samples")
plt.xlabel("x")
plt.ylabel("P(X <= x)")
plt.title("Pushforward distribution of coin RV X")
plt.legend()
plt.show()Step 4 — Mini exercises
# Exercise A: unfair coin P(H)=0.7, same X coding.
# Recompute P_X at x = -1, 0, 0.5, 1.
def P_unfair(event, p_h=0.7):
event = set(event)
mass = {"H": p_h, "T": 1 - p_h}
return sum(mass[o] for o in event)
def P_X_unfair(x):
event = {o for o in Omega if X(o) <= x}
return P_unfair(event)
for x in [-1, 0, 0.5, 1]:
print(x, P_X_unfair(x))# Exercise B: die, X(omega)=omega.
# What is P_X(3.5)? (should equal P(X <= 3.5) = P({1,2,3}) = 3/6)
Omega_die = {1, 2, 3, 4, 5, 6}
def P_die(event):
return len(set(event) & Omega_die) / len(Omega_die)
def P_X_die(x):
event = {o for o in Omega_die if o <= x}
return P_die(event)
print("P_X(3.5) =", P_X_die(3.5))Recap
| Lecture idea | In this notebook |
|---|---|
| Inverse image | {omega : X(omega) <= x} |
| Pushforward / P_X | P of that event |
| Work with samples | empirical CDF approximates P_X |
| Course goal | estimate distributions from range samples |
Next: several random variables, conditioning, then ML as distribution learning.