AI Hints
Home›Data Science Tutorial›Storytelling and Tools
Data Science · Lesson 29 of 101

Prediction for Data Scientists

A quick practical model.

⏱ 2 min read▶ Video at 49:52🎓 Free
Watch this lesson in the Data Science courseWatch on YouTube ↗Full Data Science course

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.

Prediction for Data Scientists
From the video: Prediction for Data Scientists
  • 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.

churn.pypython
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))
Output
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.

segments.pypython
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())
Output
         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
Next up: Reshaping Tables — long, wide, and why it matters