Delayed Coker Yield Optimisation
Diagnosing post-COVID model drift and building a hybrid ML + evolutionary optimiser to lift refinery yield by ~2%.
Impact at a glance
↑ ~56 points
Model accuracy (R²), from negative to positive
~2%
Yield improvement
Problem
Built during COVID-era refinery turndowns, the client's yield prediction model collapsed once normal operations resumed—scoring worse on recent data than simply guessing the historical average. Simply retraining on fresh data failed. My objective was threefold: uncover why the model was blind to the new operating regime, rebuild it for both accuracy and physical explainability, and use it to recommend optimal operating settings.
To understand why operating regimes shift, it helps to see what happens inside the unit:
How a Delayed Coker Works
0. Full-colour overview
The complete process: water in blue, hydrocarbons in purple, naphtha in pink, and hot feed in red.
Confidentiality & Proxy Walkthrough
To protect client IP, the technical deep-dive below demonstrates the exact same mathematical pipeline on an open engineering benchmark (UCI Concrete Compressive Strength).
Solution
The fix came in three parts: repair the evaluation, rebuild the model, then optimise on top of it.
1
Fix the Evaluation Split
Stop regime blindness by replacing sequential splits with stratified time-block sampling.
2
Build a Hybrid Model
Pair Ridge Regression (global physical trends) with LightGBM (local nonlinear residuals).
3
Optimise with Constraints
Run Differential Evolution across the discontinuous model surface to find peak settings safely.
Act I: Fixing a Blind Evaluation Split
Before touching the algorithm, I audited how the data was split. The model wasn't failing because the math was bad—it was failing because it had never seen the current operating regime during training.
- Diagnosis: The legacy 90:10 sequential split placed all recent post-COVID months into the test set, leaving the training set completely blind to the new operating regime.
- Fix: Implemented block-stratified sampling—training on alternating 2-month blocks and testing on the 1-month blocks in between so every operating regime is represented without temporal leakage.
- Outcome: R² jumped ~56 points (from negative back to positive) and RMSE dropped by ~17%.
Illustrative schematic, not client data.
Act II: Combining Physical Trends with Nonlinear Corrections
With an honest evaluation baseline in place, we needed a model that refinery engineers could trust. Pure tree models capture complex quirks but fail to extrapolate clean physical trends; linear models capture trends but miss local interactions.
The hybrid model: Ridge for the trend, LightGBM for what it missed.
Explore the interactive sandbox below to see how Ridge establishes the baseline trend first, leaving LightGBM to learn only the leftover residuals:
Watch the hybrid model get built
A toy example with made-up data, to show the idea. Not the concrete model.
1Ridge draws the trend
f_ridge(x) = β₀ + β₁·x
2What Ridge missed
r = y − f_ridge(x)
3LightGBM learns the misses
g(x) ≈ r
4Final prediction
ŷ = f_ridge(x) + g(x)
Step 1 of 4: Ridge draws the trend. Hold-out RMSE: Ridge 3.04, hybrid 2.39.
Ridge captures the trend. LightGBM only has to learn what is left over. Add the two and you get a model that is accurate and still easy to explain.
On the open benchmark, the engineered Hybrid model beat all five alternatives (Test R² 0.915, RMSE 4.71 MPa)—delivering gradient-boosted accuracy while retaining a clear linear backbone.
Model comparison on the open concrete dataset (RMSE, lower is better).
Act III: Searching a Stepped Surface with Differential Evolution
Predicting yield is only half the battle—operators need recommended setpoints. Because LightGBM partitions data into discrete splits, the hybrid model's response surface is full of flat steps where gradient-based optimisers get stuck. Differential Evolution (DE) solves this by evolving a population of candidate recipes across the landscape without needing derivatives.
The three moves DE repeats every generation.
Interactive Concept
How Differential Evolution escapes local traps:
Differential Evolution on a test function (Rastrigin)
A toy problem to show how the search works. Not the concrete model.
Best value · log scale
- Generation
- 0 / 150
- Best value
- 9.9782
- Best position (x, y)
- (-1.0682, 1.1933)
- Distance to (0, 0)
- 1.60151
Global minimum: f(0, 0) = 0
Generation 0: best 9.9782 · Paused
Current best result at generation 0: value 9.978212755802094, position -1.0681560349464416, 1.1932668161392213, distance from the true minimum 1.6015127253604755.
Each generation, DE mixes three points to propose a new one and keeps it only if it is better. Over time, the whole population collapses onto the best region.
Act IV: Recommending the Optimal Settings (and Reality-Checking Them)
Applying DE directly to our trained Hybrid Model, each candidate represents a physical recipe (water and cement bounds). The optimiser searches for the highest predicted strength while respecting real-world mass and ratio constraints.
How the search is scored: the hybrid model predicts each mix's strength, and DE minimises the sign-flipped prediction.
Watch the optimiser search
The real run: Differential Evolution searching cement and water for the strongest concrete mix. The surface is the hybrid model's predicted strength.
Generation 0: best — · Search complete
Each dot is a candidate recipe. The red marker is the strongest mix found so far. Watch the population spread out, then collapse onto the best region.
Outcome & Engineering Sanity Check
The Recommendation
86.1 MPa Predicted Peak
Up from the 78.8 MPa maximum observed in historical data (mirroring the ~2% yield lift achieved on the live refinery coker).
The Reality Check
73.6 MPa Cross-Check
Optimisers love to exploit model blind spots. When cross-checked against an independent model, the same recipe scored 73.6 MPa—proving why ML recommendations must be treated as bounded candidates for physical validation, not blind autopilot settings.
Key takeaways
01
Fix the evaluation before the model. A leaky split hid a failing model behind healthy-looking scores.
02
Use a simple model for the trend and a flexible one for the corrections: accurate and still explainable.
03
Optimisers exploit model blind spots. Constrain them, cross-check them, and validate before acting.