Most failed ML projects fail at framing, not modelling: the wrong target, a metric nobody cares about, or features that won't exist at prediction time. Turn the business goal into a precise prediction task first.
Business objective
What decision will the prediction change? “Reduce churn” → “which customers should get a retention offer this week?”
Prediction target
Define
yexactly, including time: churned = no purchase in the 30 days after the prediction date.Prediction point & features
Only use information available at the moment the prediction is made. Everything after it is leakage.
ML task
Binary classification, regression, ranking, clustering…
Metrics
An offline ML metric (PR-AUC, RMSE) that tracks an online business metric (retained revenue); set a success threshold up front.
Baseline
A trivial model or a simple rule. A model is only useful if it clearly beats it.
Constraints
Latency, cost, interpretability, fairness, privacy, how often labels arrive.
Common task types
| Task | Predicts | Example | Typical metrics |
|---|---|---|---|
| Regression | A number | Ride price from distance and time | MAE, RMSE, R² |
| Binary classification | One of two classes | Is this transaction fraud? | Precision, recall, F1, PR-AUC, ROC-AUC |
| Multi-class classification | One of k classes | Which product category? | Accuracy, macro-F1, log-loss |
| Multi-label classification | Any subset of k labels | Tags for an article | Per-label F1, Hamming loss |
| Ranking | An ordering of items | Search results for a query | NDCG@k, MRR, MAP |
| Recommendation | Items a user will like | Movies to show on the home page | Recall@k, NDCG@k, online CTR / watch time |
| Forecasting | Future values of a time series | Next week's demand per store | MAE, RMSE, sMAPE/MASE |
| Clustering | Groups of similar rows (no labels) | Customer segments | Silhouette; usefulness to the business |
| Anomaly detection | Unusual rows | Faulty sensor readings | Precision@k, recall on known incidents |
Always start with a baseline
On the breast-cancer dataset (63% benign), a “model” that always predicts the majority class already gets 63% accuracy. A real model has to beat that, not 50%.
from sklearn.datasets import load_breast_cancer
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X, y = load_breast_cancer(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.25, stratify=y, random_state=0)
baseline = DummyClassifier(strategy="most_frequent").fit(X_tr, y_tr)
model = make_pipeline(StandardScaler(), LogisticRegression()).fit(X_tr, y_tr)
print(round(baseline.score(X_te, y_te), 3)) # 0.629 ← always predicts "benign"
print(round(model.score(X_te, y_te), 3)) # 0.958Good baselines: the majority class or the mean (DummyClassifier, DummyRegressor), yesterday's value for a time series, a hand-written rule the business already uses, or a small logistic/linear regression.
Worked example: a spam filter
| Decision | Choice | Why / caveat |
|---|---|---|
| Task | Binary classification: spam vs not spam | Output a probability so the threshold can be tuned |
| Input | Subject, body text, sender history, links, sending IP reputation | All available when the email arrives |
| Labels | “Report spam” / “Not spam” clicks plus a sample reviewed by annotators | User reports are biased and noisy: most spam is never reported and people also “report” newsletters they signed up for |
| Metric | Precision at a fixed recall, or recall at ≥ 99.9% precision | A legitimate email lost in the spam folder (false positive) is far worse than one spam in the inbox |
| Baseline | Current blocklist and keyword rules | The model must beat what already exists |
| Constraints | Milliseconds per email; spammers adapt | Retrain often and monitor drift |
Framing traps
Proxy targets — optimising clicks when you care about satisfaction rewards clickbait.
Features from the future —
days_since_last_logincomputed at training time over the whole history, but at prediction time only up to today.Feedback loops — a model that decides who gets a loan only ever sees outcomes for approved applicants.
No action attached — a churn score nobody acts on has zero value, however high its AUC.
How would you frame a churn prediction problem?
Your model has 95% accuracy. Is it good?