Safiul Azam Data & Information Management
Pythonscikit-learnXGBoostHealthcare

Predicting Dengue from a Routine Blood Test

A screening model built on real hospital haematology from Jamalpur, tuned to catch 96% of dengue cases — because during an outbreak, a missed case costs more than a false alarm.

RoleAnalyst & developer
OrganisationIndependent project
Year2026
ToolsPython · scikit-learn · XGBoost · pandas

This project can be shown in full. It uses a public dataset with no sensitive content, so every figure, method and result on this page is the real thing — the visuals are screenshots of the working output, not rebuilds.

Context

During a dengue outbreak, hospitals in Bangladesh run out of confirmatory test kits before they run out of patients. Almost everyone with a fever gets a full blood count anyway — it is cheap and routine. The question is whether that blood count alone carries enough signal to decide who should be pushed to the front of the queue for a confirmatory test.

The data is real: patients at a hospital in Jamalpur, Bangladesh, between February and September 2024, published as a documented dataset with a citation. Not synthetic, and locally relevant — which mattered to me for a problem that affects where I live.

Approach

  • Feature engineering from clinical thresholds. Rather than inventing bins, blood measurements are categorised at the cut-offs doctors actually use — a platelet count below 150,000 is labelled Low because that is where clinicians start to worry, and low platelets are a classic dengue signature.
  • Gradient descent written from scratch before reaching for a library, to understand what the optimiser is actually doing rather than treating .fit() as a black box.
  • Unsupervised clustering first — and it failed usefully. Dengue does not leave a mark strong enough to separate patients on its own. That negative result is exactly what justified moving to a supervised model instead of assuming one was needed.
  • Overfitting demonstrated, then fixed. An unrestricted decision tree hit 99.9% training accuracy against 67.9% validation — a 32-point gap. Grid Search brought that to 79.7% / 77.0%: lower training accuracy, and a far better model. That single tree was a diagnostic step, not the final model — the tuned Random Forest that produced the results below was built on the same validated settings.
  • Recall chosen deliberately over accuracy. A missed dengue case can be sent home while their platelets fall. A false alarm costs a test kit and some worry. Those are not symmetrical, so the metric should not be either.

Results

Real hospital haematology data from Jamalpur, Bangladesh (Kaggle, cited dataset). These are the actual model outputs.

96.2%Recall — real cases caught
84.6%F1 score
75.5%Precision
76.1%Accuracy — the least useful metric here
Real output · public dataset Confusion matrix on the test set showing 200 true positives, 8 false negatives, 65 false positives and 32 true negatives
The confusion matrix is the whole argument. 200 of 208 real dengue patients caught; 8 missed. The cost is 65 healthy patients flagged for a confirmatory test they did not need — which for a screening tool is the right trade to make.
Real output · public dataset Line chart of training and validation accuracy against decision tree depth, showing the two lines diverging as depth increases
Overfitting made visible. As tree depth grows the training line keeps climbing while validation peaks and turns down — the signature of a model memorising patients instead of learning patterns.
Real output · public dataset Hierarchical clustering dendrogram of a 500-patient sample showing no clean separation between groups
The clustering step, and the reason it mattered. The dendrogram finds groups — but they do not line up with dengue status. That negative result is what justified moving to a supervised model rather than assuming one was needed.

Outcome

96.2% recall — 200 of 208 caught

On the held-out test set the tuned Random Forest reached 96.2% recall, catching 200 of 208 real dengue patients and missing 8. Precision was 75.5%, F1 84.6%, overall accuracy 76.1%.

Accuracy is the number I would trust least here. With uneven classes it can look respectable while a model does something lopsided. For a screening tool the question is simply how many sick people slip through, and on that measure the model behaves the way a first-pass screen should: it casts a wide net.

The recommendation is bounded accordingly — this is a triage aid, not a replacement for the confirmatory test. It flags likely-positive patients from a blood count that has already been taken, so limited kits and monitoring go where they are most likely to be needed.

What I’d do differently

The cost of choosing recall is real and worth stating: 65 healthy patients in the test set were flagged, and each would need a confirmatory test. A hospital can only run this screen if it can afford the extra testing the false alarms create. In a very low-resource setting the decision threshold would need moving toward precision, accepting that a few more cases slip through.

The data came from a single hospital in a single season, so I would not assume the model transfers to another district or another year without revalidation. Testing across multiple hospitals is the next step, and until that is done the model should support clinical judgement rather than substitute for it.