LearnThatStack Ace your next interview

Statistics & Experimentation.
Cheat sheet.

Quick reference for Statistics & Experimentation - sectioned for fast scanning. Skim the part you're shaky on, walk in confident.

Machine Learning & Data Science 9-section reference ~13 min read

30-second mental model

  • A p-value measures surprise under the null. The interval measures precision. Neither measures value.
  • Decide on the effect size and its interval, not on clearing 0.05.
  • Fix the metric, the sample size, and the end date before data lands. Everything chosen afterwards is storytelling.
  • Randomization is the only assumption you control. Every other causal method trades it for a belief.

Reading a result

Say what a p-value does and does not mean

Reading Verdict
"If nothing changed, results this extreme happen this often" Correct
"Probability the null is true" Wrong
"Probability this result is a fluke" Wrong
"The effect is big / important" Wrong - p = 0.01 on a 0.05% lift is worthless
p from a test stopped when it dipped below 0.05 Meaningless - see peeking below

Read a confidence interval

A 95% CI comes from a procedure that captures the truth in 95% of repeated samples. Your one interval either contains it or not.

Interval on conversion lift What to do
[-0.1%, +4.3%] Inconclusive - underpowered, get more data
[-0.2%, +0.3%] Real answer: any effect is too small to care about
[+1.8%, +2.4%] Ship, and quote the range not the point

Not "95% probability the truth is in here", not "95% of users", not "95% of future results".

Convert significance level to confidence level

confidence = 1 - alpha. alpha = 0.05 pairs with a 95% interval, and for a standard two-sided test the interval excludes the null exactly when p < 0.05.

The equivalence breaks near the boundary for score/Wilson intervals, bootstrap intervals, and one-sided tests.

Choose one-tailed or two-tailed

Threshold at 5% Cost
Two-tailed 97.5th percentile Default. Harder to clear
One-tailed 95th percentile Blind to harm - an 8% drop reads as "not significant"

Use one-tailed only when a move in the opposite direction leads to the same decision as no move. That is rare. Never pick the tail after seeing the data.

Name the error you are trading

Meaning Controlled by
Type I Claimed an effect that is not there alpha (significance level)
Type II Missed an effect that is there power (1 - beta)

With a fixed sample, tightening one loosens the other. Only more data shrinks both. Set alpha by which mistake costs more: shipping a dud burns time and pollutes baselines; killing a real winner costs revenue silently forever.

Quote a prediction interval for a single case

CI covers a parameter (the mean) and shrinks with n. A prediction interval covers the next single observation and never shrinks below the population spread.

mean delivery 3 days, 95% CI [2.9, 3.1]   // how well we know the average
                95% PI  [1, 7]            // what one parcel actually does

Quoting the CI to a customer is how you manufacture broken promises.

Sizing and powering a test

Compute sample size per arm

Inputs: baseline rate, minimum detectable effect (MDE), alpha, power.

// two-sided, alpha = 0.05, power = 0.80  ->  n ~= 16 * variance / effect^2
const variance = 0.05 * 0.95;            // 5% baseline conversion
const n = 16 * variance / (0.005 ** 2);  // 30,400 per arm for +0.5pp absolute
  • Revenue-style metrics have far larger variance than rates - budget much more traffic.
  • Each extra variant raises the count each arm needs.
  • Sample size scales with 1 / effect^2: halving the MDE quadruples the traffic.

Pick the minimum detectable effect

The MDE comes from the decision, never from the traffic you have. Ask what lift would justify the build and the risk. If that number needs more users than a month supplies, say the test cannot answer the question.

Read 80% power correctly

Power is the chance of detecting an effect of the size you designed for. 80% power = a 1-in-5 miss rate at that size, and much worse for smaller true effects.

A flat result at 80% power is weak evidence of nothing. Report the interval, not a verdict.

Buy power with: more users, longer run, variance reduction (CUPED, stratification), or a bigger MDE.

Choose primary and guardrail metrics

Want Rule
Primary metric Exactly one, fixed before launch, per-user, as close to value as traffic allows
Recommender test Purchases or engaged sessions, not homepage CTR
Button/color test Completed purchases per visitor, clicks are diagnostic only
Guardrails (veto power) Latency, error/crash rate, refunds, unsubscribes, total revenue
Vanity metrics to refuse Raw totals: pageviews, sessions, cumulative signups - they rise with traffic and season

Decide how long to run

  • Minimum one full week, usually two: weekday and weekend users differ, and two weeks covers a purchase or renewal cycle.
  • Hitting the sample size in two days does not end the test.
  • Longer is not free: cookie churn dilutes assignment and the test queue backs up.
  • Write the end date down before launch and let the analysis wait.

Assigning traffic

Bucket users deterministically

const bucket = hashInt(`${userId}:${experimentId}`) % 1000;
const arm = bucket < 500 ? 'control' : 'treatment';  // stable across sessions

Buckets are numbered slots: give 1% to a risky arm, widen to 50% later, reserve a range as a holdout, all without remapping anyone.

Two traps: no per-experiment salt means the same users are always in treatment; id % 2 skips the hash and maps signup order onto arms.

Pick the randomization unit

Unit Use when Cost
User id Logged in Cleanest
Cookie / device Anonymous traffic One person can see both arms
Session Almost never for UX changes Inconsistent experience
Cluster (city, market, community) Users influence each other Power collapses - see interference

Analyze only users who were actually exposed to the surface under test; counting the unexposed shrinks the detectable effect.

Verify assignment was actually random

  1. Sample ratio mismatch (SRM): chi-square the observed split against the intended one. 50.4/49.6 over 2M users is not luck - it is broken assignment or logging. Hard stop.
  2. Pre-period balance: compare country, platform, tenure, and last month's primary metric across arms.
  3. Do not over-read: check 20 covariates and one will hit p < 0.05 by chance. Covariate gaps need a much higher bar than SRM.

Usual causes: bots in one arm, a redirect dropping slow clients, exposure logged only inside the treatment code path.

Diagnosing a result

The test came back flat

Read the interval first. [-3%, +4%] could never have seen a 2% lift - the honest word is inconclusive, not "no effect". Then check in order:

Cause Check
Dilution What share of assigned users were actually exposed?
Broken plumbing Did the treatment render? Did both arms get the same experience?
Wrong metric Did the change move an earlier step you did not measure?
Real null Interval tight around zero + clean instrumentation - believe it and move on

The in-flow lift is 40% but overall moved 2%

Dilution explains nearly every gap this size. 40% is on the 5% of traffic that reached the new flow.

  • Check exposure share, whether the jump sits in one narrow segment, and whether 40% is relative on a tiny base (0.5% -> 0.7% is +40% relative, +0.2pp absolute).
  • Report both: exposed-user effect says whether the feature works; all-assigned effect says what shipping is worth.

Quoting 40% to leadership when the company will only ever feel 2% is the trap.

A rate improved while volume fell

CTR rose because impressions (the denominator) fell. Look at the numerator alone: if clicks fell too, the product delivered less value.

  • Stricter relevance filter = deliberate tradeoff, possibly fine. Rendering bug = not fine. Same rate move, opposite meaning.
  • Decide on absolute clicks, sessions per user, or downstream conversion - far less gameable than a ratio.
  • Ratio metrics need bootstrap over users or the delta method; treating impressions as independent units understates variance.

The winner faded after launch

Cause Signature Fix
Novelty Effect shrank day over day inside the test window Read late-window effect, or new-user-only cohort
Winner's curse Effect measured at the moment it crossed the threshold Expect regression; rerun or hold back
Population shift Test ran on an active slice, launch covers everyone Segment the launch read
Seasonality Baseline moved underneath Compare against a concurrent control

Keep 5% of users on control after launch and read the gap over the following month.

Ten variants and one wins at p < 0.05

const anyFalsePositive = 1 - Math.pow(0.95, 10);  // 0.401 -> 40% chance of a fake winner
Correction When
Bonferroni (alpha / k, so 0.005) Few comparisons, false positives are expensive
Benjamini-Hochberg (FDR) Screening many ideas at once - gentler, keeps power
Rerun the single winner vs control Usually the cheapest and most convincing. A real effect repeats

Someone peeked daily and stopped at 0.05

The 5% guarantee covers one planned analysis. Peeking daily for two weeks pushes the real false positive rate toward 20% or higher, and the effect at the stopping point is biased upward because you only stop when noise favors you.

If you must monitor: sequential / group sequential boundaries that spend the error budget across looks, or Bayesian monitoring. Fixed 0.05 plus daily peeking is the one option that quietly lies.

One metric rose and another dropped

Only ship if the exchange rate was agreed before the test ran.

  • Guardrails (crash, latency, errors, unsubscribes) get a veto, not a trade.
  • Genuine tradeoffs (revenue vs sessions) convert into one currency.
  • Check the shape: a 1% average drop is often a 6% drop concentrated in new users.
  • Check they are not one effect counted twice.
  • Time asymmetry usually settles it: engagement gains fade, retention damage compounds. When close, ramp partially with a long-run holdback.

When you cannot randomize

Decide not to run a test

Skip when the test cannot answer the question or costs more than the decision: low traffic (six months to power = stalling), legal/security/rebrand changes, strong network effects, one-shot launches, market-wide changes like pricing.

Instead Key assumption to defend
Difference-in-differences Parallel pre-trends - plot them
Regression discontinuity Credible only near the cutoff
Synthetic control / interrupted time series Blend of untreated units tracks the treated one pre-launch
Switchback (flip whole market on a schedule) Washout gap absorbs carryover
Staged rollout on guardrails + session replay No causal claim, just harm detection

Test the assumption, not just the estimate: rerun the model on a fake launch date and confirm it finds nothing. Report the number with its assumption attached.

Limit interference between arms

Randomize above the boundary where users affect each other: cluster by market/city/graph community, switchback by time slice, or split the resource (inventory, driver supply, ad budget) per arm.

  • Power now scales with the number of clusters, not users. Thirty cities detects only large effects.
  • Cluster sizes are unequal: analyze cluster means or use ratio estimators with cluster-robust variance.
  • Watch invisible shared state: caches, pacing budgets, and any model retrained on pooled logs carry treatment into control.

Fix standard errors when users are correlated

variance inflation ~= 1 + (m - 1) * ICC
ICC = 0.05, m = 100  ->  ~6x the reported variance

Use cluster means, cluster-robust standard errors, and a bootstrap that resamples clusters instead of users. Effective sample size is the number of independent units, not the number of events.

Separately, the estimand shifts: control users are partly treated by neighbors, so in a marketplace the measured lift can beat any achievable global gain. Model exposure (share of a user's neighbors in treatment), fit dose-response, and confirm with a market-level holdout.

Measure a metric that takes two months to mature

Split into a fast read and a slow read.

  • Fast: a surrogate metric validated on past experiments where you hold both the early signal and the mature outcome. A surrogate that worked for pricing will mislead on onboarding.
  • Slow: a long-term holdback - ship to most traffic, keep a small population untreated, read the mature metric when it lands. Start the clock early; extra traffic cannot buy calendar time.
  • Holdbacks decay: two months of logged-out sessions, reinstalls, and device switches, and the attrition is not random. One permanent shared holdout beats a per-feature one.

Causal reasoning

Choose what to adjust for

Draw a DAG (nodes = variables, arrows = cause -> effect, no loops) before touching the data.

Variable type Definition Action
Confounder Causes both treatment and outcome Adjust
Mediator Sits on the causal path Do not adjust - it erases the effect
Collider Caused by both sides Do not condition - it invents correlation

"Control for more variables" is not safer. And a DAG is an assumption: data cannot tell you which way an arrow points.

Spot Simpson's paradox

A trend holds in every subgroup and reverses when pooled, because the mix is unequal.

desktop:  B 10%  vs A 9%      B wins
mobile:   B  4%  vs A 3%      B wins
pooled:   B loses   (B is 80% mobile; mobile converts worse for everyone)

Split on a variable only when it causes the outcome and exists before assignment. Splitting on something the treatment itself caused hides the effect. Randomization usually balances the mix; quarter-over-quarter comparisons never do.

Separate correlation from causation

Correlation is symmetric and cheap; causation is directional and needs an intervention or a mechanism. When two variables move together, name the three rivals before believing the story: confounder, reverse causation, self-selection.

"App users spend more" is almost always heavy spenders installing first. Randomize who gets nudged to install.

Distributions, sampling, correlation

Pick the distribution

Situation Distribution Params
Successes out of a known n (conversions / visitors) Binomial mean np, var np(1-p)
Events per window with no fixed n (tickets per hour) Poisson mean = var = lambda
Counts where variance far exceeds the mean Negative binomial over-dispersion
Sums of many small influences, sample means Normal mean, sd
  • Binomial requires independent trials with the same p. Real users break both (repeat visits, heavy buyers), so true spread exceeds np(1-p) and your error bars are too narrow.
  • Poisson assumes mean = variance. Incidents and hourly clustering break it - fitting Poisson to over-dispersed counts gives intervals that are far too tight.
  • Normal sanity check with 68-95-99.7: mean 5 min, sd 4 puts two sd below zero, so the data is not normal. Skewed metrics like revenue break the rule badly.

Check the CLT actually applies

Needs: independent, identically distributed, finite variance.

  • n = 30 is enough only for mildly skewed data. Revenue per user can stay skewed at n in the thousands - bootstrap the mean and look at its shape.
  • Heavy tails (near-Cauchy: file sizes, insurance losses) never settle.
  • Independence breaks first in practice: repeated events from one user mean effective n = number of users.
  • When a handful of users can move the mean, cap or trim rather than trusting the theorem.

Build a confidence interval for a proportion

const r = k / n;                                  // 6/10 = 0.6
const half = 1.96 * Math.sqrt(r * (1 - r) / n);   // 0.304  (Wald)
Situation Use
Large n, rate away from 0 and 1 Wald (above)
Small n, or rate near 0 or 1 Wilson or Clopper-Pearson
Weird estimator, ratio metric Bootstrap: resample, read 2.5th and 97.5th percentiles

At zero successes Wald collapses to zero width and claims certainty from nothing.

Get a two-tailed p-value from counts

// 1 head in 10 flips. H0: fair coin, p = 0.5, flips independent.
// p-value = P(X <= 1) + P(X >= 9) under Binomial(10, 0.5)
const p = 2 * (1 + 10) / 1024;  // 0.0215 -> reject fairness

The p-value is the tail, not the point probability of exactly what you saw. And 1 in 20 fair coins lands here - flip more.

Measure correlation

Data Measure Note
Two numeric, linear Pearson r -1 to 1, unit-free
Curved or outlier-heavy Spearman rank Ranks first, one extreme point cannot dominate
Two categorical Cramer's V Pearson does not apply

Plot the scatter first. Pearson 0.8 next to Spearman 0.3 means a handful of rows do all the work. Pearson near zero with an obvious U shape means you measured the wrong thing.

Pick a sampling design

Design Use when Cost
Simple random You have a full population list Cleanest math
Systematic (every kth) Cheap draw from an ordered list Fails on repeating cycles
Stratified A small segment would be missed by chance Needs the group label up front; reweight to population shares
Cluster (stores, shifts, cities) Field work, interference Wider error bars
Convenience Never Bakes in whatever made those units easy to reach

Stratifying buys variance reduction only when the strata differ on the metric. With 3% enterprise customers, a random sample of 500 pulls ~8 of them and swings wildly.

Logs from a single region are a convenience sample in a warehouse costume.

Keep conditional probabilities pointing the right way

P(A and B) = P(A|B) * P(B). Sum a joint table across a row to get a marginal; divide a joint by a marginal to get a conditional.

1,000 users, 400 mobile, 100 of those churned
joint  P(mobile and churn) = 10%
marginal P(mobile)         = 40%
conditional P(churn|mobile)= 25%

"Most churners are on mobile" is P(mobile|churn). "Mobile users churn more" is P(churn|mobile). Only the second justifies rebuilding the app.

Common pitfalls

  • Choosing the metric, the threshold, or the tail after seeing results.
  • Stopping the moment p dips under 0.05.
  • Filtering on post-assignment behavior ("engaged users only") - it rebuilds the bias randomization removed.
  • Reporting a rate without its denominator, or a relative lift without the absolute.
  • Calling an underpowered flat result "no effect".
  • Adjusting for a mediator or conditioning on a collider.
  • Trusting np(1-p) or Poisson variance on clustered real-user data.
  • Averaging percentiles, or averaging a stratified sample without weights.
  • Comparing a freshly retrained model against a stale control - that measures staleness, not the algorithm.
  • Quoting a confidence interval as a promise about a single case.
Found this useful? Pass it on.
Pro · $10/mo

The sheet is free. Pro goes deeper.

Pro opens the full question library behind every sheet, every refresher and a monthly AI allowance. One subscription, all formats.

Full question library All refreshers Cancel anytime