LightGBM classifier predicting the severity of a Queensland road crash
given pre-/at-crash conditions. Classes: fatal, hospitalisation, medical treatment, minor injury.
Disclaimer. This is a population-level statistical model trained on publicly reported crash data. It is NOT suitable for individual driver risk assessment, insurance underwriting, pre-incident law enforcement targeting, or any decision with legal or financial consequence to an individual. Use it for research, road-safety analysis, and education.
Quick start
python
1from huggingface_hub import hf_hub_download
2import joblib, lightgbm as lgb, json
34REPO ="Mattysmittttt/crashrisk-qld-severity"5booster = lgb.Booster(model_file=hf_hub_download(REPO,"model.txt"))6pre = joblib.load(hf_hub_download(REPO,"preprocessor.joblib"))7classes = json.loads(open(hf_hub_download(REPO,"label_classes.json")).read())8# `pre` is a fitted sklearn ColumnTransformer; pass a DataFrame whose9# columns match the dataset's ✅ feature columns. See dataset card for10# the schema, and feature_importance.csv for the names this model uses.
Intended uses
Road-safety research and descriptive analytics.
Education on tabular ML, class imbalance, and leakage prevention.
As a baseline severity model in road-safety pipelines.
Out of scope
Insurance underwriting — using population-level statistical patterns
to set individual premiums creates fairness concerns and is outside this
model's intended scope.
Individual driver risk assessment — these features describe road
conditions and aggregate vehicle context, not driver behaviour or
identity.
Pre-incident law enforcement targeting — geographic patterns may
reflect reporting biases as much as actual risk; using them to pre-target
locations creates feedback loops.
Any decision with legal or financial consequence to a single
individual — full stop.
Training data
See the dataset card for
full provenance, cleaning, schema, and split definition.
Train (2011–2022): 152,842 rows
Validation (2023): 13,622 rows (used for early stopping
and Optuna HPO)
Features after preprocessing: 173
(low-card → OHE, high-card → TargetEncoder, numerics passthrough)
Evaluation (held-out test = 2024)
Accuracy: 0.4404 (sanity check: must NOT exceed
0.70 — observed: ok)
Macro-F1: 0.3259 [95% bootstrap CI 0.3164, 0.3351]
Log-loss: 1.1820 [1.1680, 1.1965]
Per-class metrics
class
precision
recall
f1
support
fatal
0.077
0.117
0.093
273
hospitalisation
0.609
0.580
0.594
7,051
medical treatment
0.402
0.225
0.288
4,409
minor injury
0.255
0.462
0.328
2,625
Confusion matrix
Rows = actual, columns = predicted.
—
pred fatal
pred hospitalisation
pred medical treatment
pred minor injury
actual fatal
32
198
11
32
actual hospitalisation
269
4088
949
1745
actual medical treatment
79
1565
990
1775
actual minor injury
34
866
512
1213
Top 20 feature importances (LightGBM gain)
loc_suburb_0 (gain = 1574725)
loc_suburb_3 (gain = 574071)
crash_hour (gain = 562661)
loc_abs_statistical_area_2_0 (gain = 468933)
count_unit_car (gain = 466195)
crash_year (gain = 464291)
loc_suburb_2 (gain = 403835)
loc_suburb_1 (gain = 391710)
crash_longitude (gain = 367704)
crash_latitude (gain = 332986)
loc_abs_statistical_area_2_3 (gain = 300528)
loc_post_code_0 (gain = 260922)
crash_speed_limit (gain = 254960)
loc_post_code_3 (gain = 242106)
loc_abs_statistical_area_2_2 (gain = 240559)
loc_abs_statistical_area_2_1 (gain = 235112)
loc_post_code_2 (gain = 199437)
loc_post_code_1 (gain = 194552)
loc_state_electorate_3 (gain = 183491)
loc_state_electorate_0 (gain = 183178)
SHAP explainability
Global and local SHAP plots for this model are in the
reports/shap_severity/ folder of the source repository:
summary_bar.png — mean |SHAP| across the test sample
summary_beeswarm.png — per-feature SHAP distribution
dependence_*.png — top-6 features
force_plot_examples.png — TP / TN / FP local explanations for the
fatal class
values.parquet — raw SHAP values, reproducible
Geographic surface
Per-LGA mean predicted P(fatal) under a fixed condition grid (wet/dry ×
day/night × intersection/no-feature × 60 km/h vs 110 km/h) is published in
reports/maps/ of the source repository as both interactive HTML and
static PNG.
Limitations & biases
Trained on reported crashes only — under-reporting is real.
Possible feedback loops if used to allocate enforcement or
infrastructure spend (geographic risk concentrates because past
incidents concentrated, not necessarily because future ones will).
Geographic coverage variance across QLD: urban LGAs are very
well-represented; remote LGAs much less so.
Temporal drift: 2011–2024 includes vehicle-safety improvements,
regulatory changes, and recording-system migrations.
Ethical considerations
Population-level, not causal: The model encodes correlations between
pre-crash conditions and recorded outcomes. It does not assign fault and
cannot be read as a statement about individual responsibility.
Geographic predictions can stigmatise: We publish per-LGA aggregates
only, never per-address. Even at LGA level, higher predicted risk reflects
historical reporting and demographics as much as it does inherent road
danger.
Demographic features deliberately excluded: We do not include gender,
age, or any demographic field, even though some are present in the
casualties aggregates. This is to avoid encoding protected-class proxies.
Vehicle-type counts are kept because they describe the crash configuration,
not the people involved.
Reporting bias: This is a model of reported crashes, not true
crashes. Under-reporting is differential by severity (PDO under-reported,
fatal generally fully reported) and by region.