Prediction for Data Scientists
A quick practical model.
Which customers are about to leave? That's a prediction, and models are the right tool. Our Machine Learning course goes deep. Here, you'll see how a data scientist approaches it, quickly and sensibly, with a focus on the decision.

- Who's about to leave?
- A practical approach
- Focus on the decision
A churn model
We use our cleaned data, a pipeline to prevent leakage, and two models. Average precision is the score, as we care about finding the leavers. Run it. Both models beat the base rate. And look, the simple model actually beats boosting. That's great news, as it's easy to explain to the founder. Start simple, and only add complexity if it pays.
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import average_precision_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
df = pd.read_csv("customers.csv").drop_duplicates()
df["city"] = df["city"].str.strip().str.title()
X = df[["age", "visits_per_month", "avg_spend", "loyalty", "city"]]
y = df["churned"]
X_tr, X_te, y_tr, y_te = train_test_split(X, y, stratify=y, random_state=0)
nums = ["age", "visits_per_month", "avg_spend", "loyalty"]
prep = ColumnTransformer([("n", make_pipeline(SimpleImputer(), StandardScaler()), nums),
("c", OneHotEncoder(handle_unknown="ignore"), ["city"])])
for name, m in [("Logistic", LogisticRegression(max_iter=1000)),
("Boosting", HistGradientBoostingClassifier(max_iter=120, random_state=0))]:
p = make_pipeline(prep, m).fit(X_tr, y_tr).predict_proba(X_te)[:, 1]
print(f"{name:<9} PR AUC {average_precision_score(y_te, p):.3f}")
print("Base rate:", round(y_te.mean(), 3))Logistic PR AUC 0.405 Boosting PR AUC 0.355 Base rate: 0.271
Customer segments
Clustering finds natural groups, with no labels. We use just visits and spend. Then we describe each segment. Run it. Now you've got clear groups, such as regulars who hardly ever leave, and occasional big spenders. Each group can get different treatment. A segment is only useful if the business would act on it differently.
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
df = pd.read_csv("customers.csv").drop_duplicates()
X = df[["visits_per_month", "avg_spend"]].clip(upper=df[["visits_per_month", "avg_spend"]].quantile(.99), axis=1)
df["segment"] = make_pipeline(StandardScaler(), KMeans(4, n_init=10, random_state=0)).fit_predict(X)
print(df.groupby("segment").agg(customers=("churned", "size"),
visits=("visits_per_month", "mean"),
spend=("avg_spend", "mean"),
churn=("churned", "mean")).round(2).to_string())customers visits spend churn segment 0 648 10.33 13.17 0.08 1 2513 2.28 8.89 0.36 2 1141 3.53 16.19 0.28 3 1698 5.73 9.93 0.21
Summary
A simple model, a clear metric, and segments that lead to action. You've got the core tools now. Next, we go further. First, some advanced data skills.
Key takeaways- Start simple
- Beat the base rate
- Segments must drive action