In this article
Before you start
Churn prediction is a classical table-of-features problem, so no language-model knowledge is needed. The habit it shares with large language model (LLM) evaluation is deciding how to judge a model before building it.
Why interviewers ask this
A churn model that scores well in a notebook and fails in production costs a team months, so interviewers use this question to see whether you think about the whole system and not only the algorithm. The question has no single right model, which makes it a clean test of judgement.
A weak answer names an algorithm: "I would train gradient boosting on the customer table and report accuracy." A strong answer defines churn and the prediction window, protects against leakage, splits by time and picks a metric that suits rare events. A Staff-level answer goes one step further and ties the threshold to the cost of the retention offer, then asks how the team will test whether the offer changes behaviour. A strong answer shows this order of thinking; the model choice comes last and matters least.
Churn prediction from first principles
- Churn prediction model
- A churn prediction model is a classifier that takes what is known about a customer at a prediction date and outputs the probability that the customer leaves within a fixed window afterwards, so a team can decide whom to contact.
- Right-censoring
- Right-censoring is the situation where a customer has not yet left when the data ends, so you know they stayed at least this long but not when, or whether, they will leave.
In plain words
Think of a doctor's check-up. You record a patient's measurements today and ask who will be ill within a year. The analogy breaks in one place. Your business action changes the outcome you are predicting: a customer who gets an offer may stay. So the useful output is not only "who leaves" but "who is worth contacting".
In precise terms, you freeze each customer's history at a prediction date. In a monthly snapshot, that is the day you freeze the table, such as the first of the month, and everything after it counts as the future. You attach a label saying whether they left in the following window. Then you learn the mapping from history to label.
Step 1: Define churn and its prediction window
Churn must be defined before any code, and the definition is a design choice you agree with the business. For a subscription it can be "no renewal within a set grace period"; for a shop with no contract it can be "no purchase in a chosen number of days". Then fix three windows: the history used for features, the prediction date, and the window in which leaving counts, such as the next three months (illustrative).
You also choose the framing. A binary classifier answers whether a customer churns in a given window, at one point in time (University of British Columbia applied machine learning course, 2023). Survival analysis models time until leaving and handles customers who have not left yet. Dropping them biases the answer: in an illustrative cohort of eight customers where four are still active, the average tenure of those who left is 5.25 months, against 8.625 months observed across all eight.1 The lifelines survival analysis introduction, 2026 says that leaving right-censored people out severely underestimates the true average lifespan.
Step 2: Build features only from data known at the prediction date
Every feature must be computable on the prediction date, using nothing from after it. That includes usage counts, plan type, support tickets and billing events, each cut off at the date. A feature such as "cancellation reason", or "days since last login" measured after the prediction date, is leakage: imbalanced-learn common pitfalls, 2026 defines leakage as using information that would not be available at prediction time.
Leakage gives over-optimistic estimates and poorer production performance (scikit-learn common pitfalls, 2026). Suspiciously near-perfect scores are a warning sign, not a success. Two habits prevent it. First, fit scalers, encoders and imputers on the training data only, inside a pipeline, and never call fit on test data. Second, resample inside the training fold only; oversampling the whole dataset before splitting also leaks (imbalanced-learn common pitfalls, 2026). Validation has the same trap: the label window of every training snapshot must end before the test period's prediction date, which the gap in the next step handles. The features are now safe, so the split can be honest.
Step 3: Split by time and choose a metric for rare events
Churn data is ordered in time, so train on earlier snapshots and validate on a later period. Random folds can train on the future, which TimeSeriesSplit avoids by making each training set earlier than its test fold, and its gap parameter can model the lag before a label is known (scikit-learn TimeSeriesSplit documentation, 2026). It splits by row, so with many customers per date, split on snapshot dates instead; gap counts rows, not days.
Accuracy misleads when few customers leave. In an illustrative base with a 5% churn rate, a model that always predicts "stays" scores 0.95 accuracy and catches no churner.1 Precision-recall analysis is the useful lens for imbalanced classes (scikit-learn precision-recall example, 2026). Precision is the share of flagged customers who truly leave; recall is the share of all leavers that get flagged. Precision also depends on the base rate (Williams, 2021): at an illustrative true positive rate of 0.6 and false positive rate of 0.1, precision is 0.6 when 20% churn but 0.24 when 5% churn.1 Report the base rate beside precision.
Step 4: Set the threshold from the cost of the offer
The threshold decides whom you contact, and it comes from money, not from 0.5. Take illustrative values: an offer costs 20 currency units, a customer is worth 400 units and an offer saves 30% of those who would have left.1 Contacting a customer then pays only if precision exceeds 20 / (0.3 × 400) = 0.1667, the break-even precision. Lift is the ratio of the contacted group's churn rate to the overall rate.
| Contact the top | Customers | Churners caught | Precision | Lift | Net value per contact (units) |
|---|---|---|---|---|---|
| 10% | 10,000 | 2,000 | 0.20 | 4.0 | 4.00 |
| 20% | 20,000 | 3,000 | 0.15 | 3.0 | -2.00 |
| 30% | 30,000 | 3,600 | 0.12 | 2.4 | -5.60 |
All figures in the table are illustrative.1 Illustrative precision falls to 0.12 at the top 30%, below break-even, while illustrative precision at the top 10% is 0.2, above the break-even of 0.1667.
Marginal precision and calibration
The table shows cumulative group precision, but the decision to make one more contact depends on marginal precision. In this illustrative base, the second decile adds 1,000 churners in 10,000 contacts, so marginal precision is 0.10 in the second decile and 0.06 in the third, already below 0.1667 even though group precision at the top 20% is still 0.15.1 The per-customer rule is to contact when calibrated churn probability × save rate × customer value exceeds the offer cost, which here is a score threshold of 0.1667. Calibrated means a score of 0.2 matches roughly one leaver in five such customers; check this with a reliability curve and recalibrate if it does not hold.
A model that predicts who leaves does not show who responds to an offer, so a controlled test of the campaign is the final check. After launch, monitor the score distribution and the churn rate for drift and retrain on a schedule, because precision moves with the base rate.
Step-by-step description
- Fix the label and the window.
- Use only data known at the date.
- Train on the past, test on later.
- Choose the cutoff from cost.
- Define churn and its prediction window first.
- Features use only data known at the prediction date.
- Split train and test by time.
- Set the contact threshold from the offer cost.
Text description of the diagram
- Illustrative precision at the top 10% of customers is 0.2, above the break-even of 0.1667.
- Illustrative precision falls to 0.12 at the top 30%, below break-even.
- Marginal precision is 0.10 in the second decile and 0.06 in the third.
Knowing it is half the job. Saying it is the other half.
Interview Clozo is an AI interview copilot for real interview rounds: it hears the question and puts a strong answer on your screen, and you say it in your own words. See the features or how it works.
Start Free Trial →The Staff-level answer
How would you approach building a churn prediction model from scratch?
I start by agreeing what churn means, for example no renewal within a grace period, and I predict it over a fixed window such as the next three months. I build features only from data known at the prediction date, fit all preprocessing on training data only, and split by time. Because leavers are rare, I report precision and recall with the base rate, not accuracy. Then I set the contact threshold on calibrated probabilities from the offer cost and the value of a saved customer, and I check with a controlled test that the offer changes behaviour.
What makes it Staff-level: it ends with the decision and the experiment, not with the model's score.
The rubric
| Dimension | Weak answer | Strong answer | Staff answer |
|---|---|---|---|
| Problem definition | Trains on a customer table with no stated label | Defines churn and the prediction window | Also chooses classifier or survival framing and handles customers still active |
| Leakage | Not mentioned | Features cut off at the prediction date | Also fits preprocessing in a pipeline and resamples only inside training folds |
| Validation | Random split | Split by time | Uses a gap for label lag and checks a later cohort |
| Metric | Accuracy | Precision and recall | Adds the base rate and a cost-based break-even |
| Decision | Stops at the score | Picks a threshold | Plans a controlled test of the campaign |
Three variants of this question
How would you predict churn for a product with no subscription?
Start by defining churn from inactivity, such as no purchase in a chosen number of days, and justify the number with the business. The rest of the approach is unchanged, but the label is a modelling choice and you should say so.
How would you build a first version quickly?
Build a simple baseline on a feature table with logistic regression, plus the time split and the metric. Typical features are recency of last activity, frequency of use, tenure, the trend in engagement, support contacts and billing failures. Gradient-boosted trees are the usual stronger model on tabular features like these; try them after the baseline, on the same time split, and keep them only if the cost-based value improves over the "always stays" baseline.
Would you use survival analysis instead of a classifier?
Use survival analysis when timing matters or many customers are still active, since it handles right-censoring. Kaplan-Meier (a curve of the share still subscribed over time) uses no features, while Cox proportional hazards does (University of British Columbia applied machine learning course, 2023); a classifier is simpler when one window decision is enough.
Common mistakes
- "I will split randomly and cross-validate." (wrong) Random folds can train on the future. (right) "I split by time so training always precedes testing."
- "I will scale and oversample first, then split." (wrong) That leaks test information and inflates scores. (right) "I fit preprocessing and resampling inside the training fold only."
- "The model has 95% accuracy." (wrong) With rare churn, a model that never flags anyone matches that. (right) "I report precision and recall alongside the churn base rate."
- "I will drop customers who have not churned yet." (wrong) That biases tenure and risk downwards. (right) "I keep them as censored, or I fix the window so every label is known."
- "I will contact everyone above 0.5." (wrong) The cutoff ignores cost. (right) "I choose the threshold from the offer cost and the value of a saved customer."
Follow-up questions
Why is accuracy a poor metric for a churn model?
When few customers leave, predicting "stays" for everyone gives high accuracy and zero recall. Precision-recall analysis shows how well the rare class is found (scikit-learn precision-recall example, 2026).
How do you split data for a churn model?
Split by time: earlier snapshots train, a later period tests, with a gap that matches how long labels take to be known. Random folds can train on the future and test on the past.
How do you know the retention campaign works?
A churn score ranks risk, not response, so run a controlled test: contact a random half of the high-risk group and compare leaving rates. The next-level step is uplift modelling, which estimates the change in a customer's chance of staying that the offer causes, so it targets who responds, not who leaves.
Could a language model or transformer help predict churn?
Yes, as a feature builder, for example turning support tickets into topics, but a table of simple features is the usual starting point. Check the labels such a model produces against a hand-labelled sample, as in LLM-as-a-judge.
Who should receive the offers, and what data can you use?
Check whether the offers reach some groups far more often than others, because choosing who gets a retention offer is a fairness question; see bias and fairness in machine learning. The model also uses customer behavioural data, so limit it to what the task needs; see privacy in machine learning (ML) systems.
What changes if an AI agent sends the retention offers?
The model now drives an action, so the agent needs guardrails, including defences against injected instructions in customer messages; see AI agent security. Keep the cost-based threshold and the controlled test unchanged.
- Define churn and the prediction window before any modelling.
- Use only data known at the prediction date, and fit preprocessing on training data only.
- Split by time, and report precision and recall with the base rate, not accuracy.
- Set the threshold from the offer cost and the value of a saved customer.
- Finish with a controlled test that the campaign changes behaviour.
Sources
- Common pitfalls and recommended practices (scikit-learn 1.9.1) — scikit-learn documentation, 26 Oct 2026
- Common pitfalls (imbalanced-learn 0.14.2) — imbalanced-learn documentation, 26 Oct 2026
- Precision-Recall example (scikit-learn 1.9.1) — scikit-learn documentation, 26 Oct 2026
- The Effect of Class Imbalance on Precision-Recall Curves (arXiv 2007.01905) — arXiv (Williams), 28 Apr 2021
- TimeSeriesSplit (scikit-learn 1.9.1) — scikit-learn documentation, 26 Oct 2026
- Introduction to survival analysis (lifelines 0.30.3) — lifelines documentation, 26 Oct 2026
- Lecture 20: Survival analysis, CPSC 330 Applied Machine Learning — University of British Columbia, 1 Sep 2023