Safiul Azam Data & Information Management
Pythonscikit-learnRFMCLTV

E-Commerce Customer Analytics — RFM Segmentation & CLTV Prediction

Half a million transactions reduced to five customer segments, then a gradient-boosted model that predicts what each customer will spend over the following three months.

RoleAnalyst & developer
OrganisationIndependent project
Year2026
ToolsPython · pandas · scikit-learn · matplotlib

This project can be shown in full. It uses a public dataset with no sensitive content, so every figure, method and result on this page is the real thing — the visuals are screenshots of the working output, not rebuilds.

Context

The Online Retail dataset holds 541,910 transaction lines from a UK e-commerce business over roughly twelve months. Two questions sit inside it: which customers matter, and what will they be worth next quarter.

The second question is the hard one, and it is easy to answer dishonestly. Split the data randomly and a model will score beautifully — because it has seen the future. The only split that means anything is a split in time.

Approach

  • Clean without inventing. 135,080 rows (~25%) had no Customer ID. RFM is a customer-level analysis, so those rows cannot be imputed — inventing identities would manufacture fake customers. They were removed, along with 5,225 duplicates, 8,872 returns and 40 zero-price lines, leaving ~392,700 genuine transactions across 4,338 customers.
  • Score by quartile, not raw value. All three RFM metrics are heavily right-skewed — one customer placed 209 orders, another spent over 280,000. Quartile scores are robust to that; raw values would let a handful of whales define the whole segmentation.
  • A time-based split. Train on December 2010 – August 2011, predict actual spend in September – December 2011. Features are computed strictly from the training window, and the RFM segments are recalculated on training data only — reusing the full-period segments would leak the answer into the inputs.
  • Two models, one test set. Random Forest and Gradient Boosting trained on identical data and judged on RMSE, MAE and R² together, because each of the three punishes a different kind of error.

Results

Built on the public Online Retail dataset. These are the actual model outputs — every figure below is a measured result.

0.503R² on held-out future spend
860MAE — typical error
4,338Customers segmented
26%Of customers drive 80% of revenue
Real output · public dataset Bar chart of customer counts per segment beside a pie chart of revenue contribution per segment
The core finding, in two charts. Goldmine is 30% of customers and 72.9% of revenue. Silent Leads is almost the same size — 29% — and contributes 4.0%. Segment size and segment value are close to unrelated.
Real output · public dataset Pareto chart showing cumulative revenue against cumulative percentage of customers, marking 26% of customers at 80% of revenue
The Pareto test. The 80/20 rule holds — and then some: 26% of customers generate 80% of revenue. More concentrated than the classic ratio predicts.
Real output · public dataset Horizontal bar chart of feature importance from the Gradient Boosting CLTV model, dominated by Monetary and average order value
Feature importance from the winning model. Monetary (59%) and average order value (29%) account for ~88% of predictive power. The segment dummies contribute almost nothing once the raw RFM values are present — expected, since the segments are derived from them.

Model comparison on the held-out test set

Lower is better for MAE; higher is better for R²

Outcome

R² 0.503 · MAE 860

Gradient Boosting won on every metric — RMSE 4,779 against 4,865, MAE 860 against 963, R² 0.503 against 0.485. An R² of ~0.50 means the model explains about half the variance in future spend.

That is an honest result rather than an impressive-sounding one, and the reason matters: 41.2% of customers spent nothing at all in the target window. The model is being asked to predict a number for people who silently disappeared. The wide gap between RMSE (4,779) and MAE (860) confirms most predictions land close, with the average dragged out by a handful of extreme customers.

The strategically useful output is not the prediction, though — it is the segmentation. Slipping Stars, 650 previously-frequent customers who have gone quiet, still hold 11.8% of revenue and are far cheaper to reactivate than new customers are to acquire.

What I’d do differently

The single-regressor design is the real weakness. Asking one model to handle both the 41% who went silent and the active spenders forces a compromise on both. A two-stage architecture — a churn classifier first, then a spend regressor on the survivors — fits the actual shape of the problem and is what I would build next.

There is also a cold-start limit worth stating plainly. The model leans on Monetary and average order value for 88% of its signal, so a brand-new customer has none of the inputs it needs. Their predictions cluster low regardless of true potential — and suppressing marketing on that basis would be reading missing data as a verdict.