Customer Segmentation via RFM Analysis

01 Challenge

An online retailer treats every customer the same – marketing budget goes into newsletters that loyal customers don't need and churning customers never read.

02 Approach

RFM analysis on more than 500,000 real transactions: cleaning, aggregation per customer, a 1–4 score per dimension and mapping to strategic segments.

03 Result

Clearly separated segments with concrete actions per group – from early access for Champions to a personal phone call for the lost key account.

Stack
PythonPandasSeabornRFM scoring

In e-commerce, not all customers are equal. Some buy regularly and spend a lot, others are one-time buyers or about to churn. To spend marketing budgets efficiently, it is essential to tell these groups apart.

In this project, I performed an RFM analysis (Recency, Frequency, Monetary) on a real dataset from a UK-based online retailer. The goal was to split customers into strategic segments based on their purchasing behavior.

Transactions
500k+
“Online Retail” dataset
Dimensions
3
Recency · Frequency · Monetary
Champions
38 %
largest segment
Outlier
£77k
one inactive single customer

What is RFM analysis?

The RFM method rates customers along three dimensions:

  1. Recency: How many days have passed since the last purchase?
  2. Frequency: How often has the customer ordered in total?
  3. Monetary: How much total revenue has the customer generated?

Each customer receives a score per dimension (1 to 4 in my script), which adds up to an overall score.

  1. 01Raw dataTransactions from a UK online retailerCSV
  2. 02CleaningDrop missing CustomerID, cancellations and negative valuesPandas
  3. 03AggregationRecency, Frequency, Monetary per customergroupby
  4. 04ScoringScore 1–4 per dimension, combined into an overall scoreRFM score
  5. 05ActionsSegment → channel & campaignCRM
Fig. 1 — Pipeline from the raw data table to the marketing action

Technical implementation in Python

For the analysis I used Python with Pandas for data processing and Seaborn for visualization.

1. Data cleaning

The dataset (“Online Retail”) contains more than 500,000 transactions. First, the data had to be cleaned:

  • Removing transactions without a CustomerID.
  • Filtering out cancellations (invoice numbers containing ‘C’).
  • Cleaning up faulty records (negative prices or quantities).
# Excerpt from the cleaning process
df = df.dropna(subset=['CustomerID'])
df = df[~df['InvoiceNo'].astype(str).str.contains('C')]
df['TotalPrice'] = df['Quantity'] * df['UnitPrice']

2. Calculating the metrics

Next, I aggregated the data at customer level:

latest_date = df['InvoiceDate'].max() + dt.timedelta(days=1)
rfm = df.groupby('CustomerID').agg({
    'InvoiceDate': lambda x: (latest_date - x.max()).days, # Recency
    'InvoiceNo': 'nunique',                                 # Frequency
    'TotalPrice': 'sum'                                     # Monetary
})

Results and insights

The analysis revealed clear customer segments. Here is the distribution of the identified groups:

Share of customers per segment
  • Champions38 %
  • At Risk & Hibernating22 %
  • Potential Loyalists21 %

The three strategically most important segments (81 % of the customer base)

Distribution of customer segments
Fig. 2 — Full distribution of all segments (Seaborn)

Strategic implications & recommendations

Data analysis is only the first step. The real value comes from deriving concrete actions for the marketing mix (email, SEA, social). Based on the data, I developed the following strategies:

1. Champions (38% of customers)

  • Profile: Buy often, spend a lot and purchased recently.
  • Strategy: Retention & reward. This group doesn’t need discounts to buy.
  • Concrete actions:
    • Exclusivity: Early access to new collections or “secret sales”.
    • Referral marketing: Incentives for bringing in new customers (“refer a friend”).
    • Community building: Invitations to exclusive events or VIP groups.

2. Potential Loyalists (21% of customers)

  • Profile: Good frequency, but not yet top revenue or slightly declining recency.
  • Strategy: Upselling & cross-selling. The goal is to raise basket value and frequency.
  • Concrete actions:
    • Personalized recommendations: “Customers who bought X also liked Y” (via email automation).
    • Threshold bonuses: “Spend just €20 more and get free shipping/a gift.”
    • Loyalty program: Introducing a points system to encourage the next purchase.

3. At Risk & Hibernating (22% of customers)

  • Profile: High historical value, but inactive for a long time (> 6 months). Churn is imminent.
  • Strategy: Win-back / reactivation.
  • Concrete actions:
    • Automated email flows: A sequence after 90/180 days of inactivity.
    • Incentives: Aggressive discounts (e.g. a “15% welcome-back voucher”) or time-limited offers.
    • Surveys: “Why haven’t you ordered in a while?” – use the feedback to improve processes.

Visualization: who are the most valuable customers?

A look at the average revenue (monetary value) per segment confirms the importance of the “Champions”:

Average revenue per segment
Fig. 3 — Average monetary value per segment

In addition, the scatter plot shows the correlation between recency and frequency. You can clearly see that “Champions” (top left) bought very often and very recently, while “Lost” customers (bottom right) were active rarely and long ago.

Scatter plot recency vs. frequency
Fig. 4 — Recency vs. frequency: Champions top left, lost customers bottom right

Conclusion

With this Python script I turned a raw transaction dataset into actionable marketing insights. Instead of bombarding all customers with the same newsletter, this segmentation enables personalized communication, which demonstrably increases conversion rate and customer lifetime value.

This project demonstrates my ability to apply technical data science methods directly to business questions in e-commerce.

👉 What’s next? In my project Personalization & A/B Testing I show how to use these segments technically to serve dynamic landing pages.