0

Google Cloud × Methanex Hackathon at UBC Sauder · 1st Runner-Up

AI-Driven Anomaly Detection — Industrial Sensor Intelligence

Built an early-warning system for industrial process failures across 200+ sensor channels, combining Isolation Forest, LSTM and Autoencoder ensembles with a Gemini-powered chat interface for operator queries. Shipped a Streamlit monitoring dashboard, a simulated real-time streaming pipeline, and automated alerting workflows, deployed to GCP with a modular Python codebase.

The problem

In a methanol plant, equipment doesn't usually fail all at once — it drifts, and by the time a process excursion trips an alarm, the damage window has already opened. Operators were watching hundreds of sensor channels by eye, which doesn't scale and misses the slow degradation patterns that precede a failure.

Constraints

This was a hackathon build (Google Cloud × Methanex at UBC Sauder), which shaped every decision.

  • Data. No live plant feed and no labeled failure set. I worked from historical sensor exports and a simulated streaming pipeline — which meant "anomaly" had to be defined statistically and against historical incident logs, not against a clean ground-truth of real failures.
  • Latency / operability. The output had to look like something an operator could actually use during a shift: a live dashboard and alerts, not a notebook. That pushed toward lightweight, streaming-friendly models over anything that needed a GPU cluster.
  • Stakeholder. The judges — and the plant staff the scenario was built around — are process engineers, not ML people. Detections that couldn't be explained in plant terms were worthless, however good the ROC curve.
  • Time. A hackathon clock. Scope had to land on something that demonstrably worked end to end rather than one over-tuned model.

Approach

First attempt — a single model. I started with one Isolation Forest across all channels. It caught sudden spikes well but was blind to slow drift — a bearing degrading over 30 hours never looks like a point outlier in any single reading. A single detector was structurally the wrong tool because industrial failures span very different signatures.

Second attempt — an ensemble by failure mode. I split detection across three complementary methods and combined them:

  • Isolation Forest for point anomalies (sudden spikes), isolating outliers by random partitioning — O(n log n) and streaming-friendly, unlike LOF, which is quadratic. Contamination was set to 0.02 from historical incident rates.
  • LSTM Autoencoder for temporal anomalies (drift, gradual degradation): it learns normal sequence dynamics and its reconstruction error spikes on unfamiliar patterns. I used a sequence length of 48 (48 hours of hourly readings) and a latent dimension of 32, chosen on held-out reconstruction error.
  • Statistical baselines (z-score, moving-average envelopes, residuals) — the interpretable layer operators can reason about and trust.

The three vote into a weighted ensemble score. On top I shipped a Streamlit dashboard, a simulated real-time streaming pipeline, automated alerting workflows, and a Gemini-powered chat interface so an operator could ask "which sensors triggered last week?" in plain English — deployed to GCP as a modular Python codebase.

Evaluation

Because there was no clean ground-truth of real failures, I was honest with myself about what "it works" could mean here, and evaluated on three fronts.

Detection quality against historical incidents. Using Methanex's historical incident logs as weak labels, the ensemble reached roughly 94% precision on flagged events with a false-positive rate under ~3% per week, and surfaced anomalies 24–48 hours ahead of the logged excursion in the cases we could line up. These are hackathon-grade numbers on historical and simulated data — directional evidence the approach is sound, not a validated production SLA.

Ablation — did the ensemble earn its complexity? The most useful result was comparative: Isolation Forest alone missed the slow-drift cases entirely, and the LSTM autoencoder alone was noisier on clean spikes. The ensemble's advantage came specifically from covering both failure modes — which is the whole argument for the added complexity, and the thing I'd defend in a design review.

Usability. The chat interface and dashboard were evaluated the soft way a hackathon allows — could a non-ML judge ask a question and get a defensible answer? That's what the "1st Runner-Up" result reflects: a system that a process engineer could actually operate.

What the metrics don't capture. The precision and false-positive numbers rest on historical logs and simulated streaming, so they almost certainly flatter real-world performance — a live plant has sensor faults, maintenance windows, and regime changes that a replay doesn't. The lead-time figure is measured on the handful of incidents we could align, not a representative sample. And precision says nothing about the failure that matters most in operations: the missed anomaly. Without a real labeled failure set, recall on true novel failures is the number I genuinely couldn't measure — and it's the one a plant would care about most.

What I'd do differently

  • Design the evaluation around recall, not precision. I optimized toward flagging real anomalies cleanly, but in process safety a missed failure dwarfs a false alarm. I'd invest first in constructing a labeled (even semi-synthetic) failure set so I could measure recall honestly, and tune the ensemble thresholds against that.
  • Add drift monitoring on the detector itself. The models assume "normal" is stationary. Plants change — new setpoints, seasonal effects. Without monitoring for concept drift, the autoencoder's baseline goes stale and false positives creep up. I'd bake that in from the start.
  • Calibrate the ensemble weights, don't hand-set them. The vote weights were tuned by judgment under time pressure. A small labeled validation set and a proper calibration step (or a simple stacked meta-model) would make the combined score far more defensible than three hand-chosen coefficients.