Fine-tuning playbook

How to improve a research risk model with this framework. “Fine-tuning” here means systematic iteration of tabular models (features, splits, family, calibration) — not LLM fine-tuning.

1. What you can tune

KnobWhereEffect
Dataset / mappingDatasets page, map-import APIBetter inputs → better ceiling
Task YAMLtasks/*.yaml, Train presetsHorizon, windows, index, label column
WindowsConfig / Train / windows_daysShort vs long history signal (w7d…)
SplitPatient vs temporalHow hold-out generalizes
Model familylogreg, RF, XGBoost, LightGBMBias/variance trade-off
Calibratecheckbox / --calibrateBetter probability quality (Brier/ECE)
Compare setConfig compare_modelsPick best of several families
Promotetrain promote / compare promote_bestActive model.pkl for Predict

2. The iteration loop (diagram)

3. Workbench steps (recommended)

  1. Datasets — select or upload CSV → Run health → Continue to train only when ready.
  2. Config — set windows (e.g. 7, 30, 180), default model, compare models, optional calibrate.
  3. Train — apply a task preset (diabetes / …) → Train once as baseline.
  4. Train → Leakage audit — if temporal issues appear, fix index/horizon before chasing AUROC.
  5. Train → Compare — multi-model ranking; promote best when satisfied.
  6. Results / Analytics — metrics, importance, cohort filters (age/label/patient).
  7. Results → Generate SHAP — explanations for demos and debugging.
  8. Predict — schema form; keep “reuse as next input” while exploring what-if values.
Train page
Train page — presets, train, compare, leakage

4. CLI / Make recipes

# Baseline
make train

# Stronger evaluation habits
make train-patient          # patient-grouped split
make train-temporal         # time-based hold-out

# Trust
make leak-audit
make shap

# Explicit CLI with calibration + multi-window
PYTHONPATH=. python -m training.train \
  --format longitudinal \
  --data data/raw/paper_synthetic_cohort.csv \
  --model xgboost \
  --windows 7,30,180 \
  --split-by-patient \
  --calibrate

# Multi-model compare via API (stack running)
curl -sS -X POST http://127.0.0.1:8000/v1/jobs/compare \
  -H 'Content-Type: application/json' \
  -d '{
    "data_path":"data/demo/ehr_data.csv",
    "data_format":"longitudinal",
    "split_by_patient":true,
    "windows_days":[7,30,180],
    "promote_best":true
  }' | jq .

5. Knob reference (practical advice)

Windows

Too short → miss chronic signal. Too long → noise / leakage risk if index is wrong. Start with [7,30,180].

Patient vs temporal split

Patient split avoids same-person leakage across folds. Temporal split tests future performance — use when timestamps are reliable.

Model family

LogReg = interpretable baseline. Trees / XGBoost = more capacity; always pair with SHAP + calibration checks.

Calibrate

Turn on when Brier/ECE are poor even if AUROC looks fine. Isotonic wraps the fitted estimator.

6. Compare → promote (data flow)

7. Stop checklist (before you claim success)

CheckPass criterion
HealthNo blockers (or documented force with persona rules)
Leakage auditNo temporal / patient-disjoint red flags you ignore
DiscriminationAUROC / PR-AUC reported with split type
CalibrationBrier / ECE inspected; calibrate if needed
ExplainSHAP drivers make clinical-research sense
LimitsYou can state what the model is not (see LIMITATIONS.md)

Diagrams of the wider system: Design & architecture diagrams.