PROMETHEUS OS
NATIVE AI OPERATING SYSTEM
[INIT] Prometheus OS loading...
[CORE] Neural interface initializing...
[AI] LLM router connecting...
[MEM] Memory graph loading...
[AGT] Agent chains on standby...
[SEC] Security protocols active...
[NET] Provider mesh established...
[UI] Workspace rendering...
[DONE] All systems nominal.
Welcome to PROMETHEUS OS.
READY · OFFLINE · SECURE · PRIVATE
🎨 THEME ENGINE
PROMETHEUS OS · 23 THEMES
Trial version: Dark + Light themes only.
Full theme access with PROMETHEUS OS license.
Dark theme active
Experience all 23 themes in PROMETHEUS OS

Model Evaluation and Metrics

Intermediate 16 min· 4 exercises

Measure model quality honestly: pick classification and regression metrics that match the business problem, validate with the right cross-validation scheme, diagnose bias and variance, and compare models with statistical care.

By the end of this lesson you will be able to
  • Compute accuracy, precision, recall, F1, specificity and cost from a confusion matrix
  • Compare ROC-AUC and PR-AUC and choose between them under class imbalance
  • Explain calibration and evaluate it with reliability diagrams, the Brier score and expected calibration error
  • Choose among MAE, RMSE and MAPE for regression and explain each one's failure modes
  • Select k-fold, stratified, grouped or time-series cross-validation to match the data's structure
  • Choose a decision threshold that minimizes expected business cost and test whether one model is reliably better than another

Before this: The ML Workflow: Framing, Data, Splits and Leakage, Linear and Logistic Regression, Probability and Statistics for AI

A model is only as good as the evidence that it works. Evaluation decides whether a model ships, which of two models wins, what threshold it runs at, and whether a promised improvement is real or noise. Many failed ML projects did not have bad models; they had good-looking numbers produced by the wrong metric, a leaky split, or a test set used one time too many. This lesson covers the measurements professionals rely on and the judgment needed to pick among them.

Intuition: the metric is the contract

Think of a metric as the contract between the model and the business. A fraud model "scoring 95% accuracy" sounds excellent until you learn that 95% of transactions are legitimate, so a model that never flags anything also scores 95%. The contract was badly written. Good evaluation starts by asking what an error costs, who bears it, and how the predictions will be used (ranked? thresholded? summed into a forecast?), then chooses metrics that reward exactly that behaviour.

Classification metrics

The confusion matrix

For a binary classifier with a positive class (say, fraud), every prediction falls into one of four cells:

Predicted positivePredicted negative
Actually positiveTrue positive (TP)False negative (FN)
Actually negativeFalse positive (FP)True negative (TN)

From these counts:

Accuracy=TP+TNTP+TN+FP+FN,Precision=TPTP+FP,Recall=TPTP+FN,\text{Accuracy} = \frac{TP+TN}{TP+TN+FP+FN}, \quad \text{Precision} = \frac{TP}{TP+FP}, \quad \text{Recall} = \frac{TP}{TP+FN},

Specificity=TNTN+FP,FPR=1−Specificity,F1=2⋅Precision⋅RecallPrecision+Recall.\text{Specificity} = \frac{TN}{TN+FP}, \quad \text{FPR} = 1 - \text{Specificity}, \quad F_1 = \frac{2 \cdot \text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}.

Precision answers "when the model raises an alarm, how often is it right?" Recall (also called sensitivity or true positive rate, TPR) answers "of all real positives, how many did we catch?" F1F_1 is their harmonic mean, which is dragged down by whichever is smaller. The general Fβ=(1+β2)PRβ2P+RF_\beta = (1+\beta^2)\frac{PR}{\beta^2 P + R} weights recall β\beta times as much as precision.

Worked example

1,000 transactions, 50 of them fraudulent. The model flags 100; 40 of those are fraud.

  • TP=40TP = 40, FP=60FP = 60, FN=50−40=10FN = 50 - 40 = 10, TN=950−60=890TN = 950 - 60 = 890.
  • Accuracy =(40+890)/1000=0.93= (40 + 890)/1000 = 0.93.
  • Precision =40/100=0.40= 40/100 = 0.40. Recall =40/50=0.80= 40/50 = 0.80.
  • F1=2(0.40)(0.80)/(1.20)≈0.533F_1 = 2(0.40)(0.80)/(1.20) \approx 0.533.
  • Specificity =890/950≈0.937= 890/950 \approx 0.937, so FPR ≈0.063\approx 0.063.

The trivial "never fraud" model has accuracy 950/1000=0.95950/1000 = 0.95, higher than our model, with recall 0. Under imbalance, accuracy is nearly useless; report precision, recall and a cost.

For more than two classes, compute per-class metrics and average them: macro averaging weights classes equally (good when rare classes matter), weighted averaging weights by class frequency, and micro averaging pools all counts (for single-label multiclass problems, micro-F1 equals accuracy).

Thresholds, ROC and PR curves

Most classifiers output a score or probability p^\hat p; the label comes from a threshold tt (predict positive if p^≥t\hat p \ge t). Every threshold gives a different confusion matrix, so a single precision or recall number describes one operating point. Curves describe all of them.

  • The ROC curve plots TPR (recall) against FPR as tt sweeps from 1 to 0. ROC-AUC, the area under it, equals the probability that a randomly chosen positive is scored higher than a randomly chosen negative. Random scoring gives 0.5; perfect ranking gives 1.0.
  • The precision-recall (PR) curve plots precision against recall. Its summary, average precision (AP, a step-wise estimate of PR-AUC), has a random baseline equal to the positive rate, not 0.5.

Why the difference matters: FPR divides by the number of negatives. When negatives vastly outnumber positives (say 1 fraud per 1,000), a model can produce many times more false alarms than true detections while FPR stays tiny, so ROC-AUC looks excellent. Precision exposes this because its denominator contains the false positives directly. Saito and Rehmsmeier (2015) showed empirically that PR plots are more informative than ROC plots on imbalanced data. Rules of thumb:

SituationPrefer
Balanced classes, care about ranking overallROC-AUC
Rare positives, care about the quality of alarmsPR-AUC / average precision
A fixed operating point is knownPrecision and recall (or cost) at that threshold
Comparing across datasets with different prevalenceROC-AUC (prevalence-invariant), with care

Calibration

A model is calibrated if, among all cases where it predicts probability pp, the fraction that are positive is about pp. Ranking metrics like AUC ignore calibration entirely: multiply every score by 0.5 and AUC is unchanged. But calibration matters whenever probabilities are used as probabilities: expected-cost decisions, risk scores shown to clinicians, combining models, or the threshold formula below.

Tools:

  • Reliability diagram: bin predictions (e.g. 10 bins), plot mean predicted probability against observed positive rate; a calibrated model lies on the diagonal.
  • Brier score: 1n∑i(p^i−yi)2\frac{1}{n}\sum_i (\hat p_i - y_i)^2, a proper scoring rule (lower is better). Log loss is another.
  • Expected calibration error (ECE): ∑b∣Bb∣n ∣y‾Bb−p^‾Bb∣\sum_{b} \frac{|B_b|}{n}\,\left|\overline{y}_{B_b} - \overline{\hat p}_{B_b}\right| over bins BbB_b. It depends on the binning, so treat it as a diagnostic.

Fixes: Platt scaling (fit a logistic regression on the scores) and isotonic regression (a monotone step function, needs more data), both available through CalibratedClassifierCV, and temperature scaling for neural networks (Guo et al., 2017, found that modern deep networks are often overconfident). Always fit calibrators on data not used to train the model.

Regression metrics

With residuals ei=yi−y^ie_i = y_i - \hat y_i:

MAE=1n∑i∣ei∣,RMSE=1n∑iei2,MAPE=100%n∑i∣eiyi∣.\text{MAE} = \frac{1}{n}\sum_i |e_i|, \qquad \text{RMSE} = \sqrt{\frac{1}{n}\sum_i e_i^2}, \qquad \text{MAPE} = \frac{100\%}{n}\sum_i \left|\frac{e_i}{y_i}\right|.

Worked example. True values y=(100,200,300,50)y = (100, 200, 300, 50), predictions y^=(110,180,330,40)\hat y = (110, 180, 330, 40). Residuals: −10,20,−30,10-10, 20, -30, 10.

  • MAE =(10+20+30+10)/4=17.5= (10+20+30+10)/4 = 17.5.
  • MSE =(100+400+900+100)/4=375= (100+400+900+100)/4 = 375, so RMSE =375≈19.36= \sqrt{375} \approx 19.36.
  • MAPE =14(0.10+0.10+0.10+0.20)=12.5%= \frac{1}{4}(0.10 + 0.10 + 0.10 + 0.20) = 12.5\%.

How to choose:

  • MAE is in the target's units, robust to outliers, and is minimized by predicting the conditional median.
  • RMSE penalizes large errors quadratically, is minimized by the conditional mean, and is the right choice when big misses are disproportionately costly. RMSE is always at least MAE; a large gap signals a few big errors.
  • MAPE is scale-free and easy to explain, but it is undefined at y=0y=0, explodes near zero, and is asymmetric: for positive targets and non-negative forecasts, an under-forecast can contribute at most 100%, while an over-forecast is unbounded, so optimizing MAPE biases forecasts low. Alternatives include weighted MAPE (∑∣ei∣/∑∣yi∣\sum|e_i| / \sum|y_i|) and MASE (error scaled by a naive baseline's error), common in forecasting.
  • R2R^2 =1−SSE/SST= 1 - \text{SSE}/\text{SST} is the fraction of variance explained relative to predicting the mean. It can be negative on test data.

Cross-validation

A single train/test split gives one noisy estimate. k-fold cross-validation splits the training data into kk folds, trains on k−1k-1 and validates on the remaining one, rotating kk times, and reports the mean and spread of the kk scores. k=5k=5 or 1010 is standard.

Pick the splitter to match how the model will meet data in production:

Data structureSplitterWhy
i.i.d. rows, balancedKFold(shuffle=True)basic case
Classification, imbalanceStratifiedKFoldeach fold keeps the class ratio
Several rows per patient/user/deviceGroupKFoldthe same entity never appears in train and validation
Time-ordered dataTimeSeriesSplitalways train on the past, validate on the future

Using shuffled k-fold on time series or on grouped data leaks information and inflates scores, sometimes dramatically. Hyperparameter tuning adds another trap: if you pick the best configuration by its cross-validation score, that score is optimistically biased. Report the final number on an untouched test set, or use nested cross-validation (an inner loop for tuning, an outer loop for estimation).

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_validate

X, y = make_classification(n_samples=5000, weights=[0.95, 0.05],
                           n_informative=5, random_state=0)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
res = cross_validate(LogisticRegression(max_iter=1000), X, y, cv=cv,
                     scoring=["accuracy", "roc_auc", "average_precision", "f1"])
for m in ["accuracy", "roc_auc", "average_precision", "f1"]:
    s = res[f"test_{m}"]
    print(f"{m:18s} {s.mean():.3f} +/- {s.std():.3f}")

On this 5%-positive synthetic dataset you will typically see high accuracy and ROC-AUC alongside markedly lower average precision and F1, the imbalance story in numbers.

Bias, variance and learning curves

For squared error, the expected test error of a learning algorithm at a point xx decomposes as

E[(y−f^(x))2]=(f(x)−E[f^(x)])2⏟bias2+E[(f^(x)−E[f^(x)])2]⏟variance+σ2⏟noise,\mathbb{E}\big[(y - \hat f(x))^2\big] = \underbrace{\big(f(x) - \mathbb{E}[\hat f(x)]\big)^2}_{\text{bias}^2} + \underbrace{\mathbb{E}\big[(\hat f(x) - \mathbb{E}[\hat f(x)])^2\big]}_{\text{variance}} + \underbrace{\sigma^2}_{\text{noise}},

where ff is the true function, y=f(x)+εy = f(x) + \varepsilon with noise variance σ2\sigma^2, and expectations are over training sets (and noise). Bias is systematic error from a model too simple to capture ff; variance is sensitivity to the particular training sample; noise is irreducible. Increasing model flexibility typically lowers bias and raises variance. (Very large neural networks can show "double descent," where test error falls again past the interpolation point, so treat the classic U-curve as a guide rather than a law.)

Learning curves plot training and validation scores against training-set size:

  • High bias (underfitting): both curves converge to a poor score with a small gap. More data will not help; add capacity or better features.
  • High variance (overfitting): training score is much better than validation, and the gap narrows as data grows. More data, regularization or a simpler model will help.

sklearn.model_selection.learning_curve and validation_curve (score against a hyperparameter) produce these directly.

Comparing models statistically

If model B beats model A by 0.4 points of accuracy, is that real? Some tools:

  • Look at the spread. Compare fold-by-fold (paired) scores; if B wins on only 3 of 10 folds, the mean difference is not convincing.
  • McNemar's test for two classifiers on the same test set. Let bb = cases A got right and B got wrong, cc = the reverse. Under the null of equal error rates, χ2=(∣b−c∣−1)2b+c\chi^2 = \frac{(|b-c|-1)^2}{b+c} approximately follows a chi-squared distribution with 1 degree of freedom. Example: b=30b = 30, c=15c = 15 gives χ2=142/45≈4.36\chi^2 = 14^2/45 \approx 4.36, above the 5% critical value 3.84 (p≈0.037p \approx 0.037).
  • Paired tests over CV folds need care, because folds share training data and the scores are correlated, which makes a naive paired t-test overconfident. Dietterich (1998) analysed this problem and proposed the 5×2 cv paired t-test; corrected resampled t-tests are another option.
  • Bootstrap confidence intervals on the test-set metric difference are simple and work for any metric.

Also budget for the multiple-comparisons problem: if you try 50 variants and pick the best on the same validation set, some of its edge is luck.

Choosing metrics that match business costs

Assign a cost to each cell of the confusion matrix and choose the threshold that minimizes total cost. Continuing the fraud example, suppose a missed fraud (FN) costs 500 dollars and a false alarm (FP) costs 10 dollars of analyst time. Three candidate thresholds:

ThresholdTPFNFPCost in dollars =500 FN+10 FP= 500\,FN + 10\,FP
High (strict)30201510,000 + 150 = 10,150
Medium4010605,000 + 600 = 5,600
Low (lenient)4552002,500 + 2,000 = 4,500

The lenient threshold has the worst precision (45/245≈0.1845/245 \approx 0.18) yet the lowest cost. F1 would have picked the opposite: it is about 0.63 at the strict threshold (precision 30/4530/45, recall 0.600.60), 0.53 at the medium one, and 0.31 at the lenient one, so maximizing F1 selects the most expensive option here. F1 encodes an implicit cost ratio that rarely matches the real one.

With calibrated probabilities there is a closed form. Predict positive when the expected cost of saying "negative" exceeds that of saying "positive": p⋅CFN>(1−p)⋅CFPp \cdot C_{FN} > (1-p)\cdot C_{FP}, i.e.

t∗=CFPCFP+CFN=1010+500≈0.0196.t^* = \frac{C_{FP}}{C_{FP} + C_{FN}} = \frac{10}{10 + 500} \approx 0.0196 .

Real constraints also matter: if analysts can review only 120 alerts a day, the operating point is fixed by capacity, and the relevant metric becomes precision (or fraud value caught) in the top 120.

import numpy as np
from sklearn.metrics import confusion_matrix

def best_threshold(y_true, p, c_fp=10, c_fn=500):
    best = None
    for t in np.linspace(0.001, 0.999, 999):
        tn, fp, fn, tp = confusion_matrix(y_true, p >= t, labels=[0, 1]).ravel()
        cost = c_fp * fp + c_fn * fn
        if best is None or cost < best[1]:
            best = (t, cost)
    return best  # tune on validation data, report cost on test data

Common pitfalls

  • Reporting accuracy on imbalanced data, or ROC-AUC alone when positives are rare.
  • Tuning the threshold or hyperparameters on the test set, then reporting the test score as if it were unbiased.
  • Leaky cross-validation: shuffling time series, splitting rows of the same customer across folds, or fitting scalers/encoders on all data before splitting.
  • Ignoring variance: quoting a single split's score without a confidence interval or fold spread.
  • Treating scores as probabilities without checking calibration, especially after resampling or class weighting, both of which distort predicted probabilities.
  • Using MAPE on data with zeros or near-zero targets.
  • Optimizing a proxy forever: offline metrics should be validated against the online outcome (A/B test, business KPI) at least once.

In practice

  • Write down the cost of each error type and the operating constraint (review capacity, latency, regulatory requirements) before choosing metrics.
  • Report a small, fixed panel: one ranking metric (ROC-AUC or AP), the metrics at the chosen threshold, a calibration check, and the business cost, each with fold spread or bootstrap intervals.
  • Use stratified CV for classification, grouped CV whenever entities repeat, and time-based splits for anything temporal, including a final out-of-time test.
  • Keep a locked test set touched once per major decision; use cross-validation or a validation set for everything else.
  • Slice metrics by segment (region, device, customer type). Aggregate scores can hide a subgroup where the model fails, which matters for fairness as well as accuracy.
  • For LLM and generative systems the same principles apply with different measurements; see the evaluation lessons in AI 300 and AI 330.

Key takeaways

  • Accuracy misleads under class imbalance; report precision, recall and a business cost at the chosen threshold.
  • ROC-AUC measures ranking and is insensitive to prevalence, while PR-AUC exposes false alarms when positives are rare.
  • Calibration is separate from discrimination; check it with reliability diagrams or the Brier score before treating scores as probabilities.
  • MAE targets the median and is robust, RMSE targets the mean and punishes large errors, and MAPE breaks near zero and biases forecasts low.
  • The cross-validation splitter must mirror production: stratified for imbalance, grouped for repeated entities, forward-in-time for temporal data.
  • With calibrated probabilities, the cost-minimizing threshold is C_FP / (C_FP + C_FN), which is usually far from 0.5.

Terms in this lesson

Precision
The fraction of predicted positives that are truly positive, TP / (TP + FP).
Recall
The fraction of actual positives the model detects, TP / (TP + FN), also called sensitivity or true positive rate.
ROC-AUC
The area under the curve of true positive rate versus false positive rate, equal to the probability a random positive outranks a random negative.
Average precision
A step-wise summary of the precision-recall curve whose random-classifier baseline equals the positive class rate.
Calibration
The agreement between predicted probabilities and observed frequencies of the positive outcome.
Brier score
The mean squared difference between predicted probabilities and binary outcomes, a proper scoring rule where lower is better.
Stratified k-fold
Cross-validation that preserves each class's proportion in every fold.
Nested cross-validation
An outer cross-validation loop for performance estimation wrapped around an inner loop used only for hyperparameter tuning.
McNemar's test
A paired significance test comparing two classifiers using only the test cases on which they disagree.

Check your understanding

  1. 1.

    A model has TP = 30, FP = 20, FN = 10, TN = 940. What is its F1 score?

  2. 2.

    Positives are 0.2% of your data and you care about how many of the model's alerts are real. Which summary metric is most informative?

  3. 3.

    You are forecasting daily sales using three years of data. Which validation scheme is appropriate?

  4. 4.

    A missed default costs 900 dollars and wrongly declining a good applicant costs 100 dollars. With calibrated default probabilities, what threshold minimizes expected cost?

  5. 5.

    Training accuracy is 99% and validation accuracy 78%; the gap shrinks steadily as you add training data. What is the most likely diagnosis?

Exercises

Work each problem before opening the solution.

  1. Exercise 1Core

    A disease screening test is applied to 2,000 people, 100 of whom have the disease. It flags 180 people, of whom 90 truly have the disease. Build the confusion matrix and compute accuracy, precision, recall, specificity and F1. Then explain why precision is low despite high recall and specificity.

    Show solution

    TP=90TP = 90, FP=180−90=90FP = 180 - 90 = 90, FN=100−90=10FN = 100 - 90 = 10, TN=1900−90=1810TN = 1900 - 90 = 1810.

    • Accuracy =(90+1810)/2000=0.95= (90 + 1810)/2000 = 0.95.
    • Precision =90/180=0.50= 90/180 = 0.50.
    • Recall =90/100=0.90= 90/100 = 0.90.
    • Specificity =1810/1900≈0.953= 1810/1900 \approx 0.953.
    • F1=2(0.5)(0.9)/1.4≈0.643F_1 = 2(0.5)(0.9)/1.4 \approx 0.643.

    Precision is low because the disease is rare (5% prevalence). Even a 4.7% false positive rate applied to 1,900 healthy people produces about 90 false alarms, as many as the true detections. This is the base-rate effect: positive predictive value depends on prevalence, which is why screening programs follow positive results with a more specific confirmatory test.

  2. Exercise 2Core

    For true values (10,0.5,20,40)(10, 0.5, 20, 40) and predictions (12,1.5,18,36)(12, 1.5, 18, 36), compute MAE, RMSE and MAPE. Which metric is distorted, and why?

    Show solution

    Residuals y−y^y - \hat y: −2,−1,2,4-2, -1, 2, 4.

    • MAE =(2+1+2+4)/4=2.25= (2 + 1 + 2 + 4)/4 = 2.25.
    • MSE =(4+1+4+16)/4=6.25= (4 + 1 + 4 + 16)/4 = 6.25, RMSE =2.5= 2.5.
    • Percentage errors: 2/10=20%2/10 = 20\%, 1/0.5=200%1/0.5 = 200\%, 2/20=10%2/20 = 10\%, 4/40=10%4/40 = 10\%. MAPE =(20+200+10+10)/4=60%= (20 + 200 + 10 + 10)/4 = 60\%.

    MAPE is distorted by the near-zero target 0.5: an absolute error of 1 unit, the smallest in the set, contributes 200% and dominates the average. MAE and RMSE treat that miss as small. Weighted MAPE, ∑∣ei∣/∑∣yi∣=9/70.5≈12.8%\sum|e_i|/\sum|y_i| = 9/70.5 \approx 12.8\%, gives a far more sensible picture.

  3. Exercise 3Core

    Write scikit-learn code that trains a gradient-boosting classifier on an imbalanced synthetic dataset, picks the threshold minimizing cost (FP = 5, FN = 100) on a validation split, and reports the cost on a separate test split, compared with the default 0.5 threshold.

    Show solution
    import numpy as np
    from sklearn.datasets import make_classification
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import HistGradientBoostingClassifier
    
    X, y = make_classification(n_samples=20000, weights=[0.97, 0.03],
                               n_informative=6, random_state=1)
    X_tr, X_tmp, y_tr, y_tmp = train_test_split(X, y, test_size=0.4, stratify=y, random_state=1)
    X_va, X_te, y_va, y_te = train_test_split(X_tmp, y_tmp, test_size=0.5, stratify=y_tmp, random_state=1)
    
    clf = HistGradientBoostingClassifier(random_state=1).fit(X_tr, y_tr)
    
    def cost(y_true, p, t, c_fp=5, c_fn=100):
        pred = p >= t
        fp = np.sum(pred & (y_true == 0)); fn = np.sum(~pred & (y_true == 1))
        return c_fp * fp + c_fn * fn
    
    p_va = clf.predict_proba(X_va)[:, 1]
    grid = np.linspace(0.01, 0.99, 99)
    t_best = grid[np.argmin([cost(y_va, p_va, t) for t in grid])]
    
    p_te = clf.predict_proba(X_te)[:, 1]
    print("chosen threshold:", round(t_best, 2))
    print("test cost @0.5 :", cost(y_te, p_te, 0.5))
    print("test cost @best:", cost(y_te, p_te, t_best))
    

    The chosen threshold lands well below 0.5 (the theoretical optimum for calibrated probabilities is 5/105≈0.0485/105 \approx 0.048), and the test cost is lower than at 0.5. The threshold is tuned on validation data and the cost reported on test data, so the reported number is not optimistically biased.

  4. Exercise 4Challenge

    Two classifiers are evaluated on the same 500 test cases. Both are correct on 400 and both wrong on 40. A alone is correct on 38; B alone is correct on 22. (a) Compute each model's accuracy. (b) Run McNemar's test with continuity correction at the 5% level. (c) Explain why a naive paired t-test on 10-fold CV scores can overstate significance.

    Show solution

    (a) A correct =400+38=438= 400 + 38 = 438, accuracy 87.6%87.6\%. B correct =400+22=422= 400 + 22 = 422, accuracy 84.4%84.4\%. (Check: 400+40+38+22=500400 + 40 + 38 + 22 = 500.)

    (b) b=38b = 38 (A right, B wrong), c=22c = 22. χ2=(∣38−22∣−1)2/(38+22)=152/60=3.75\chi^2 = (|38-22| - 1)^2/(38+22) = 15^2/60 = 3.75. The critical value for 1 degree of freedom at 5% is 3.84, so we cannot reject equal error rates (p≈0.053p \approx 0.053). A 3.2-point accuracy gap on 500 cases is suggestive but not conclusive; collect more test data.

    (c) The 10 fold scores are not independent: any two training sets share about 89% of their data, and every case is in the test fold once. The paired t-test assumes independent differences, so the estimated variance of the mean difference is too small and the test rejects the null too often (an inflated Type I error). Dietterich (1998) documented this and recommended alternatives such as the 5x2cv paired t-test or McNemar's test on a single held-out set; corrected resampled t-tests adjust the variance for the overlap.

Further reading

Go further

Sources

Fact-checked and last reviewed 2026-11-05

Stay in the loop
Prometheus OS™ · Native AI OS · Built for the future © 2025 - 2026