Where this session sits
The cohort triangle from a2 describes what happened. Starting today, we model it. Survival analysis is the bridge: it keeps a2's honest, forward-looking spirit but adds two things the triangle cannot give you - correct handling of still-active customers, and covariate effects ("does contract type change churn risk?"). The RFM personas you built in a4 become the segments we compare here, and the P(alive) models in a6 pick up where censoring math leaves off. Work along in the companion notebook notebooks/a5_survival.ipynb.
The censoring problem 15 min live
A customer who is still active when your data ends has not churned - their lifetime is at least what you observed, and that is all you know. They are right-censored. The naive "average customer lifetime" - mean tenure of the customers who churned - silently throws these people away, so it only counts the quitters and comes out biased low. Kaplan-Meier counts everyone: S(t) is the probability of surviving past t, drawn as a step curve that steps down only at observed churn events. Censored customers simply exit the risk set when their data runs out - they thin the denominator of later steps without stepping the curve themselves.
Live★ Build-along: the six-customer worked example8 min▶
Six customers, observed for up to ten months. A churned at month 2, C at month 4, E at month 7. B, D and F were still active when the data ended, at months 3, 5 and 9 - censored. Walk the estimator by hand once, then let lifelines do it forever:
- Month 2: 6 customers at risk, 1 churns. S(2) = 5/6 = 0.83. B is censored at month 3 - the curve does not move, but B leaves the risk set.
- Month 4: 4 at risk (C, D, E, F), 1 churns. S(4) = 0.83 x 3/4 = 0.63. D exits censored at month 5.
- Month 7: 2 at risk (E, F), 1 churns. S(7) = 0.63 x 1/2 = 0.31. F exits censored at month 9. Median survival - where S(t) crosses 0.5 - is 7 months.
- The naive number: mean tenure of the churned three is (2 + 4 + 7) / 3 = 4.3 months. The honest median is 7. Same data, and the naive figure understated lifetime by counting only quitters.
Here is that churn-definition choice applied to the repo's own orders: call 90 days of silence churn, then plot how long each churned customer lasted from first order to last. The shape explains why this session exists.
Comparing segments honestly 8 min live
One KM curve per segment - contract type, acquisition channel, or the RFM personas from a4 - and the gaps become visible. But visible is not the same as real: two curves from the same population will drift apart by luck. The log-rank test compares whole curves, not one cherry-picked time point, and answers "how surprising is a gap this size if the segments actually churn identically?" This is the censoring-correct cousin of reading a2's triangle rows: same question, but every still-active customer is counted instead of dropped.
Live★ Build-along: two KM fits overlaid + log-rank6 min▶
Split the frame by segment, fit one KaplanMeierFitter per side, plot on a shared axis, then let the test speak. Swap in any a4 persona pair - Champions vs Hibernating is a favorite.
Two reading rules. First, a tiny p-value on a tiny gap can still be commercially boring - report the gap size and the p-value together. Second, if the curves cross, the log-rank test loses power and "which segment is better" depends on the horizon; say so instead of averaging it away.
Cox proportional hazards 14 min live
KM compares one segmentation at a time. Cox proportional hazards handles many covariates at once, and it is semi-parametric: it estimates each covariate's effect as a hazard ratio without ever specifying the baseline churn curve. The canonical Telco read: a month-to-month contract carries roughly 3x the churn hazard of a two-year contract, other covariates held fixed. Read exp(coef) as multiplicative risk, verify the proportional-hazards assumption with check_assumptions(), and judge ranking quality with the C-index.
Live★ Build-along: CoxPHFitter on a Telco-shaped frame8 min▶
One row per customer: tenure in months, a churn flag, and covariates. Fit, print the summary, and read the exp(coef) column out loud before anything else.
- exp(coef) = 3.0 reads: "at any moment, a month-to-month customer who is still with us has three times the instantaneous churn risk of an otherwise-identical two-year customer."
- Proportional hazards means that ratio is assumed constant over time.
check_assumptions()flags covariates that violate it - stratify or add time-varying terms rather than shipping a broken ratio. - C-index is the probability the model correctly orders a random pair by churn time - a ranking score, not a calibration score.
Self-studyHazard vs probability, and why models get versions4 min read▶
Hazard is not probability. The hazard at t is the instantaneous churn risk among customers who survived to t - risk per unit time, conditional on still being here. S(t) is the cumulative result of running that gauntlet. A segment can have high early hazard and still contain the most durable survivors, which is exactly the a5 lesson a6 leans on: churn falls with tenure because the fragile leave first.
The frozen-history tie-in. a2's completed triangle cells are facts: frozen, immutable, never restated. Survival estimates are not facts - they are models, and they legitimately update as more customers age and censored lifetimes resolve. So version them: stamp every KM median and hazard ratio with a fit date and a data cutoff, and never splice a re-fit estimate into a frozen reported table as if it were the same kind of number.
When NOT to reach for survival: descriptive reporting where the cohort table already answers the question. Reach for it when censoring is material (many still-active customers), when you need covariate effects, or when you want individual lifetime estimates. A tool upgrade you do not need is just a slower way to say the same thing.
Subscription and non-subscription businesses are playing different games. A contract business observes churn: the cancellation is an event with a timestamp, so KM and Cox apply directly - which is why Telco churn is the canonical teaching dataset. A shop or a game only ever infers churn from silence, through the inactivity-window definitions from Part 1. That inference gap is precisely why the buy-till-you-die models in a6 exist: they replace "define a window and hope" with a per-customer P(alive).
Try it yourself - this week ◐ 30 min total
- Fit KM on the synthetic ecommerce orders using a 90-day inactivity churn definition: a customer's duration ends at their last purchase + 90 days if no further order lands in that window; otherwise they are censored at the data cutoff.
- Re-run with 60-day and 120-day windows and watch
median_survival_time_move. Write one sentence on what that means: the churn definition IS a modeling choice, and it belongs printed on the chart. - Overlay KM for two a4 personas and run the log-rank test. Report gap size and p-value together, in one stakeholder-ready sentence.
- Both plots go into your running retention report - a8 assembles it, and a6 will want your churn-window choice as its baseline.
What this session draws on
Survival analysis is a mature statistical field; this session teaches the working retention-analyst core of:
Three questions before you go 🎯 ◐ 90 seconds
1 · Mean tenure of your churned customers is 4.3 months. Why is "average customer lifetime is 4.3 months" wrong?
Still-active customers are right-censored: their lifetimes are at least what you observed, and they are disproportionately your durable customers. Averaging only observed churns systematically understates lifetime. KM keeps them in the risk set and gets the honest answer.
2 · Your Cox summary shows exp(coef) = 3.0 for month-to-month contracts. What does that mean?
A hazard ratio is multiplicative instantaneous risk among survivors, assumed constant over time (that is the proportional-hazards assumption - check it). It is not a difference in months and not a percentage-point gap.
3 · When is the plain a2 cohort table enough, with no survival model at all?
The cohort table is the right tool for describing what happened. Survival earns its complexity when censoring is material, when you need covariate effects (Cox), or when you want per-customer lifetime estimates. Matching tool to question is the skill.