Project: Predictive Maintenance with IoT Sensor Data
Unplanned downtime is expensive. This project predicts whether a machine will fail within the next 24 hours from vibration, temperature and pressure readings.
Frame the problem
Predictive maintenance is usually a rare-event classification. Missing a failure costs far more than a false alarm, so recall at an acceptable precision matters more than accuracy. Never split randomly: use earlier data for training and later data for testing, or the model sees the future.
Create a sample dataset
A synthetic dataset lets you run the whole pipeline. Replace it with a public dataset such as NASA C-MAPSS when you build the portfolio version.
import numpy as np, pandas as pd
rng = np.random.default_rng(1)
n = 6000
t = pd.date_range("2026-01-01", periods=n, freq="h")
vib = rng.normal(1.0, 0.1, n); temp = rng.normal(70, 3, n); pres = rng.normal(30, 1, n)
fail_at = [1500, 3200, 5000]
for f in fail_at: # readings degrade before each failure
ramp = np.linspace(0, 1, 48)
vib[f-48:f] += ramp * 0.8; temp[f-48:f] += ramp * 9
df = pd.DataFrame({"ts": t, "vib": vib, "temp": temp, "pres": pres})
df["fail_next_24h"] = 0
for f in fail_at:
df.loc[f-24:f, "fail_next_24h"] = 1
print(df["fail_next_24h"].mean())Feature engineering
Rolling statistics expose slow degradation that a single reading hides. Use only past values.
for c in ["vib", "temp", "pres"]:
r = df[c].rolling(12)
df[f"{c}_mean12"] = r.mean()
df[f"{c}_std12"] = r.std()
df[f"{c}_delta"] = df[c] - df[c].shift(6)
df = df.dropna().reset_index(drop=True)
FEATS = [c for c in df.columns if c not in ("ts", "fail_next_24h")]Train and evaluate
Handle class imbalance with a weight and judge by the precision-recall trade-off.
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.metrics import classification_report
cut = int(len(df) * 0.7)
train, test = df.iloc[:cut], df.iloc[cut:]
w = (train.fail_next_24h == 0).sum() / max((train.fail_next_24h == 1).sum(), 1)
model = HistGradientBoostingClassifier(max_depth=4, random_state=0)
model.fit(train[FEATS], train.fail_next_24h,
sample_weight=train.fail_next_24h.map({0: 1, 1: w}))
pred = model.predict_proba(test[FEATS])[:, 1] > 0.5
print(classification_report(test.fail_next_24h, pred, zero_division=0))Real-time scoring loop
In production, readings arrive from MQTT or Kafka. The loop keeps a rolling buffer, builds the same features and raises an alert above a threshold.
from collections import deque
buf = {c: deque(maxlen=12) for c in ["vib", "temp", "pres"]}
def score(reading):
for c in buf: buf[c].append(reading[c])
if len(buf["vib"]) < 12: return None
row = {}
for c in buf:
s = pd.Series(buf[c])
row[f"{c}"] = s.iloc[-1]; row[f"{c}_mean12"] = s.mean(); row[f"{c}_std12"] = s.std()
row[f"{c}_delta"] = s.iloc[-1] - s.iloc[-6]
return float(model.predict_proba(pd.DataFrame([row])[FEATS])[0, 1])
for _, r in test.head(30).iterrows():
p = score(r)
if p and p > 0.7: print("ALERT", r.ts, round(p, 2))Hands-on practice
Run the examples in the downloadable Jupyter notebook. The extra checks below focus on mistakes that appear in real projects, not just syntax.
Create rolling sensor features
import pandas as pd
s=pd.Series([40,42,41,50,55])
print(pd.DataFrame({'temp':s,'roll3':s.rolling(3).mean()}))temp roll3 40 NaN 42 NaN 41 41.0 50 44.3 55 48.7
Rolling features capture trend but must use only past data at prediction time.
Translate probabilities into maintenance priorities
assets=[('A',.12),('B',.81),('C',.46)]
print(sorted(assets,key=lambda x:x[1],reverse=True))[('B', 0.81), ('C', 0.46), ('A', 0.12)]Ranking risk can be more useful operationally than a hard binary prediction.
Self-check
- Can you explain why the first practice result is trustworthy rather than just plausible?
- What would you monitor or test before using this Predictive Maintenance workflow in production?
- Which assumption in the example would break first on a larger or messier dataset?
Frequently asked questions
Which metric matters most in predictive maintenance?
Recall for failures at an acceptable precision, because missed failures are costly while false alarms waste inspections.
Why not split data randomly?
Random splits leak future information into training and give unrealistically good scores for time-ordered data.
Which public dataset can I use?
NASA C-MAPSS turbofan data and the AI4I 2020 predictive maintenance dataset are commonly used.
Primary references
Use these official sources when exact syntax, defaults or definitions matter beyond the examples here.




















































































































































