Contents
Deep Breakdown
What it tells me (Situation Awareness): The binomial theorem gives the exact expanded form of a power of a two-term sum. produces terms, each of the form for . The coefficient ("n choose k") counts the number of ways to pick exactly factors of from the factors in the product . In DA/DS, the binomial theorem appears in: the binomial probability distribution (directly this formula with and ), Taylor/linear approximations for small (the first-order term of the expansion), compound growth and variance propagation, and polynomial feature expansion in machine learning (expanding to get cross-features ). The theorem is also the theoretical foundation of Pascal's triangle.
Flowchart
Real-world use
Where it is used
Binomial distribution: the probability that exactly successes occur in independent Bernoulli trials with success probability is — this is exactly the binomial theorem applied to . Compound growth approximation: for small (e.g., annual growth rate compounded times). Polynomial feature generation: for two features , the degree-2 expansion generates the polynomial basis used in kernel SVMs and polynomial regression. Variance of a sum of random variables (when terms are independent).
Problem it solves
Expanding by hand via repeated multiplication becomes infeasible for large . The binomial theorem gives the exact result directly, without iterative multiplication. Each term is computed independently using the formula , so you can extract any single term (e.g., the term in ) without computing all others.
How it solves the problem
Consider the product ( factors). Each term in the expansion is produced by choosing one of from each of the factors. To get a term with exactly factors of (and factors of ), you must choose from specific factors — the number of ways to do this is . The resulting term is . Summing over all possible values of (from 0 to ) gives the full expansion.
Example in a business
A conversion rate analyst wants the probability that exactly 3 out of 10 randomly selected users convert, given a 20% conversion rate. Using the binomial theorem with (non-conversion), (conversion), , : . The binomial theorem is the backbone of this calculation.
The formula, piece by piece
Breaking the notation:
- : a binomial ("two-term") expression raised to the power — the quantity being expanded.
- : sum over all integer values of from 0 to inclusive — terms total.
- : the binomial coefficient "n choose k" — — the number of ways to select items from without order.
- : raised to the power — decreases as increases (first term: , last term: ).
- : raised to the power — increases as increases (first term: , last term: ). First and last terms:
- : .
- : . Middle term (when is even, ): — has the largest binomial coefficient. Special case : — the standard form used for probability generating functions and small- approximations. Linear approximation: for small : (first two terms only).
The formula in words
" expands into terms. Each term is: how many ways to pick copies of from factors (), times to the remaining power (), times to the chosen power (). The powers of decrease and the powers of increase as you go from to . In Python: from sympy import expand, symbols; expand((a+x)**n) or use scipy.special.comb(n, k) to compute individual coefficients."
Critical Concepts
- Binomial coefficients are symmetric: . The coefficient of equals the coefficient of . This corresponds to the symmetry of Pascal's triangle.
- Sum of coefficients = : setting : . Total number of subsets of an -element set.
- Binomial distribution connection: is the -th term of — the binomial theorem guarantees all probabilities sum to 1.
- First-order approximation: for . In finance: for small interest rate . In ML: gradient approximations for small perturbations.
- Polynomial features: the degree-2 expansion of generates the polynomial kernel basis.
More generally, the PolynomialFeatures transformer in scikit-learn applies the binomial (and multinomial) theorem to generate interaction terms.
Step-by-step calculation (tiny example)
Task: expand .
Step 1: Identify , , , , . There will be 4 terms ().
Step 2: Compute each binomial coefficient , , , .
Step 3: Write each term : . : . : . : .
Step 4: Assemble .
Step 5: Verify by substitution : . Formula: .
Code examples
Beginner example (Python)
# Binomial theorem expansion
from math import comb, factorial
def binomial_term(n: int, k: int, a: float, x: float) -> float:
"""Compute the k-th term of the binomial expansion of (a + x)^n."""
return comb(n, k) * (a ** (n - k)) * (x ** k)
def binomial_expansion(n: int, a: float, x: float) -> list[float]:
""" Expand (a + x)^n and return all n+1 terms. Args: n: Power (non-negative integer). a: First term of the binomial. x: Second term of the binomial. Returns: List of n+1 term values. """
return [binomial_term(n, k, a, x) for k in range(n + 1)] # Expand (2 + x)^3 symbolically (x=1 for numeric check)
n_val = 3
a_val = 2.0
terms = binomial_expansion(n_val, a_val, 1.0)
print(f"Expansion of ({a_val} + x)^{n_val}:")
for k, term in enumerate(terms):
coeff = comb(n_val, k) * (a_val ** (n_val - k))
print(f" k={k}: C({n_val},{k}) × {a_val}^{n_val - k} × x^{k} = {coeff:.0f}x^{k} (at x=1: {term:.1f})")
print(f" Sum at x=1: {sum(terms):.1f} vs ({a_val}+1)^{n_val} = {(a_val + 1) ** n_val:.1f}") # Binomial distribution: P(X=k) for n=10,
p=0.2
n_trials = 10
p = 0.2
print(f"\nBinomial distribution: n={n_trials}, p={p}")
print(f"{'k':>4} {'P(X=k)':>10} {'term check':>12}")
for k in range(n_trials + 1):
prob = binomial_term(n_trials, k, 1 - p, p)
print(f"{k:>4} {prob:>10.6f}")
total = sum(binomial_term(n_trials, k, 1 - p, p) for k in range(n_trials + 1))
print(f"Sum = {total:.8f} (should be exactly 1.0)") # Linear approximation (1 + r)^n ≈ 1 + nr for small r
r = 0.02 # 2% growth rate
n = 5
exact = (1 + r) ** n
approx = 1 + n * r
print(f"\nLinear approximation: (1 + {r})^{n}")
print(f" Exact: {exact:.6f}")
print(f" Approx: {approx:.6f}")
print(f" Error: {abs(exact - approx):.8f}")Beginner example (R)
# Binomial theorem in R # Expand (a + x)^n term by term
binomial_term <- function(n, k, a, x) choose(n, k) * a^(n - k) * x^k
binomial_expansion <- function(n, a, x) { sapply(0:n, function(k) binomial_term(n, k, a, x))
} # Expand (2 + x)^3 at
x=1
n_val <- 3; a_val <- 2.0
terms <- binomial_expansion(n_val, a_val, 1.0)
cat(sprintf("Expansion of (%.0f + x)^%d at x=1:\n", a_val, n_val))
for (k in 0:n_val) { coeff <- choose(n_val, k) * a_val^(n_val - k)
cat(sprintf(" k=%d: coeff=%.0f term=%.1f\n", k, coeff, terms[k + 1]))
}
cat(sprintf(" Sum=%.1f vs (%.0f+1)^%d=%.1f\n", sum(terms), a_val, n_val, (a_val + 1)^n_val)) # Binomial distribution
n_trials <- 10; p <- 0.2
cat(sprintf("\nBinomial: n=%d, p=%.2f\n", n_trials, p))
probs <- sapply(0:n_trials, function(k) binomial_term(n_trials, k, 1 - p, p))
cat(sprintf("Sum of all P(X=k) = %.8f\n", sum(probs))) # Linear approximation
r <- 0.02; n <- 5
cat(sprintf("\n(1+%.2f)^%d: exact=%.6f approx=%.6f\n", r, n, (1+r)^n, 1 + n*r))Professional example (Python)
import numpy as np
import pandas as pd
from math import comb
from scipy.stats import binom as scipy_binom # Scenario: A/B test power analysis using the binomial distribution
# For a given baseline conversion rate and minimum detectable effect,
# compute the full binomial probability distribution for both variants
# and compare the theoretical PMF to the binomial theorem expansion
BASELINE_RATE = 0.10 # control conversion rate (p_control)
MDE = 0.03 # minimum detectable effect (absolute)
VARIANT_RATE = BASELINE_RATE + MDE # 13% variant rate
N_TRIALS = 200 # sample size per variant
def binomial_pmf_exact(n: int, p: float) -> pd.DataFrame:
""" Compute the exact binomial PMF for X ~ Bin(n, p) using the binomial theorem. P(X = k) = C(n, k) * p^k * (1-p)^(n-k) Args: n: Number of trials. p: Success probability per trial. Returns: DataFrame with columns: k, coefficient, p_k, 1-p_nk, pmf, cdf. """
q = 1 - p
rows = []
cumulative = 0.0
for k in range(n + 1):
coeff = comb(n, k)
pmf_k = coeff * (p ** k) * (q ** (n - k))
cumulative += pmf_k
rows.append({ "k": k, "C(n,k)": coeff, "p^k": p ** k, "(1-p)^(n-k)": q ** (n - k), "pmf": pmf_k, "cdf": cumulative, })
return pd.DataFrame(rows)
control_pmf = binomial_pmf_exact(N_TRIALS, BASELINE_RATE)
variant_pmf = binomial_pmf_exact(N_TRIALS, VARIANT_RATE) # Summary statistics
control_mean = (control_pmf["k"] * control_pmf["pmf"]).sum()
variant_mean = (variant_pmf["k"] * variant_pmf["pmf"]).sum() # Probability of observing k >= threshold under each variant
k_threshold = int(np.ceil(N_TRIALS * (BASELINE_RATE + MDE / 2)))
p_exceed_control = 1 - control_pmf.loc[control_pmf["k"] < k_threshold, "pmf"].sum()
p_exceed_variant = 1 - variant_pmf.loc[variant_pmf["k"] < k_threshold, "pmf"].sum()
print(f"Binomial PMF via Binomial Theorem: P(X=k) = C(n,k)·p^k·(1-p)^(n-k)")
print(f"n = {N_TRIALS} | control p = {BASELINE_RATE} | variant p = {VARIANT_RATE}")
print("=" * 72)
print(f"{'Metric':<30} {'Control':>12} {'Variant':>12}")
print(f"{'Expected conversions E[X]':<30} {control_mean:>12.2f} {variant_mean:>12.2f}")
print(f"{'P(X >= ' + str(k_threshold) + ')':<30} {p_exceed_control:>12.4f} {p_exceed_variant:>12.4f}")
print(f"{'PMF sums to 1 (verify)':<30} {control_pmf['pmf'].sum():>12.8f} {variant_pmf['pmf'].sum():>12.8f}")
print(f"\nNote: PMF sum = 1 is guaranteed by the binomial theorem: Σ C(n,k)·p^k·(1-p)^(n-k) = (p + 1-p)^n = 1^n = 1")Professional example (R)
# A/B test power: binomial PMF for control vs variant using binomial theorem
BASELINE_RATE <- 0.10
MDE <- 0.03
VARIANT_RATE <- BASELINE_RATE + MDE
N_TRIALS <- 200
binomial_pmf_exact <- function(n, p) { k <- 0:n
pmf <- choose(n, k) * p^k * (1 - p)^(n - k) data.frame(k = k, pmf = pmf, cdf = cumsum(pmf))
}
control_pmf <- binomial_pmf_exact(N_TRIALS, BASELINE_RATE)
variant_pmf <- binomial_pmf_exact(N_TRIALS, VARIANT_RATE)
control_mean <- N_TRIALS * BASELINE_RATE
variant_mean <- N_TRIALS * VARIANT_RATE
k_threshold <- 25
p_exceed_control <- 1 - sum(control_pmf$pmf[control_pmf$k < k_threshold])
p_exceed_variant <- 1 - sum(variant_pmf$pmf[variant_pmf$k < k_threshold])
cat(sprintf("n = %d | control p = %.2f | variant p = %.2f\n", N_TRIALS, BASELINE_RATE, VARIANT_RATE))
cat(sprintf("E[X] control: %.2f variant: %.2f\n", control_mean, variant_mean))
cat(sprintf("P(X >= %d) control: %.4f variant: %.4f\n", k_threshold, p_exceed_control, p_exceed_variant))
cat(sprintf("PMF sum control: %.8f variant: %.8f\n", sum(control_pmf$pmf), sum(variant_pmf$pmf)))Source: AIO p. 43