Problem
A mid-market e-commerce client had rising customer-acquisition costs but no reliable signal on which customers were about to lapse. Standard "haven't bought in 90 days" rules flagged everyone too late — by then the customer had already moved to a competitor.
Approach
Built a survival-analysis layer over transaction events combined with a gradient-boosted classifier predicting 30/60/90-day churn probability. Feature engineering across recency, frequency, basket diversity, support-ticket sentiment, browse-without-buy patterns, and seasonal anchors. Per-customer churn probability paired with per-feature attribution so the retention team could see why the model flagged each account.
Stack
Python · XGBoost · lifelines · event-stream pipeline · Postgres · scikit-learn
Outcome
Retention team shifted from broad win-back campaigns to per-segment intervention. The "why" attribution turned out to be the bigger unlock than the score itself — different segments churn for different reasons, and one-size retention emails were burning budget on customers who needed something else entirely.