Three public manufacturing datasets, three different data structures, three deliberately different strategies — not one technique applied three times.
| Layer | Dataset | Structure | Method |
|---|---|---|---|
| L1 | SECOM | one wafer = a static snapshot | imbalanced classification + drift monitoring |
| L2 | PHM 2016 CMP | one wafer = an in-process trajectory | time-series virtual metrology |
| L3 | Bosch | one product = a path across stations | process flow graph + attribution |
Weekly fail rate falls 23% → 1–5% over three months. 55–66% of sensors exceed the PSI action threshold in every test segment. And a walk-forward simulation shows no retraining policy beats leaving the model frozen — detecting drift is not the same as being able to fix it.
A path's historical fail rate ranks first of 263 features by importance — and still degrades out-of-time ranking. Train-vs-test correlation: Spearman ρ = 0.09 (p = 0.36).
Error does not grow with tool wear. The most-worn quartile is the most accurate, because consumable usage is an input feature the model already learned.
Problem. 590 sensors per wafer, 6.6% fail. An escaped bad wafer costs ~100× a needless re-inspection. Rank wafers so limited re-inspection capacity lands where failures are.
SPC first. A fab engineer reaches for a control chart, so that is the bar: Hotelling T² on PCA scores catches 8% of failures at 11% false alarms. Failures are not global multivariate outliers — which is what justifies supervised ML.
Threshold from cost, never 0.5. The operating point is the minimum of the expected-cost curve, chosen on a validation window inside training.
I built the sensor correlation network with the standard fMRI functional-connectivity recipe — correlate all pairs, keep the strongest 5% of edges, rank by degree centrality — then tested whether hub sensors make better features than mutual-information top-k.
And against randomly chosen subsets of the same size.
Neither principled method beats random at any k. Both sit inside ±1 sd of the random control everywhere. Nothing beats keeping all 444 features.
Honest label: this is a data-driven correlation network, not a process flow graph. SECOM's sensors are anonymized. The process-flow story is Bosch's.
This sub-project was built around the argument that under drift, a monitor-and-retrain loop matters more than model choice. So I wrote the experiment that tests it: walk forward through the wafer stream, compare four policies at identical windows, refit preprocessing, model and threshold on every retrain.
| policy | PR-AUC | retrains | fails in train | p vs frozen |
|---|---|---|---|---|
| frozen | 0.093 | 0 | 63 | — |
| triggered (PSI fires) | 0.088 | 7 | 79 | 0.30 |
| expanding | 0.088 | 8 | 79 | 0.30 |
| sliding | 0.054 | 8 | 33 | 0.47 |
No policy beat frozen. And that −41% on sliding is not a finding — one window with 5 failures carries 75% of it. Paired window by window: 3–4, p = 0.47.
What it did establish: the PSI trigger fires in 7 of 8 windows, so "retrain when drift is detected" is operationally the same as "retrain always" — the trigger buys no economy here.
Problem. Measuring material removal rate is slow and occupies metrology capacity, and the answer arrives after the run. If the in-process trace predicts it, most wafers skip physical measurement.
The data was supposed to be gone. phmsociety.org now
404s its own download links and the official test labels ship as
?. I recovered the trajectories from the Internet Archive and
found the withheld test labels published separately — 424
(WAFER_ID, STAGE) keys matching the official test set
exactly. So this is scored on the real competition test
set, not a holdout I invented.
The expectation: as the polishing pad and dresser wear, prediction error grows, motivating a retraining trigger on accumulated hours.
| Polishing-table wear | n | MSE | MAE |
|---|---|---|---|
| Q1 fresh | 106 | 8.93 | 2.16 |
| Q2 | 106 | 5.27 | 1.79 |
| Q3 | 106 | 7.43 | 1.90 |
| Q4 worn | 106 | 3.32 | 1.44 |
The most-worn quartile is the most accurate. Consumable usage is an input feature, so the model learned the wear effect rather than decaying with it.
Same split, same official test set, same metric, same static inputs. Only the trajectory encoding differs: ~200 hand-crafted time and frequency descriptors, versus a network reading the raw signals.
| model | track | val MSE | test MSE |
|---|---|---|---|
| XGBoost | hand-crafted | 31.98 | 6.24 |
| RandomForest | hand-crafted | 29.57 | 7.64 |
| BiGRU ×3 seeds | learned | 27.63 | 14.45 |
| Ridge | hand-crafted | 44.47 | 25.17 |
| 1D-CNN ×3 seeds | learned | 18.01 | 28.59 |
Hand-crafted wins by 2.3×. At ~1,600 training runs, compressing a trajectory into physically-motivated descriptors beats asking a network to rediscover them.
Nothing in the data says the stations are connected. Column
names (L3_S36_F3939) encode line and station; date columns encode
the order a product visited them. Those two together are the edge list.
Before claiming ML is needed, run the chart a process engineer reaches for. Hotelling T² compares a unit's measurement vector against an in-control mean and covariance — which presumes every unit is measured the same way.
With 7,927 distinct routes, most measurement slots are empty for most products. Those blanks are stations never visited, not readings that went missing. Imputing them invents in-control behaviour that never happened.
| baseline | recall @UCL | false alarms | PR-AUC | vs random |
|---|---|---|---|---|
| T², all products, imputed | 46.1% | 35.9% | 0.0047 | 1.2× |
| T², largest route family | 6.5% | 5.2% | 0.0051 | 1.5× |
| XGBoost model A | — | — | 0.0244 | 6.2× |
SPC's failure here is structural, not statistical. The plant does not have one process to chart. It has 7,927 — which is exactly the argument for modelling the routing explicitly.
| model | MCC @val | MCC @oracle | PR-AUC | capture@20% |
|---|---|---|---|---|
| A: station aggregates | 0.069 | 0.112 | 0.024 | 0.287 |
| B: + path & graph features | 0.099 | 0.102 | 0.018 | 0.272 |
| C: GNN on routing subgraphs | 0.062 | 0.095 | 0.018 | 0.260 |
MCC needs a threshold. At the oracle threshold — the best
any of them could reach on test — the model without
graph features wins, and every threshold-free metric agrees.
path_risk still ranked first of 263 features by gain.
Model C injects the structure a completely different way — each product becomes a subgraph of stations it visited, so message passing can combine a reading with its neighbours' along the route. It lands with B, behind A. Two independent routes to the same answer.
Why: a path family's historical fail rate does not carry forward. Across 108 families with ≥200 products in both windows, Pearson r = 0.23, Spearman ρ = 0.09 (p = 0.36), while prevalence drifts 0.66% → 0.40%. The encoding memorised a level, not a property.
"All pass" scores 93% on SECOM and 99.4% on Bosch. Reported instead: PR-AUC, MCC, expected cost under an asymmetric matrix, and decile capture — because inspection capacity is the real constraint.
Public Bosch solutions reach MCC ≈ 0.4+ largely through row-Id
ordering, which leaks the response. Excluded. My numbers are what the
process data supports.
4.7 GB across ~2,100 sparse columns: read in 100k-row chunks and collapsed to per-station aggregates before anything is held at once. Missing values are routing information ("never visited this station"), preserved as visit counts and left as NaN — never imputed.
common/ holds metrics, splits, SPC baselines and drift
monitoring, used by all three sub-projects. 20 unit tests, including one
that catches an int64 overflow in the MCC threshold search at scale.
Every one of these projects has a place where the obvious reading of the numbers was wrong:
| looked true | the check |
|---|---|
| graph features lift MCC 43% | oracle threshold |
| hub selection beats mutual info | random control |
| virtual metrology R² 0.993 | within-cluster fit |
| error grows with tool wear | stratified error table |
| the 1D-CNN is the best model | held-out test + seed spread |
| sliding retrain is 41% worse | paired Wilcoxon per window |
| retraining fixes drift — my own claim | walk-forward simulation |
Each cost one extra diagnostic. None of them needed a bigger model. The last one cost me my own headline claim, which I rewrote rather than defended. That is the habit I would bring to a yield team.