Skip to content

Case 03 · Clinical ML

Prosthetic joint infection pre-diagnosis

A model that produces a result is not a model a hospital can use. So I built it through to deployment.

Role
Modelling, front end, back end, deployment
Built with
scikit-learn · XGBoost · SHAP · pyeda · Flask · Docker
Data
324 records, 11 clinical features
All work
Real interface screenshot: the model's decision paths, as the tool draws them.

01The problem

Infection after joint replacement has to be judged before revision surgery, from bloodwork and comorbidity indices rather than certainty. An accurate model is necessary but not sufficient: a clinician has to be able to see why it said what it said.

02What it does

A stacking ensemble makes the prediction; a Random Forest is then fitted to interpret it, and the resulting decision rules are minimised until they are short enough to read. SHAP values sit beside the result so a single case can be argued with, not just accepted.

Real interface screenshot: the same decision path, written out by the tool as rules.
Transcribed from the screenshot above, character for character: all seven clauses.
Decision pathif ( Positive_Histology == False & two_positive_culture == False & APTT <= 32.5 & APTT > 28.5 & Synovial_WBC <= 2795.0 & Total_Elixhauser_Groups_per_record <= 1.5 & PLATELET <= 321.0 & Synovial_PMN <= 83.0 )| ( Positive_Histology == False & two_positive_culture == False & Segment <= 70.5 & Single_Positive_culture <= 0.5 & Synovial_PMN <= 87.5 )| ( Positive_Histology == False & Synovial_PMN <= 82.5 )| ( Positive_Histology == False & Synovial_PMN <= 82.5 & Hb > 12.5 )| ( Positive_Histology == False & APTT <= 32.5 & Synovial_PMN <= 82.5 & Synovial_WBC <= 8280.0 & Serum_ESR <= 58.5 )| ( Positive_Histology == False & APTT <= 32.5 & Synovial_WBC <= 23099.0 & Age > 48.5 )| ( two_positive_culture == False & Hb > 12.5 & Serum_ESR <= 57.0 & PLATELET <= 402.5 & Synovial_WBC <= 21314.0 )then infected

03Getting it into a hospital

Flask front and back end, login, patient records, an interactive prediction page, packaged in Docker so it can be stood up somewhere other than a laptop. The rule minimisation is expensive: the app takes over two minutes to boot. That is a cost worth paying once at startup rather than on every request.

2
models: one to predict, one to explain
Links
Source (private repository)

100%

Drag or scroll to move · pinch, + or − to zoom · Esc to close