CSC3119 · Module 1 of 9

Data Preparation, Preprocessing Leaks & Clinical Imbalance

Turn messy clinical hospital registries into leak-free deployable pipelines

~56 min to study properly

A trained machine learning model is only as dependable as the data engineering feeding it. In the Uganda Regional Referral Hospital stroke dataset, we face missing BMI values, string encodings, and extreme class imbalance.

Checkpoint · the examiner asks

Why is accuracy a dangerous metric for clinical triage with 5% positive cases, and why must data scalers and SMOTE oversampling never touch the test set?

In one minute

Leakage is the cardinal sin: fit scalers, imputers and SMOTE on the training split only, ideally inside an sklearn Pipeline/ColumnTransformer, or test information inflates your metrics. With ~4.9% stroke prevalence, a model that always predicts 'no stroke' scores 95% accuracy and misses every patient — judge clinical models by recall, precision and PR-AUC.

Traps examiners look for
  • Calling fit_transform on the full dataset before train_test_split.
  • Applying SMOTE to the test set.
  • Celebrating 95% accuracy on a 5%-positive problem.
Read

Study notes

01The stroke dataset and why it is hard

The capstone uses a stroke-risk dataset from a Ugandan Regional Referral Hospital: age, gender, hypertension, heart disease, average glucose level, BMI, smoking status, work type, residence — and whether the patient had a stroke. Three properties make it a good teacher:

  • Missing values — BMI is blank for a few percent of patients.
  • Categorical strings — work_type, smoking_status need encoding before most models can use them.
  • Extreme class imbalance — only about 4.9% of patients had a stroke.

Each of these has a correct, standard treatment. The danger is applying it in a way that quietly leaks information or optimises the wrong metric.

02The accuracy paradox

With 4.9% positives, a "model" that always answers no stroke is right for 95.1% of patients. Its accuracy is 95.1% — and its recall is 0%: every stroke patient is sent home.

For clinical triage the costs are lopsided: a false negative (missed stroke) can be fatal; a false positive (an extra clinic visit) costs time. So we judge models by:

  • Recall / sensitivity = TP / (TP + FN) — what share of stroke patients we catch.
  • Precision = TP / (TP + FP) — what share of flagged patients actually have the condition.
  • F2 score — a harmonic mean that weights recall more than precision.
  • PR-AUC — area under the precision–recall curve, more informative than ROC-AUC when positives are rare.

Always look at the confusion matrix, not one number.

03Data leakage

Leakage is any way information from the test set (or the future) reaches training. The classic version:

X_scaled = StandardScaler().fit_transform(X)       # ✗ statistics from ALL rows
X_train, X_test, ... = train_test_split(X_scaled, y)

The scaler's mean and standard deviation now include test patients, so the test score is optimistic. The same applies to imputing with a mean computed on all rows, selecting features using all rows, or oversampling before splitting.

The fix is to split first, then fit every learned transformation on the training split only. The cleanest way is an sklearn Pipeline: pipeline.fit(X_train, y_train) fits the imputer, scaler, encoder and model on training data, and pipeline.predict(X_test) only applies them.

04Pipelines, ColumnTransformer and SMOTE

prep = ColumnTransformer([
    ("num", Pipeline([("impute", SimpleImputer(strategy="median")), ("scale", StandardScaler())]),
     ["age", "avg_glucose_level", "bmi"]),
    ("cat", OneHotEncoder(handle_unknown="ignore"), ["work_type", "smoking_status", "gender"]),
])
model = ImbPipeline([("prep", prep), ("smote", SMOTE()), ("clf", XGBClassifier())])
  • ColumnTransformer applies the right preprocessing to each column group.
  • handle_unknown="ignore" stops the API crashing on a category it never saw.
  • SMOTE creates synthetic minority examples by interpolating between real stroke patients. Inside an imblearn pipeline it runs only during fit, so test data is never oversampled. Alternatives: class_weight="balanced" or XGBoost's scale_pos_weight (≈ negatives / positives ≈ 18).

The whole pipeline is what you save and deploy — that's what makes the preprocessing identical in production.

Watch it done

Worked examples

Worked example 1

The trivial model's scorecard

3,000 patients, 5% stroke prevalence. Compute accuracy, recall and precision for a model that always predicts 'no stroke'.

    Worked example 2

    Computing F2

    A model has precision 0.32 and recall 0.86. Compute F1 and F2 and explain why F2 suits triage.

      Vocabulary

      Key terms

      The Silent Killer of Production ML: Train-Serve Skew

      Google's landmark paper on ML technical debt notes that differences between training data pipelines and real-time inference code account for over 60% of production prediction failures. Bundling ColumnTransformers directly into model artifacts eliminates manual feature recreation bugs.

      Practise

      Quick check

      0 of 8 correct so far. Wrong answers come with an explanation — and the buddy can unpack them.

      Q1In a hospital cohort of 2,000 patients, 100 experience a stroke. A baseline model predicts 'No Stroke' for all 2,000. What is its accuracy and recall?

      Q2Which preprocessing step causes data leakage if executed before train_test_split?

      Q3What is wrong with calling StandardScaler().fit_transform(X) before train_test_split?

      Q4Recall measures…

      Q5Where should SMOTE be applied?

      Q6Why OneHotEncoder(handle_unknown='ignore')?

      Q7For rare positives, which curve is more informative?

      Q8XGBoost's scale_pos_weight for ~5% positives is roughly…

      Exam-style

      Written practice

      Short answer5 marks

      Explain why accuracy is misleading on the stroke dataset and which metrics you would use instead.

      Short answer5 marks

      Define data leakage and give two examples of how it can happen in preprocessing.

      Long answer12 marks

      Design the preprocessing and training pipeline for the stroke model. Cover missing BMI, categorical features, scaling, class imbalance, evaluation metrics and how you guarantee zero leakage and identical preprocessing in production.

      Watch

      Videos

      Fresh picks are chosen by AI every day.
      Hands-on

      Clinical Feature Preparation, Scaler Leakage & Imbalance Simulator

      5 guided tasks: predict, experiment, explain — then challenge yourself. Plus 2 coding exercises you run right in the browser.

      Start the lab