DATA SCIENCE · ML ENGINEERING · 2026
Telco Churn Prediction API
The situation
A telecom company loses customers every month and wants to know which ones are likely to leave next, and why, early enough for a retention team to do something about it. This project works 7,043 customer records to answer that, and then ships the answer as a running service rather than a notebook.
The dataset is public. The question behind it is one every subscription business eventually asks, and the useful version of it is not "how accurate is the model." It is "who does the retention team call this week, and what do we already know about them when we get them on the phone."
The work
The first half of the work was finding out which signals were real. Contract type came out as the single strongest predictor by mutual information (0.098, roughly 60% higher than the next feature), and the raw group rates said the same thing without any model involved: month-to-month customers churn at 1.61x the average rate, two-year contract customers at 0.11x. Tenure was the strongest numeric predictor at -0.35 correlation. A cluster of internet and security add-ons sat in a clear second tier around 0.04 to 0.06.
Two findings were worth more than the ranking itself. First, gender and phone service carry essentially no signal at all, under 0.001 mutual information, which is a useful negative result: it tells a retention budget where not to go. Second, total charges is actively misleading read on its own. In isolation it correlates negatively with churn at -0.20, but that is mostly an artifact of its relationship with tenure, since charges accumulate as tenure grows. Once the model accounts for tenure directly, the trained coefficient on total charges flips to a small positive push toward churn. A univariate correlation and a multivariate coefficient can legitimately disagree, and reporting only the first would have pointed a retention strategy in the wrong direction.
The modelling decision that mattered was the metric, for the same reason it mattered on the Salifort project: the two mistakes have different costs. A false negative is a customer who leaves without ever being flagged, which is a silent and total loss of that customer's revenue with no chance to intervene. A false positive is a retention call placed to someone who was staying anyway, which wastes a call and possibly a discount while the customer keeps paying. Missing a churner is expensive, a false alarm is cheap, so recall on the churn class is the metric and accuracy is not.
Tuned accordingly with balanced class weights and L1 regularization, recall went from 0.60 to 0.83. Accuracy went down, from 0.82 to 0.75, and precision with it, from 0.69 to 0.52. That trade is the point rather than a regression: AUC is 0.86 for both versions, so the model's underlying ability to rank customers by risk did not change at all. What moved is where the decision threshold sits, which is a business choice about which error you would rather make. Five-fold stratified cross-validation confirmed the tuned result was not one lucky split, at mean recall 0.804.
Then came deployment, the part that separates this from a notebook. The preprocessing and the model are fit together as a single scikit-learn Pipeline, so the transformations applied at prediction time are the ones learned on the training data and nothing leaks. That pipeline is served behind a FastAPI endpoint, containerized with Docker, and running on fly.io.
How it went
The model catches 83% of the customers who go on to churn, which is the number that decides whether the thing is operationally useful: run it, get a list, work the list before the notice period starts.
It is live rather than described. POST a customer's features to the running service and it returns a prediction and a probability, and the interactive docs at churn-prediction-api.fly.dev/docs let anyone try it without writing a line of code. A month-to-month customer on fiber optic paying by electronic check, two months into their tenure, comes back at 0.85 probability of churn, which is the three strongest risk factors in the analysis stacked on one customer and the model agreeing with its own coefficients.
The five recommendations that came out of it follow the signal rather than the model: prioritise outreach to month-to-month customers, especially on fiber optic paying by electronic check; incentivise contract upgrades, since two-year customers churn at roughly a tenth of the average rate and that is the highest-leverage lever available; target the first several months of tenure, before the protective effect has had time to accumulate; bundle security and support add-ons into retention offers; and stop spending retention budget on demographic targeting, because gender carries no predictive signal worth the money.
The honest limitation is on that fourth recommendation. Security and support add-ons are associated with lower churn, but this analysis does not establish that adding them causes retention rather than reflecting a more engaged customer to begin with. That distinction matters before anyone spends money on it, so it ships with the recommendation rather than being left for someone to discover later.
83%
recall on churners, tuned model
What it proves
Finishing the job. A model that stays in a notebook is a claim; the same model behind an endpoint someone can call is a working system, and the gap between those two is where most analytics projects quietly stop. It also proves the metric argument holds up: accuracy went down here on purpose, and explaining why a lower-accuracy model is the better business decision is the part a client is actually buying.