Sample Size, Minimum Detectable Effect, and Power › Deriving the Sample Size Formula
Machine Learning from ScratchAll chapters Sample Size, Minimum Detectable Effect, and Power › Deriving the Sample Size FormulaOne section · Sections in this chapter3 / 12 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Let's derive the sample size formula for the most common case: a one-sample z-test. The same logic extends to other tests with minor modifications.
Setup
We want to test:
- (null hypothesis)
- (specific alternative, where )
With:
- Known population standard deviation σ
- Significance level α (two-tailed)
- Desired power 1 - β
The Derivation
Step 1: Find the rejection criterion under H₀
Under the null hypothesis, the test statistic follows N(0, 1).
We reject when , which corresponds to:
Step 2: Calculate power under H₁
Under the alternative , we want:
For a one-sided test (detecting ), the power is:
Under , . Standardizing:
Step 3: Solve for n
Setting power equal to :
This means:
Note: is the z-value such that , so .
Solving for n:
where is the standardized effect size (Cohen's d).
import numpy as np
from scipy import stats
def sample_size_one_sample(effect_size, sigma=1, alpha=0.05, power=0.80):
"""
Calculate required sample size for a one-sample z-test.
Parameters:
-----------
effect_size : float
The minimum detectable effect in original units
sigma : float
Population standard deviation
alpha : float
Significance level (two-tailed)
power : float
Desired power (1 - beta)
Returns:
--------
int : Required sample size (rounded up)
"""
# Standardized effect size (Cohen's d)
d = effect_size / sigma
# Critical values
z_alpha = stats.norm.ppf(1 - alpha / 2) # Two-tailed
z_beta = stats.norm.ppf(power) # Power quantile
# Sample size formula
n = ((z_alpha + z_beta) / d) ** 2
return int(np.ceil(n))
# Example: Detect a medium effect (d = 0.5) with 80% power at α = 0.05
n = sample_size_one_sample(effect_size=0.5, sigma=1, alpha=0.05, power=0.80)
print("One-sample z-test for d = 0.5:")
print(f" Required n = {n}")
# Verify the components
z_alpha = stats.norm.ppf(0.975)
z_beta = stats.norm.ppf(0.80)
print("\nComponents:")
print(f" z_α/2 = {z_alpha:.4f}")
print(f" z_(1-β) = {z_beta:.4f}")
print(f" Sum = {z_alpha + z_beta:.4f}")
print(
f" n = ({z_alpha + z_beta:.4f} / 0.5)² = {((z_alpha + z_beta) / 0.5) ** 2:.1f}"
)One-sample z-test for d = 0.5: Required n = 32 Components: z_α/2 = 1.9600 z_(1-β) = 0.8416 Sum = 2.8016 n = (2.8016 / 0.5)² = 31.4