Level 5 — MasteryModel Evaluation & Selection

Model Evaluation & Selection

90 minutes60 marksprintable — key stays hidden on paper

Level 5 — Mastery (cross-domain: probability, optimization, coding) Time limit: 90 minutes Total marks: 60

Answer all three questions. Show all derivations. Where code is requested, write clean, runnable Python (NumPy/scikit-learn conventions accepted).


Question 1 — Bias–Variance Decomposition & Learning-Curve Prognosis (22 marks)

(a) For squared-error regression, let the data be generated by y=f(x)+εy = f(x) + \varepsilon with E[ε]=0\mathbb{E}[\varepsilon]=0, Var(ε)=σ2\operatorname{Var}(\varepsilon)=\sigma^2. Let f^D(x)\hat f_D(x) be an estimator trained on random dataset DD. Prove the pointwise decomposition

ED,ε[(yf^D(x))2]=(f(x)ED[f^D(x)])2Bias2+VarD(f^D(x))Variance+σ2.\mathbb{E}_{D,\varepsilon}\big[(y-\hat f_D(x))^2\big] = \underbrace{\big(f(x)-\mathbb{E}_D[\hat f_D(x)]\big)^2}_{\text{Bias}^2} + \underbrace{\operatorname{Var}_D(\hat f_D(x))}_{\text{Variance}} + \sigma^2.

State clearly every independence/zero-mean assumption you use. (8 marks)

(b) Consider kk-nearest-neighbours regression on a fixed test point x0x_0 with kk neighbours whose true values are all f(x0)\approx f(x_0) locally, and i.i.d. noise variance σ2\sigma^2. Show that the variance term of the prediction is σ2/k\sigma^2/k and argue how bias behaves as kk grows. Use this to explain why kk acts as a complexity/regularization knob (with k ⁣k\!\downarrow = more complex). (6 marks)

(c) A team reports: training RMSE =0.18= 0.18, validation RMSE =0.52= 0.52, and both curves have flattened as training-set size increased. The irreducible noise std is estimated at σ0.15\sigma \approx 0.15. Diagnose the regime (underfit/overfit/well-fit), justify using the numbers, and give two concrete, distinct remedies consistent with your diagnosis. Explain why adding more data alone would (or would not) help. (8 marks)


Question 2 — Threshold Metrics, ROC/PR Geometry, and a Proof (20 marks)

A binary classifier is evaluated on a test set with PP positives and NN negatives. At a given threshold the confusion counts are TP,FP,FN,TNTP, FP, FN, TN.

(a) Starting from definitions, derive expressions for precision, recall (TPR), and FPR in terms of these counts. Then prove that if the class prior π=P/(P+N)\pi = P/(P+N) decreases (dataset becomes more imbalanced) while TPR and FPR are held fixed, precision monotonically decreases. Give the precision formula purely in terms of TPR, FPR, and π\pi. (8 marks)

(b) A model produces scores. Sorted by descending score the true labels are:

[1, 1, 0, 1, 0, 0](P=3, N=3).[\,1,\ 1,\ 0,\ 1,\ 0,\ 0\,] \qquad (P=3,\ N=3).

Compute the AUC by counting concordant positive–negative pairs (ties none). Show the pair count and the normalisation. (6 marks)

(c) For the same score ordering, an operating point is chosen after the top-3 scores are predicted positive. Build the confusion matrix and compute accuracy, precision, recall, and F1F_1. Then state, with justification, whether this threshold is Pareto-optimal on the PR curve relative to the top-2 threshold. (6 marks)


Question 3 — Nested Cross-Validation & Honest Model Selection (18 marks)

(a) Explain precisely why selecting hyperparameters by the same kk-fold CV score that is then reported as the model's generalization estimate produces an optimistically biased estimate. Frame it as a multiple-comparisons / selection-bias argument. (6 marks)

(b) Write pseudocode (or Python) for nested cross-validation with an outer 5-fold loop and inner 3-fold grid search over a hyperparameter grid G. Your code must return an unbiased generalization estimate and clearly separate the selection loop from the evaluation loop. (7 marks)

(c) A practitioner uses standard kk-fold CV on a dataset where each patient contributes multiple correlated rows, and also does feature selection (top-mm by correlation with the target) once on the full dataset before CV. Identify the two distinct leakage/pitfalls, explain the direction of the resulting bias, and give the corrected protocol for each. (5 marks)

Answer keyMark scheme & solutions

Question 1

(a) Bias–variance proof (8 marks)

Let fˉ(x)=ED[f^D(x)]\bar f(x)=\mathbb{E}_D[\hat f_D(x)]. Write E[(yf^)2]=E[(f+εf^)2].\mathbb{E}[(y-\hat f)^2]=\mathbb{E}[(f+\varepsilon-\hat f)^2]. Expand into three groupings by inserting ±fˉ\pm \bar f: yf^=ε+(ffˉ)+(fˉf^).y-\hat f = \varepsilon + (f-\bar f) + (\bar f - \hat f). Square and take expectation over DD and ε\varepsilon: E[(yf^)2]=E[ε2]+(ffˉ)2+E[(fˉf^)2]+2(cross terms).\mathbb{E}[(y-\hat f)^2]=\mathbb{E}[\varepsilon^2]+ (f-\bar f)^2 + \mathbb{E}[(\bar f-\hat f)^2] + 2(\text{cross terms}).

  • E[ε2]=σ2\mathbb{E}[\varepsilon^2]=\sigma^2 (zero-mean noise). (1)
  • (ffˉ)2(f-\bar f)^2 is deterministic =Bias2=\text{Bias}^2. (1)
  • E[(fˉf^)2]=VarD(f^)\mathbb{E}[(\bar f-\hat f)^2]=\operatorname{Var}_D(\hat f). (1)

Cross terms vanish:

  • E[ε(ffˉ)]=E[ε](ffˉ)=0\mathbb{E}[\varepsilon(f-\bar f)]=\mathbb{E}[\varepsilon]\cdot(f-\bar f)=0 (noise indep. of training set, zero mean). (1.5)
  • E[ε(fˉf^)]=0\mathbb{E}[\varepsilon(\bar f-\hat f)]=0: test noise ε\varepsilon at xx is independent of f^D\hat f_D (trained on DD, disjoint from test noise), and E[ε]=0\mathbb{E}[\varepsilon]=0. (1.5)
  • E[(ffˉ)(fˉf^)]=(ffˉ)E[fˉf^]=(ffˉ)0=0\mathbb{E}[(f-\bar f)(\bar f-\hat f)]=(f-\bar f)\,\mathbb{E}[\bar f-\hat f]=(f-\bar f)\cdot 0=0 since ED[f^]=fˉ\mathbb{E}_D[\hat f]=\bar f. (1)

Hence result. Assumptions stated: zero-mean noise, noise independent of DD, fˉ=E[f^]\bar f=\mathbb{E}[\hat f]. (1)

(b) kNN variance (6 marks)

Prediction f^(x0)=1ki=1kyi\hat f(x_0)=\frac1k\sum_{i=1}^k y_i where locally yi=f(x0)+εiy_i=f(x_0)+\varepsilon_i, εi\varepsilon_i i.i.d. (0,σ2)(0,\sigma^2).

  • Var(f^)=1k2Var(εi)=kσ2k2=σ2/k\operatorname{Var}(\hat f)=\frac{1}{k^2}\sum \operatorname{Var}(\varepsilon_i)=\frac{k\sigma^2}{k^2}=\sigma^2/k. (3)
  • Bias: as kk grows, neighbours span a larger region where ff varies, so E[f^]\mathbb{E}[\hat f] averages over differing ff values → bias grows with kk. (2)
  • Thus small kk = low bias / high variance = complex model; large kk = smooth/regularized. kk is the complexity knob. (1)

(c) Diagnosis (8 marks)

  • Large gap: val 0.520.52 \gg train 0.180.18high variance / overfitting. (2)
  • Train RMSE 0.180.18 is only slightly above irreducible floor σ=0.15\sigma=0.15; model fits training data near the noise floor but generalizes poorly → confirms variance-dominated, low bias. (2)
  • Curves have flattened ⇒ more data will not close the gap much (learning curve plateaued); adding data alone has limited benefit. (2)
  • Two remedies (any two distinct): (i) increase regularization / reduce model complexity; (ii) feature selection / dimensionality reduction; (iii) ensembling/bagging to reduce variance; (iv) early stopping. (2)

Question 2

(a) Derivation + monotonicity proof (8 marks)

  • Precision =TPTP+FP=\dfrac{TP}{TP+FP}, Recall/TPR =TPP=\dfrac{TP}{P}, FPR =FPN=\dfrac{FP}{N}. (2)
  • Substitute TP=TPRPTP=\text{TPR}\cdot P, FP=FPRNFP=\text{FPR}\cdot N: Precision=TPRPTPRP+FPRN.\text{Precision}=\frac{\text{TPR}\,P}{\text{TPR}\,P+\text{FPR}\,N}. Divide by (P+N)(P+N), with π=P/(P+N)\pi=P/(P+N), 1π=N/(P+N)1-\pi=N/(P+N): Precision=TPRπTPRπ+FPR(1π).\boxed{\text{Precision}=\frac{\text{TPR}\,\pi}{\text{TPR}\,\pi+\text{FPR}\,(1-\pi)}}. (3)
  • Monotonicity: write Prec=11+FPRTPR1ππ\text{Prec}=\dfrac{1}{1+\frac{\text{FPR}}{\text{TPR}}\cdot\frac{1-\pi}{\pi}}. As π\pi\downarrow, 1ππ\frac{1-\pi}{\pi}\uparrow, denominator \uparrow, so precision \downarrow (TPR, FPR fixed, both positive). Hence strictly decreasing in the imbalance. (3)

(b) AUC by pair counting (6 marks)

Labels descending: positions of positives = {1,2,4}, negatives = {3,5,6}. AUC =1PNpos p,neg n1[score(p)>score(n)]=\frac{1}{P\cdot N}\sum_{\text{pos }p,\text{neg }n}\mathbf 1[\text{score}(p)>\text{score}(n)]. Count concordant pairs (positive ranked above negative):

  • pos@1: beats negs at 3,5,6 → 3
  • pos@2: beats 3,5,6 → 3
  • pos@4: beats 5,6 (not 3) → 2

Total concordant =8=8, out of PN=9P\cdot N=9. (4) AUC=8/90.889.\text{AUC}=8/9\approx 0.889. (2)

(c) Top-3 operating point (6 marks)

Top-3 predicted positive = positions {1,2,3}; labels there = {1,1,0}.

  • TP=2 (pos at 1,2), FP=1 (neg at 3), FN=1 (pos at 4), TN=2 (negs at 5,6). (2)
  • Accuracy =(2+2)/6=0.667=(2+2)/6=0.667; Precision =2/30.667=2/3\approx0.667; Recall =2/30.667=2/3\approx0.667; F1=2.667.667.667+.667=0.667F_1=2\cdot\frac{.667\cdot.667}{.667+.667}=0.667. (2)
  • Top-2 threshold: TP=2, FP=0 → Precision =1.0=1.0, Recall =2/3=2/3. Compared to top-3 (Prec .667, Recall .667): top-2 has equal recall but higher precision, so top-3 is dominated / NOT Pareto-optimal. (2)

Question 3

(a) Optimistic bias (6 marks)

  • Choosing the hyperparameter with the best CV score means maximizing over many noisy estimates. The maximum of noisy estimates is biased high (its expectation exceeds the true best). (3)
  • The winning config partly won by fitting the noise/idiosyncrasies of these particular folds → the reported CV score is contaminated by the selection, no longer an unbiased estimate of generalization. It is a multiple-comparisons/"winner's curse" bias. (3)

(b) Nested CV (7 marks)

from sklearn.model_selection import KFold
import numpy as np
 
def nested_cv(X, y, model_factory, G, fit_score):
    outer = KFold(5, shuffle=True, random_state=0)
    outer_scores = []
    for tr, te in outer.split(X):                 # evaluation loop
        # --- inner: model selection only ---
        inner = KFold(3, shuffle=True, random_state=1)
        best_g, best_val = None, -np.inf
        for g in G:
            vals = []
            for itr, iva in inner.split(X[tr]):
                m = model_factory(g).fit(X[tr][itr], y[tr][itr])
                vals.append(fit_score(m, X[tr][iva], y[tr][iva]))
            if np.mean(vals) > best_val:
                best_val, best_g = np.mean(vals), g
        # --- refit on full outer-train, score on untouched outer-test ---
        m = model_factory(best_g).fit(X[tr], y[tr])
        outer_scores.append(fit_score(m, X[te], y[te]))
    return np.mean(outer_scores), np.std(outer_scores)

Marks: inner loop selects only (2), outer test never seen during selection (3), refit + return mean±std (2).

(c) Leakage pitfalls (5 marks)

  1. Grouped data leakage: rows from the same patient appear in both train and validation folds → info leaks, optimistic bias. Fix: use GroupKFold/StratifiedGroupKFold keyed on patient ID. (2.5)
  2. Feature selection before CV (selection leakage): correlations computed on full data (incl. validation) → optimistically biased. Fix: put feature selection inside the CV pipeline, refit on each training fold only. (2.5)
[
 {"claim":"kNN averaging variance is sigma^2/k",
  "code":"k,s=symbols('k s',positive=True); var=k*s**2/k**2; result = simplify(var - s**2/k)==0"},
 {"claim":"AUC = 8/9 for the given ranking",
  "code":"pos=[1,2,4]; neg=[3,5,6]; c=sum(1 for p in pos for n in neg if p<n); result = Rational(c,len(pos)*len(neg))==Rational(8,9)"},
 {"claim":"Top-3 F1 = 2/3",
  "code":"TP,FP,FN=2,1,1; P=Rational(TP,TP+FP); R=Rational(TP,TP+FN); F1=2*P*R/(P+R); result = F1==Rational(2,3)"},
 {"claim":"Precision decreases as prior pi decreases (fixed TPR,FPR)",
  "code":"pi,tpr,fpr=symbols('pi tpr fpr',positive=True); prec=tpr*pi/(tpr*pi+fpr*(1-pi)); d=diff(prec,pi); result = simplify(d.subs({tpr:Rational(1,2),fpr:Rational(1,4),pi:Rational(1,3)}))>0"}
]