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.
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:
- Recency: How many days have passed since the last purchase?
- Frequency: How often has the customer ordered in total?
- 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.
- 01Raw dataTransactions from a UK online retailerCSV
- 02CleaningDrop missing CustomerID, cancellations and negative valuesPandas
- 03AggregationRecency, Frequency, Monetary per customergroupby
- 04ScoringScore 1–4 per dimension, combined into an overall scoreRFM score
- 05ActionsSegment → channel & campaignCRM
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:
The three strategically most important segments (81 % of the customer base)

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”:

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.

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.