Unsupervised anomaly detection on industrial bearing vibration data, using the NASA IMS Bearing Dataset — three real test-to-failure experiments where bearings ran until physical failure (inner race, outer race, and roller element defects).
Relevant domains: Industrial IoT · Predictive maintenance · Condition monitoring
The goal: detect degradation before catastrophic failure, using only healthy operating data for training — no labeled failure examples needed at training time, mirroring a real predictive-maintenance scenario.
Bearings degrade gradually, then fail catastrophically. By the time vibration is audibly or visibly abnormal, a machine may already be hours from failure. Catching degradation early — from statistical patterns in vibration data alone, without ever having seen a failure before — is the core challenge of predictive maintenance, and the reason this is framed as unsupervised anomaly detection rather than classification.
- Feature extraction — raw 1-second vibration snapshots (20,480 points, 20kHz) are converted into 8 statistical features per channel per timestamp (mean, std, skew, kurtosis, entropy, RMS, max, peak-to-peak).
- EDA — trend analysis per bearing, correlation analysis to trim redundant features, and visual identification of each dataset's failure onset.
- Modeling — both an Isolation Forest and an Autoencoder are trained only on healthy-labeled data for each test run, then scored across the full timeline (healthy + failure).
- Threshold tuning — default/naive thresholds significantly underperformed; both models were re-tuned via precision-recall curve optimization (F1-optimal threshold) against each dataset's known failure onset.
- RMS vs. kurtosis lead time is failure-mode dependent. Kurtosis (sensitive to sharp, impulsive shock events) sometimes gives earlier warning than RMS (overall vibration energy) — but not always. In one case (gradual outer-race wear) the two moved together; in another (severe spalling), kurtosis actually dropped near failure as vibration became more continuous than impulsive.
- Threshold selection mattered more than model choice. Both models' default/naive thresholds performed markedly worse (precision as low as 0.27 on one set) than after F1-optimal tuning — after tuning, both models converged to comparable, strong performance across all three datasets.
- One dataset — with two overlapping failure modes on the same test — was consistently the hardest case for both models. A genuine limitation, not a bug, and a useful stress test for comparing model robustness.
| Dataset | Failure mode | Isolation Forest F1 | Autoencoder F1 |
|---|---|---|---|
| Set 1 | Inner race + roller defect (overlapping) | 0.81 | 0.90 |
| Set 2 | Outer race failure | 0.98 | 0.98 |
| Set 3 | Outer race failure | 0.99 | 1.00 |
All results after F1-optimal threshold tuning via precision-recall curve. Both models trained exclusively on healthy-labeled data.
The live demo has two modes:
- Historical Exploration — browse RMS/kurtosis/skew/entropy trends per bearing across all three test runs, with the labeled failure onset marked, plus a feature correlation heatmap and the results table above.
- Live Prediction — score any reading against either trained model. Upload
your own
setN_timefeatures.csvand pick a timestamp, or use manual entry with one-click "load normal/anomaly example" buttons. Includes a session history table so you can compare both models on the same reading.
This project also includes a standalone FastAPI serving layer (main.py),
built and validated independently — it loads the same trained models and
exposes /predict and /predict/set1 REST endpoints. The original plan was
for the Streamlit dashboard to call this API as its backend.
Partway through deployment, Hugging Face abruptly moved their Docker Spaces SDK
behind a paywall with no prior notice — which would have been the natural home
for a combined FastAPI + Streamlit deployment. Rather than pay for hosting a
portfolio demo, the dashboard was reworked to load the trained models directly
(the same pattern used in RUL-Predictor),
enabling a free deployment on Streamlit Community Cloud with no external API
dependency. main.py remains fully functional as a standalone service for
anyone who wants to run it separately (e.g. uvicorn main:app --reload).
├── data/
│ ├── raw/ # NASA IMS dataset (not included — see below)
│ └── processed/ # Extracted feature CSVs
├── models/ # Trained models, scalers, tuned thresholds
├── notebooks/
│ ├── 01_feature_extraction.ipynb
│ └── 02_eda_modelling.ipynb
├── main.py # Standalone FastAPI serving layer (optional)
├── dashboard.py # Streamlit app (loads models directly)
└── requirements.txt
The raw dataset isn't included in this repo (large, not mine to redistribute).
Download it from the
NASA Prognostics Data Repository,
and place the three test folders under data/raw/.
pip install -r requirements.txt
# 1. Extract features from raw data (skip if using pre-extracted CSVs)
jupyter notebook notebooks/01_feature_extraction.ipynb
# 2. Run EDA + train/save models
jupyter notebook notebooks/02_eda_modelling.ipynb
# 3. Run the dashboard (loads models directly, no API needed)
streamlit run dashboard.py
# Optional: run the standalone FastAPI service separately
uvicorn main:app --reload| Component | Purpose |
|---|---|
| Python | Core language |
| NumPy / Pandas | Data handling |
| Scikit-learn | Isolation Forest, evaluation metrics |
| TensorFlow / Keras | Autoencoder |
| Matplotlib / Seaborn | Visualization |
| Streamlit | Interactive dashboard |
| FastAPI | Standalone REST serving layer (optional) |
NASA Prognostics Center of Excellence (PCoE) IMS Bearing Dataset — three test-to-failure runs, four bearings each, cycled until physical failure (inner race, outer race, and roller element defects). Dataset source