Breadth: classic ML, evaluation and A/B testing
Before this lesson: a first course in machine learning and in statistics (hypothesis tests, the normal distribution). For the code of AUC and logistic regression, see lesson 06. Depth on these topics is in a first ML course and in the Probability and Statistics track; canary releases and peeking in production are in MLOps lesson 06. Time: about 85 minutes, plus the notebook.
Why this matters #
Breadth questions come in phone screens, in "ML knowledge" rounds and in data-science loops. They test whether you give a short, correct, structured answer quickly. Common failures are an answer that runs for five minutes, a wrong basic definition (precision vs recall), or no number at all.
A good breadth answer has four parts and takes 30 seconds to 2 minutes:
- one sentence that defines the thing;
- the formula or the mechanism;
- one trade-off, or when to use it;
- one number or one example.
The same tools matter in ML for science. Evaluation design decides whether a weather or medical model is tested honestly (spatial, temporal and patient-level leakage). Calibration decides whether a probabilistic forecast can be trusted. And "is model B better than model A?" is a hypothesis test on a fixed test set.
1. Predict first #
2. The picture #
2.1 Error has three sources #
Fix one input . The prediction error there comes from three sources:
- noise in the label, which no model can remove;
- bias: the average model (over many training sets) is offset from the truth;
- variance: the fitted model moves when you draw a new training set.
A constant predictor has large bias and almost no variance. A 1-nearest-neighbour predictor has small bias and large variance. Most choices in classic ML (model size, regularization, the number of neighbours, ensembles) move error between bias and variance.
Move the degree slider and watch the 20 faint fits, each trained on a new random training set of 15 points. The thick orange curve is their average, and the dashed curve is the true function. At degree 0–1 the average is far from the truth (bias). At degree 9–10 the average is close to the truth, but the single fits swing wildly (variance). The lower chart shows bias², variance and the noise for every degree; their sum is the expected test error, a U-shaped curve. The average training error only falls as the degree grows.
2.2 L1 gives zeros, L2 does not #
Regularization adds a penalty on the weights to the loss. With an L2 (ridge) penalty the weights shrink towards zero but stay nonzero. With an L1 (lasso) penalty many weights become exactly zero. The picture: minimize the loss inside a ball. The L1 ball is a diamond with corners on the axes, and the smallest loss contour often touches it at a corner, where one coordinate is 0.
Drag the centre of the ellipses (the unregularized solution) and shrink the radius. The L1 solution (diamond) often sits on a corner, so one weight is exactly 0. The L2 solution (disk) almost never lands on an axis. Ask yourself: why does the corner win so often?
2.3 A classifier is a ranking plus a threshold #
A classifier gives each example a score. Three different questions follow, and each has its own metrics:
- Does the score rank positives above negatives? (ROC-AUC, average precision.)
- At the chosen threshold, how many alarms are right, and how many positives are found? (precision, recall, .)
- Is the score a probability: of the cases scored 0.8, are 80% positive? (calibration, log-loss, Brier score.)
Move the prevalence slider from 50% down to 0.5% (the fraud preset) and keep the threshold. The ROC curve and its AUC do not move: TPR and FPR are each computed inside one class. The PR curve, the precision and the number of false alarms per caught positive change a lot, because precision compares the two classes in absolute numbers. Then move the threshold and watch precision and recall trade against each other. The areas right of the threshold are the true positives and the false positives.
2.4 An A/B test is two noisy coins #
In an A/B test, each user converts with some probability . The rate of one arm with users has standard error . The difference of two independent arms has standard error . To see a true difference reliably, must be about 2.8 standard errors: 1.96 for the test at , plus 0.84 for power 0.8. Solve for :
Small effects need many users, because grows like : half the effect needs four times the users.
Find the number of users that gives 80% power. The blue curve is the distribution of the observed difference when there is no effect; the orange curve, when the true lift is the MDE. The test rejects outside the dashed lines. Power is the orange area outside them. Move until the power reads 0.80, then halve the MDE and see how far must move.
Your model has training error 2% and validation error 15%. Which change is most likely to reduce the validation error?
A large gap between training and validation error is the sign of high variance (overfitting). More data lowers the variance and does not change the bias; stronger regularization trades a little bias for less variance. A more flexible model, longer training or a smaller all lower bias and raise variance, so they make the gap worse. Also check that training and validation come from the same distribution.
In the orthonormal case the lasso solution is . With and least-squares weights , what is ?
Soft thresholding moves every weight towards zero and stops at zero: , (because ), . The first option is ridge-like shrinkage by a factor , which never gives exact zeros.
3. Definitions and main results #
3.1 Bias and variance #
Setting. Let with and . A model is fitted on a random training set . The new noise at the test point is independent of . Let be the average fit over training sets.
Theorem (bias–variance decomposition, squared loss). At a fixed input ,
Why this is true, in one line. We split the error into three pieces that are "uncorrelated", so the squares add like the sides of a right triangle.
Proof.
- Add and subtract and : .
- Square: . Take the expectation over and .
- , because is a constant.
- , because is independent of .
- .
- What remains is .
Two small examples.
- -nearest neighbours (regression). Suppose the neighbours of have independent labels with noise variance . The prediction is the mean of labels, so its variance is . Larger lowers the variance, but uses neighbours farther from , whose values differ from : the bias grows.
- Constant model (the training mean). Its variance is small (about ), but its bias at is , large wherever is far from its average.
| Change | Bias | Variance |
|---|---|---|
| more flexible model (deeper tree, more features, smaller in -NN) | down | up |
| stronger regularization (larger , early stopping) | up | down |
| more training data | same | down |
| average many bagged models | about the same | down, to a floor (section 3.3) |
| more boosting rounds | down | up, eventually |
Diagnosis from learning curves. High bias: the training error is high and the validation error is close to it; use a more flexible model or better features. High variance: the training error is low and the gap to validation is large; get more data, regularize, or average models. A large gap can also mean that training and validation data differ (shift or leakage), so check that too.
Beyond squared loss, and double descent
The clean additive decomposition holds for squared loss. For the 0–1 loss of classification the terms do not add up this way, although "bias" and "variance" are still useful words. Very large models can show double descent: the test error rises to a peak where the model can just interpolate the training data, and then falls again as the model grows further. Explicit or implicit regularization (for example, the minimum-norm solution that gradient descent finds) lowers the variance beyond that peak. See the deep learning lesson on generalization.
3.2 L1 vs L2 regularization #
- Ridge (L2): minimize . The solution is , and the matrix is invertible for every . Ridge shrinks all weights towards 0 but keeps them nonzero. With correlated features it shares the weight among them.
- Lasso (L1): minimize . In the simplest case, an orthonormal design (, least-squares solution ), it acts on each coordinate alone:
Every becomes exactly 0. Ridge in the same case, with penalty , gives : never exactly 0.
- Why zeros. The slope of near 0 is : it does not vanish. So a small weight must "pay" per unit, and if the loss gains less than that, the weight stays at 0. The slope of near 0 is , so a tiny nonzero weight is almost free.
- Bayesian (MAP) view. With Gaussian noise of variance , a Gaussian prior gives ridge (with for the penalty ). A Laplace prior gives the lasso (with ). The Laplace density has a sharp peak at 0, which is where the exact zeros come from.
- In practice. Standardize the features first (the penalty is not scale invariant). Do not penalize the intercept. With a group of correlated features the lasso picks one of them almost at random; the elastic net (penalty ) keeps the group. Choose by cross-validation.
3.3 Trees, bagging and boosting #
Decision trees (CART). A tree splits greedily. At each node it picks the feature and the threshold with the largest decrease of weighted impurity. For classification with class fractions in a node:
For regression the impurity is the sum of squared errors. Trees need no feature scaling, handle mixed feature types and interactions, and are easy to read. They have high variance, and their piecewise-constant predictions cannot extrapolate beyond the training range.
Proposition (variance of an average). Let each have variance and pairwise correlation . Then
Proof.
- .
- Divide by : .
More trees remove only the second term; the floor stays. Bagging trains deep trees on bootstrap samples (draw points with replacement). A random forest also picks each split from a random subset of the features (often of the features for classification); this lowers . Each point is left out of a bootstrap sample with probability . So the trees that did not see a point give a nearly free test estimate for it: the out-of-bag (OOB) error.
Gradient boosting is gradient descent in function space. Start with the best constant . At each round :
- compute the pseudo-residuals , the negative gradient of the loss with respect to the current prediction. For squared loss this is , the ordinary residual;
- fit a small tree to the pairs ;
- set each leaf value by a line search on the loss;
- update with a learning rate (shrinkage) , often 0.05–0.1.
Why "gradient descent": if we could change each prediction freely, the steepest-descent step would be . A tree cannot fit every exactly, so it fits the best approximation of this step that generalizes to new .
XGBoost's leaf weight
XGBoost takes a second-order (Newton) step. With and the sums of the first and second derivatives of the loss over the examples in a leaf, and an L2 penalty on the leaf weights, the best leaf weight is . For squared loss is the number of examples in the leaf, so is a shrunk mean residual. LightGBM and CatBoost are other popular implementations with different tree-growing and categorical-feature strategies.
| Bagging / random forest | Boosting | |
|---|---|---|
| training | parallel, independent trees on bootstrap samples | sequential; each tree fits the errors of the current ensemble |
| base learner | deep trees: low bias, high variance | shallow trees (depth 3–8): high bias, low variance |
| mainly reduces | variance | bias |
| more trees | the error converges; no extra overfitting | overfits eventually; use early stopping |
| tuning | few knobs, robust | learning rate, rounds, depth, regularization |
| typical use | strong baseline with an OOB estimate | best accuracy on tabular data |
3.4 Metrics #
With true and false positives and negatives :
| Metric | Formula | In words |
|---|---|---|
| precision | how many alarms are right | |
| recall (TPR, sensitivity) | how many positives are found | |
| harmonic mean of precision and recall | ||
| FPR | how many negatives raise an alarm | |
| accuracy | misleading when one class is rare |
- ROC-AUC is the area under the curve of TPR against FPR over all thresholds. It equals for the score of a random positive and of a random negative. So it measures ranking only. It does not change under any increasing transform of the scores, and it does not depend on the class ratio, because TPR and FPR are each computed inside one class.
- PR curve and average precision (AP). Precision mixes the two classes, so it depends on the class ratio. A random ranking has AP about equal to the prevalence. With rare positives, report AP and the precision at the operating threshold.
- Proper scores and calibration. Log-loss and the Brier score are minimized in expectation by the true probability. A reliability diagram plots the observed frequency of positives against the predicted probability, in bins; a calibrated model lies on the diagonal. Fix a miscalibrated model on held-out data: temperature scaling (divide the logits by one ; standard for neural networks), Platt scaling (a logistic regression on the score), or isotonic regression.
- Multi-class: macro averaging gives each class the same weight; micro averaging pools all decisions, so large classes dominate.
- Regression: MSE is minimized by the conditional mean and punishes outliers strongly; MAE is minimized by the conditional median and is robust. MAPE, the mean of , is undefined at and punishes over-prediction more than under-prediction.
Proposition (threshold from costs). A false alarm costs and a missed positive costs . If is calibrated, flagging has lower expected cost exactly when
Proof. Flagging costs in expectation (a false alarm when ). Not flagging costs (a miss when ). Flag when , that is .
For example, if a missed fraud costs 20 times a false alarm, flag when .
3.5 Evaluation design and leakage #
-
Three sets. Train to fit, validation to choose, test to report, used once. For a model choice and an honest estimate from little data, use nested cross-validation.
-
-fold cross-validation. Stratify by class for classification. Split by group when examples are not independent: one patient, one user or one weather station in one fold only. For time series, train on the past and test on the future, with a gap. For spatial fields, use blocks larger than the correlation length.
-
Leakage is information in the training data or features that is not available at prediction time:
- target leakage: a feature recorded after the outcome (for example "refund issued" to predict fraud);
- preprocessing on all data: a scaler, PCA, feature selection or target encoding fitted before the split;
- duplicates or near-duplicates across splits;
- a random split of time series or grouped data.
Fix: fit every preprocessing step inside the training fold (a pipeline), and split by time or group when the data has that structure.
-
Class imbalance. Keep the natural class ratio in validation and test. Class weights or resampling change the effective prior, so the predicted probabilities are no longer calibrated; recalibrate, or keep the data as it is and move the threshold.
-
Offline vs online. An offline metric is a proxy for the product goal. The online A/B test is the final judge.
3.6 Probability questions #
Interviews often ask one short probability question. Three types cover most of them.
Bayes' rule with a base rate. A disease has prevalence 0.5%. A test has sensitivity 99% () and specificity 99% (). A person tests positive. What is ?
The natural-frequency check makes it easy to say aloud: of 100,000 people, 500 are sick and 495 of them test positive. Of the 99,500 healthy people, 1% (995) also test positive. So of the positives are sick. The false positives win because the healthy group is 200 times larger. This is the same effect as low precision under class imbalance.
Linearity of expectation. always, even for dependent variables. Example: shuffle cards numbered . The expected number of cards in their own position is 1. Let if card is in position ; then , and , for every . The are dependent, and it does not matter.
A first-step equation. How many fair coin flips, on average, until two heads in a row? Let be the expected number of further flips from the start, and the number after one head. Condition on the next flip:
- (a head ends the game; a tail starts over);
- .
Substitute the first into the second: , so and .
How to answer aloud. Name the events. Write the formula with symbols first. Plug in the numbers. Then check with natural frequencies or an extreme case (for example, "with prevalence 50% the answer would be 99%").
A test has sensitivity 90% and specificity 95%. The prevalence is 1%. About what fraction of the people who test positive have the condition?
Of 10,000 people, 100 are sick and 90 test positive. Of 9,900 healthy people, 5% (495) test positive. So . The sensitivity is , not ; mixing them up is the base-rate fallacy.
3.7 Hypothesis tests and A/B testing #
Words. The null hypothesis says "no difference". A type I error rejects a true ; its probability is the level . A type II error keeps a false ; its probability is , and the power is . The p-value is the probability, computed under , of a test statistic at least as extreme as the one observed. It is not the probability that is true. The minimum detectable effect (MDE) is the smallest effect that is worth detecting. It is a business choice, not the effect you hope for.
Two-proportion z-test. With conversions out of users in arm , rates and pooled rate :
Reject at level when (1.96 for ). For a table this is the same test as the test without continuity correction: .
Theorem (sample size per arm). Let the metric have per-user variance in control and in treatment, with users per arm and true difference . With the normal approximation, a two-sided test at level has power when
where is the -quantile of the standard normal distribution.
Proof.
- The difference of the two means, , has standard error (independent arms; central limit theorem).
- The test rejects when .
- Under the alternative, . Ignore the tiny chance of rejecting in the wrong direction. Then , with the standard normal CDF.
- Power means , so .
- Substitute from step 1, square, and solve for .
Rule of thumb. With , and power 0.8: , so per arm. For a conversion rate , .
What the formula says.
- : half the MDE needs four times the users.
- : a metric with less variance needs fewer users (conversion instead of revenue, or variance reduction with CUPED below).
- An unequal split with a fraction in treatment needs about times as many users in total as a 50/50 split: 2.8 times for 90/10.
Design checklist.
- A hypothesis and one primary metric (the overall evaluation criterion), plus guardrail metrics such as latency, errors and revenue.
- The unit of randomization, usually the user.
- Baseline, MDE, and power → per arm.
- Duration: divided by the eligible users per arm per day, rounded up to full weeks.
- Checks: an A/A test (two identical arms; it should reject about 5% of the time) and a sample-ratio check.
- The analysis plan and the decision rule, fixed before the start.
- Report the effect with a confidence interval, and ask whether it is practically large enough, not only significant.
Pitfalls and their fixes.
- Peeking. Checking every day and stopping at the first inflates the type I error: about 0.08 with 2 looks, 0.14 with 5, 0.19 with 10, and 0.25 with 20 equally spaced looks. Fix the sample size in advance, or use a sequential design built for many looks (alpha spending, always-valid p-values).
- Sample-ratio mismatch (SRM). The observed split differs from the design more than chance allows. Test the counts with a goodness-of-fit test and raise an alarm at about . An SRM means a bug in assignment, logging or filtering; do not trust the result until it is found.
- Novelty, primacy and day-of-week effects. Users react to change itself. Run full weeks, plot the effect by day, and compare new with returning users.
- Many metrics or variants. With 20 independent metrics at , . Choose the primary metric in advance; correct the others (Holm, or Benjamini–Hochberg for the false discovery rate).
- Interference. The analysis assumes that a user's outcome does not depend on the assignment of other users (SUTVA, the stable unit treatment value assumption). Social networks and two-sided marketplaces break it. Randomize clusters or markets, or use switchback designs (switch the whole system over time).
- Unit of randomization ≠ unit of analysis. If you randomize users but compute the click rate per page view, the naive variance is too small, because the views of one user are correlated. Analyze one value per user, or use the delta method or a user-level bootstrap.
- Changing the split during the test (for example 1% → 50%) can make the pooled totals show the reverse of every daily result (Simpson's paradox). Analyze the period with a fixed split.
Press "Run 2,000 A/A tests" with 1 look, then with 10 and 20 looks. Both arms are identical, so every rejection is a false positive. A path turns orange when it crosses at any look, and the experimenter stops there. The lower chart compares the simulated false-positive rate with the planned 5%.
A 50/50 test shows 50,600 users in control and 49,400 in treatment. The test of the counts gives . What is the right next step?
A sample-ratio mismatch this large almost never happens by chance. It means that some users were lost or added in one arm, often in a way that depends on the treatment (for example, a crash that drops engaged users). Then the arms are no longer comparable, and re-weighting or running longer does not fix the bias.
Variance reduction with CUPED
Replace the outcome by , where is the same metric measured before the experiment and . The variance falls by the factor , with the correlation of and : gives , so about half the users are needed. The estimate of the treatment effect stays unbiased, because is measured before randomization and so has the same distribution in both arms.
Answers to section 1. (1) About 60,000. The formula gives 57,760 per arm (57,763 with the pooled variance under ); the rule of thumb gives . (2) Ask for the precision at the operating threshold (or the AP). ROC-AUC ignores the class ratio. Suppose the threshold gives TPR 0.80 at FPR 0.05. Per 1,000,000 transactions there are 5,000 frauds and 995,000 normal ones: 4,000 frauds are caught, and normal transactions raise false alarms. Precision is : about 12 false alarms for every fraud caught.
SQL patterns for data rounds
Some loops add a SQL question on experiment logs. The logical order of a query is
FROM/JOIN → WHERE → GROUP BY → HAVING → window functions → SELECT → DISTINCT →
ORDER BY → LIMIT. Most bugs put a step in the wrong place.
- Joins.
LEFT JOINkeeps every left row and fillsNULLwhen nothing matches. A condition on the right table belongs in theONclause: inWHEREit removes theNULLrows and turns the left join into an inner join. Anti-join (rows without a match):NOT EXISTS (...). - NULL.
x = NULLis never true; useIS NULL.COUNT(*)counts rows,COUNT(col)counts non-NULLvalues.x NOT IN (subquery)returns no rows if the subquery contains aNULL. - Groups.
WHEREfilters rows before grouping;HAVINGfilters groups after it. - Window functions compute a value per row without collapsing rows:
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY ts).RANK()gives 1, 1, 3 for a tie andDENSE_RANK()gives 1, 1, 2. Top- per group:ROW_NUMBER()in a subquery, thenWHERE rn <= N.
Conversion rate per variant, with the user as the unit, from tables assignments(user_id, variant, assigned_at) and events(user_id, event, ts):
WITH per_user AS (
SELECT a.user_id, a.variant, COUNT(e.user_id) AS purchases
FROM assignments AS a
LEFT JOIN events AS e
ON e.user_id = a.user_id
AND e.event = 'purchase'
AND e.ts >= a.assigned_at -- only purchases after assignment
GROUP BY a.user_id, a.variant
)
SELECT variant, COUNT(*) AS users,
ROUND(AVG(CASE WHEN purchases > 0 THEN 1.0 ELSE 0.0 END), 3) AS conv_rate
FROM per_user
GROUP BY variant;
On a small test table (users 1–3 in A, 4–6 in B; users 1, 4 and 5 buy after assignment) this gives
A: 3 users, rate 0.333 and B: 3 users, rate 0.667. If you move the two purchase conditions to
WHERE, the users without purchases disappear and both rates become 1.0.
4. Worked example #
A. Metrics on ten examples. Four positives with scores 0.95, 0.85, 0.70, 0.45; six negatives with scores 0.80, 0.60, 0.40, 0.30, 0.20, 0.10.
- Threshold 0.5. The predicted positives are the scores 0.95, 0.85, 0.80, 0.70, 0.60. Of these, 3 are real positives. So , , (the 0.45), .
- Precision . Recall . . Accuracy .
- ROC-AUC by counting pairs. There are (positive, negative) pairs. The positive 0.95 beats all 6 negatives; 0.85 beats 6 (0.80 is lower); 0.70 beats 5 (not 0.80); 0.45 beats 4 (0.40, 0.30, 0.20, 0.10). Total , so AUC .
- Average precision. Sort by score: 0.95 (+), 0.85 (+), 0.80 (−), 0.70 (+), 0.60 (−), 0.45 (+), …. The positives arrive at ranks 1, 2, 4 and 6. The precision at those ranks is , , , . Each positive adds of recall, so AP .
- Now add six more negatives with the same scores (the prevalence falls from 40% to 25%). Recall stays and ROC-AUC stays : both are computed inside one class. Precision falls to , and AP falls to .
B. An A/B test from plan to decision. A new checkout page. Baseline conversion , MDE points (a 5% relative lift), two-sided, power 0.8.
- Sample size: per arm.
- Duration: 20,000 eligible users per day, split 50/50, give 10,000 per arm per day. days. Round up to 7 days (one full week), so about 70,000 per arm.
- Result: control has 7,024 conversions of 70,240 users (); treatment has 7,360 of 69,760 ().
- SRM check first. The expected count per arm is 70,000. , : no alarm. (With 70,700 vs 69,300 it would be , : stop and debug.)
- Test. Pooled . Then , and .
- 95% confidence interval of the difference, with the unpooled standard error 0.162 points: points. The effect is significant, and the whole interval is above zero. Whether a lift of 0.2–0.9 points pays for the change is a product decision.
The plan of example B needs 57,760 users per arm for an MDE of 0.5 points. The product team now wants to detect 0.25 points. About how many users per arm?
. Halving multiplies by 4: . The standard error falls only like , so to halve it you need four times the data.
5. In code #
Libraries check the numbers of section 4. The notebook has these cells and the exercises.
import numpy as np
from scipy import stats
from sklearn.metrics import (average_precision_score, confusion_matrix,
precision_recall_fscore_support, roc_auc_score)
# (A) metrics on ten examples
y = np.array([1, 1, 1, 1, 0, 0, 0, 0, 0, 0])
s = np.array([0.95, 0.85, 0.70, 0.45, 0.80, 0.60, 0.40, 0.30, 0.20, 0.10])
pred = (s >= 0.5).astype(int)
print(confusion_matrix(y, pred).ravel()) # tn fp fn tp: [4 2 1 3]
prf = precision_recall_fscore_support(y, pred, average="binary")[:3]
print(np.round(prf, 3)) # [0.6 0.75 0.667]
print(roc_auc_score(y, s), round(average_precision_score(y, s), 3)) # 0.875 0.854
y2, s2 = np.r_[y, y[4:]], np.r_[s, s[4:]] # six more negatives, same scores
p2, r2 = precision_recall_fscore_support(y2, (s2 >= 0.5).astype(int), average="binary")[:2]
print(round(p2, 3), r2, roc_auc_score(y2, s2), round(average_precision_score(y2, s2), 3))
# 0.429 0.75 0.875 0.775
# (B) sample size, SRM check, z-test and confidence interval
za, zb = stats.norm.ppf(0.975), stats.norm.ppf(0.80)
n = (za + zb) ** 2 * (0.10 * 0.90 + 0.105 * 0.895) / 0.005 ** 2
print(round(n)) # 57760
print(round(stats.chisquare([70240, 69760]).pvalue, 3)) # 0.2: no sample-ratio mismatch
print(round(stats.chisquare([70700, 69300]).pvalue, 5)) # 0.00018: mismatch, debug first
xa, na, xb, nb = 7024, 70240, 7360, 69760
pa, pb, pool = xa / na, xb / nb, (xa + xb) / (na + nb)
z = (pb - pa) / np.sqrt(pool * (1 - pool) * (1 / na + 1 / nb))
print(round(z, 2), round(2 * stats.norm.sf(abs(z)), 5)) # 3.39 0.00069
se = np.sqrt(pa * (1 - pa) / na + pb * (1 - pb) / nb)
print(np.round(100 * np.array([pb - pa - za * se, pb - pa + za * se]), 2)) # [0.23 0.87]
# (C) simulation: power at n = 57,760, and an A/A test
rng = np.random.default_rng(0)
def rejection_rate(p_a, p_b, n, reps=20_000):
a, b = rng.binomial(n, p_a, reps), rng.binomial(n, p_b, reps)
pool = (a + b) / (2 * n)
z = (b - a) / n / np.sqrt(pool * (1 - pool) * 2 / n)
return np.mean(np.abs(z) > za)
print(rejection_rate(0.10, 0.105, 57_760)) # 0.796 (about 0.80; Monte Carlo error 0.003)
print(rejection_rate(0.10, 0.100, 57_760)) # 0.049 (about 0.05: the A/A test)
6. Where it shows up #
- ML practice. Model selection is bias–variance in action. Offline metrics choose a candidate; an online A/B test decides, and offline and online results often disagree. Gradient-boosted trees (XGBoost, LightGBM, CatBoost) are still the default for tabular data.
- Rare events. Fraud, spam, defects and disease screening all have low prevalence. Precision at the operating point and the base-rate effect of section 3.6 decide whether the model is useful.
- ML for science. Random splits of gridded weather fields or seismic records leak through spatial and temporal correlation; use blocks in space and time, and keep all records of one station, patient or event in one fold. Probabilistic forecasts need calibration (reliability diagrams). Comparing two models on the same test cases is a paired test: bootstrap over the cases and report an interval.
- Product teams. Every launch decision for a ranking, recommendation or pricing model goes through an A/B test with the design checklist of section 3.7.
7. Common mistakes #
- "The p-value is the probability that is true." It is the probability of data at least this extreme, computed under .
- Accuracy or ROC-AUC alone on rare events. Report precision and recall at the operating point, or AP.
- Preprocessing on all data before cross-validation. Scaling, feature selection and target encoding must be fitted inside each training fold.
- Random splits of grouped or time-ordered data. Split by group or by time.
- Stopping an A/B test at the first , or ignoring a sample-ratio mismatch.
- Analyzing per page view while randomizing per user. The naive variance is too small.
- "Random forests cannot overfit." More trees do not add overfitting, but deep trees on noisy data still have variance, and the floor stays. "Boosting reduces variance" is also wrong as a main claim: boosting mainly reduces bias.
- Confusing sensitivity with . Always bring in the base rate.
8. Check yourself #
- 100 trees, each with variance 1 and pairwise correlation 0.3. What is the variance of their
average, and how do you lower it further?
Answer
. More trees can only remove the . To go lower, decrease (fewer features per split, more randomness) or the variance of each tree. - Baseline conversion 5%, relative MDE 10%, , power 0.8. How many users per arm
(rule of thumb)? And for a relative MDE of 5%?
Answer
, so per arm. Half the MDE needs 4 times as many: . - In worked example 4A, which of recall, precision, ROC-AUC and AP change when the test set gets
six more negatives with the same scores?
Answer
Recall (0.75) and ROC-AUC (0.875) do not change: each is computed inside one class. Precision () and AP () fall, because they depend on the class ratio. - A missed defect costs 50 and a false alarm costs 5. Your model is calibrated. Above which
probability do you flag a part?
Answer
. Flag when . - A colleague checks the A/B test every day for 10 days and stops when . What is the
false-positive rate, and what are two fixes?
Answer
About 0.19 instead of 0.05 for 10 equally spaced looks. Fix the sample size and analyze once; or use a sequential test with alpha spending or always-valid p-values. - You randomize by user, and the metric is clicks per page view. Why is the usual two-proportion
test wrong here?
Answer
The page views of one user are correlated, so they are not independent trials. The test treats each view as independent and underestimates the variance, which gives too many false positives. Compute one value per user (clicks/views per user, or totals with the delta method) or bootstrap over users.
State the bias–variance decomposition for squared loss at a point .
: noise + bias² + variance.
Why does the lasso give exact zeros and ridge does not?
The slope of at 0 is , so a weight stays at 0 unless the loss gains more than ; soft thresholding sets every to 0. Ridge only scales: .
Variance of the average of models, each with variance and pairwise correlation ?
. More models remove only the second term.
What does each tree of gradient boosting fit?
The pseudo-residuals , the negative gradient of the loss at the current predictions; for squared loss, the ordinary residuals .
Define precision and recall.
Precision : the share of alarms that are right. Recall : the share of positives that are found.
Why can ROC-AUC look excellent on a fraud model that is useless in practice?
ROC-AUC uses TPR and FPR, each inside one class, so it ignores the class ratio. At 0.5% prevalence a 5% FPR gives about 12 false alarms per caught fraud. Report precision at the threshold, or AP.
Rule-of-thumb sample size per arm for a conversion rate and absolute MDE (, power 0.8)?
. For , : about 57,600.
What does peeking do to an A/B test?
Stopping at the first over many looks inflates the false-positive rate: about 0.14 with 5 looks and 0.19 with 10, instead of 0.05.
How do you detect a sample-ratio mismatch, and what does it mean?
A goodness-of-fit test of the arm counts against the planned split (alarm at about ). It means a bug in assignment, logging or filtering; the result cannot be trusted.
Prevalence 0.5%, sensitivity 99%, specificity 99%. What is ?
: two of three positives are false.
9. Interview angle #
Recognize the question from the wording.
| The question says | Start with |
|---|---|
| "my model overfits / underfits", "train 2%, val 15%" | bias vs variance; the learning-curve diagnosis; one fix per direction |
| "L1 or L2?", "feature selection" | soft thresholding, the diamond corner, the priors, the elastic net for correlated groups |
| "bagging vs boosting", "why does a random forest work" | ; the comparison table |
| "99% accurate", "fraud", "rare disease" | base rate, confusion matrix, precision at the operating point, AP |
| "is the model calibrated?" | reliability diagram, log-loss or Brier, temperature or isotonic scaling on held-out data |
| "how do you split the data?" | groups, time, space; where leakage enters; preprocessing inside the fold |
| "a test is 99% accurate, the person tests positive" | Bayes' rule, then natural frequencies |
| "design an experiment", "how long should the test run?" | the 7-step checklist; ; full weeks |
| "the result is significant on day 3" | peeking; fixed horizon or sequential design |
Typical questions and short model answers.
- "Explain the bias–variance trade-off." — "At a fixed input, the expected squared error splits into noise, bias squared and variance. Bias is how far the average model is from the truth; variance is how much the model changes with a new training set. Flexible models have low bias and high variance. Regularization, more data and averaging lower the variance. I diagnose it from learning curves: a large train–validation gap means variance; high error on both means bias."
- "Bagging vs boosting?" — "Bagging trains deep trees in parallel on bootstrap samples and averages them. The average of models with correlation has variance , so bagging lowers variance, and random forests lower with random feature subsets. Boosting trains shallow trees in sequence; each tree fits the negative gradient of the loss at the current predictions. It lowers bias and needs early stopping. On tabular data, boosting usually wins on accuracy."
- "ROC-AUC or PR-AUC for fraud?" — "ROC-AUC measures ranking and ignores the class ratio. At 0.5% fraud, a threshold with 80% recall and 5% FPR gives a precision of only 7%, about 12 false alarms per caught fraud, with an excellent ROC-AUC. So I report average precision and the precision and recall at the operating threshold, chosen from the costs of the two errors."
- "How many users do we need for this A/B test?" — "I need the baseline rate, the minimum effect worth detecting, the level and the power. Then , about . For 10% baseline and a 0.5-point lift that is about 58,000 per arm. I divide by the daily traffic per arm and round up to full weeks."
- "The PM checked the dashboard on day 3 and it is significant. Can we ship?" — "Not yet. If we look every day and stop at the first significant result, the false-positive rate is much higher than 5%, about 19% with 10 looks. We fixed the sample size in advance, so we wait. If early stopping matters, we use a sequential test with alpha spending. I also check the sample ratio and the guardrail metrics first."
- "A test is 99% sensitive and 99% specific; the disease has 0.5% prevalence. Positive result: probability of disease?" — "About one third. Of 100,000 people, 500 are sick and 495 test positive; of 99,500 healthy people, 995 test positive. So 495 of 1,490 positives are sick."
Typical follow-ups. "What if the metric is revenue, not conversion?" (higher variance: more users, CUPED, or a capped metric). "What if users talk to each other?" (interference: cluster or market randomization, switchbacks). "Why not test 20 metrics?" ( chance of a false positive; one primary metric, corrections for the rest). "How do you choose in -fold?" (5 or 10; more folds lower bias of the estimate but cost more and have correlated folds).
Mock prompt (A/B design). "A new ranking model raises offline NDCG by 2%. Design the online test." A strong answer contains: one primary metric (for example, sessions with a purchase per user) and guardrails (latency, revenue, errors); user-level randomization; the power calculation with a baseline and an MDE, and the duration in full weeks; an A/A test and an SRM check; no peeking, or a sequential design; a check for novelty effects; the decision rule fixed in advance; and a note on interference if the product is a marketplace.
10. Practice #
The notebook for this lesson runs in Colab. Each exercise has a check cell and a folded solution:
bias_variance: estimate bias², variance and noise for polynomial fits by simulation, and check that they add up to the test MSE.precision_recall_atandcost_threshold: precision and recall at a threshold, and the threshold that minimizes the expected cost.sample_size_per_arm: the formula of section 3.7, checked against a simulation of the power.two_proportion_ztest: the z-test, checked againstscipy.stats.chi2_contingency.srm_check: the sample-ratio check withscipy.stats.chisquare.
Timed practice (25 minutes each, talking aloud): "explain the bias–variance trade-off with a picture"; "derive the sample-size formula"; "design an A/B test for a new search ranking"; "our model is 99% accurate on fraud; what do you ask?"; "implement ROC-AUC from scratch"; "expected number of coin flips until HH"; Chip Huyen's questions on evaluation and A/B testing (see below).
Say it aloud drill. Start a 2-minute timer for each question of section 9. Answer with the four parts of "Why this matters" (definition, mechanism, trade-off, number). Record yourself, then compare with sections 3–4. Repeat the ones where you ran over time or had no number.
11. Watch and read #
- Kohavi, Longbotham, Sommerfield and Henne (2009), Controlled experiments on the web: survey and practical guide: §3.2 (sample size, the rule of 16) and §6 (A/A tests, pitfalls).
- James, Witten, Hastie and Tibshirani, An Introduction to Statistical Learning (free PDF): §2.2 (bias–variance), §5.1 (cross-validation), §6.2 (ridge and lasso), chapter 8 (trees, bagging, random forests, boosting).
- Chip Huyen, Introduction to Machine Learning Interviews (free online book): the chapters on ML fundamentals, evaluation and statistics.
- scikit-learn user guide, Probability calibration: reliability diagrams, Platt scaling and isotonic regression.
- Friedman (2001), Greedy function approximation: a gradient boosting machine: the original gradient boosting paper.
- Deng, Xu, Kohavi and Walker (2013), Improving the sensitivity of online controlled experiments by utilizing pre-experiment data (CUPED).
Runs in your browser with nothing to install. The notebook repeats the key demos and has exercises with checks; solutions are inside, folded.
No Google account needed: Python runs inside your browser. The first start downloads about 40 MB; your changes are saved in this browser only.