RFM Segmentation: Method, Assumptions & Examples
By MCP Analytics Team | Published , updated
Executive Summary
RFM segmentation scores each customer on three behaviors taken from order history: Recency (how long since the last order), Frequency (how many orders) and Monetary value (how much spent). The scores are simple to compute and explain, and they are a practical way to decide who to contact first.
This paper is a method guide. It explains how to compute and score RFM, how to handle skewed data, and how to check on your own data whether the scores predict anything. The only numbers in it come from one simulation, whose code is shown; they describe that simulated setup and are not a claim about any company or industry.
To see which of your own customers are most valuable and which are slipping away, try the free RFM segmentation tool.
Key Points
- Scores are only useful if they predict. The method is to score on a history window and test against a later window; the example below does that and shows how.
- Which dimension predicts best depends on the business. In the simulation, where customers buy at steady individual rates, frequency separated future buyers best (64% of the top frequency group bought in the next 90 days against 19% of the lowest) and recency less so (47% against 22%).
- Combining scores sharpened the picture. Customers scoring 4 or 5 on all three dimensions bought next at 60%, against 36% overall.
- Skew needs handling. Order counts and spend are heavily skewed; rank before cutting into bins so ties do not collapse the groups.
Recommendation: compute RFM from a fixed window, score by rank, then test the scores against a later period before building campaigns on them.
1. Introduction
1.1 Why Behavior-Based Segments
Demographic attributes say little about whether a customer will buy again. Order history shows what customers actually did: how recently, how often and how much. RFM turns that history into three numbers per customer that can be ranked and combined.
1.2 What This Paper Covers
- The definitions of recency, frequency and monetary value
- Scoring approaches and how to handle skew and ties
- A reproducible holdout test of whether the scores predict later purchases
- Guidance on segments, windows and limits
2. Background
2.1 The Three Measures
- Recency (R): days since the customer's most recent order.
- Frequency (F): number of orders in the analysis window.
- Monetary value (M): total spend in the window (average order value is an alternative).
RFM comes from direct marketing practice (Hughes, 1994), and later work (Fader, Hardie and Lee, 2005) shows how recency and frequency relate to probabilistic models of customer purchasing.
2.2 Scoring Approaches
Quintile scoring splits customers into five equal groups on each dimension, scoring 1 to 5 (recency scored so that the most recent customers get 5). A customer in the top group on all three scores 555; there are 125 combinations, usually grouped into a handful of named segments. Quartile scoring uses four groups and 64 combinations. Weighted scoring combines the three scores with weights chosen on business grounds or from a predictive model. Threshold scoring uses absolute cut-offs, such as ordered in the last 30 days, five or more orders and over a spend amount, so segments do not shift as the customer base changes.
3. Approach
3.1 Window and Data
Choose an analysis window that matches the purchase cycle: long enough to see infrequent buyers, short enough that old behavior is not mixed with current. Transactions need reliable timestamps, a customer identifier that is consistent over time, and values on one currency basis. Returns, test orders and duplicates should be handled before scoring.
3.2 Skew and Ties
Order counts and spend are right-skewed, and most customers in many businesses have only one or two orders. Cutting into quintiles by value then runs into many identical values, so the cut can fail or the bins come out unequal. Ranking the customers first (breaking ties by order) makes equal-sized bins, though customers with identical behavior can then land in different bins; document the choice. For spend, a log transform or extra bins at the top separate big spenders who would otherwise share a single top bin with moderate ones.
3.3 Segments
Name segments by the behavior they describe, for example: top on all three (best customers), high on frequency and low on recency (lapsed regulars), recent with one order (new customers). Keep the names and rules written down, because they will be reused in campaigns and reports.
3.4 Validate by Holdout
Compute the scores using data up to a cut-off date, then compare the share of each score group that bought in a period after the cut-off. If the scores do not separate buyers from non-buyers on your data, they do not help for targeting, whatever the segment names suggest.
4. A Reproducible Example
The code below simulates 4,000 customers with different steady purchase rates and basket sizes, scores the 2,752 who ordered in the 540-day history window, and checks who bought in the following 90 days.
import numpy as np
import pandas as pd
rng = np.random.default_rng(8)
N, DAYS_HISTORY, DAYS_AHEAD = 4000, 540, 90
# Synthetic customers: each has a purchase rate (orders per year) and a typical basket value
rate = rng.gamma(shape=0.8, scale=2.0, size=N) # skewed: most buy rarely, a few buy often
basket = rng.lognormal(mean=3.8, sigma=0.6, size=N)
rows = []
for cust in range(N):
n_orders = rng.poisson(rate[cust] * (DAYS_HISTORY + DAYS_AHEAD) / 365)
day = rng.integers(0, DAYS_HISTORY + DAYS_AHEAD, size=n_orders)
value = basket[cust] * rng.lognormal(0, 0.3, size=n_orders)
rows += list(zip([cust] * n_orders, day, value))
orders = pd.DataFrame(rows, columns=["customer", "day", "value"])
history = orders[orders.day < DAYS_HISTORY]
future = orders[orders.day >= DAYS_HISTORY]
rfm = history.groupby("customer").agg(last=("day", "max"), frequency=("day", "size"), monetary=("value", "sum"))
rfm["recency"] = DAYS_HISTORY - rfm["last"] # days since last order
rfm["bought_next_90d"] = rfm.index.isin(future.customer.unique())
def quintile(series, ascending=True):
"""Score 1-5; rank first so tied values (many one-order customers) do not collapse the bins."""
return pd.qcut(series.rank(method="first", ascending=ascending), 5, labels=[1, 2, 3, 4, 5]).astype(int)
rfm["R"] = quintile(rfm["recency"], ascending=False) # most recent = 5
rfm["F"] = quintile(rfm["frequency"])
rfm["M"] = quintile(rfm["monetary"])
print(f"customers with at least one order in the history window: {len(rfm):,}; bought in the next 90 days: {rfm.bought_next_90d.mean():.1%}")
print("share who bought in the next 90 days, by score (1 = lowest, 5 = highest):")
print(pd.DataFrame({dim: rfm.groupby(dim).bought_next_90d.mean() for dim in "RFM"}).round(3).to_string())
champions = rfm[(rfm.R >= 4) & (rfm.F >= 4) & (rfm.M >= 4)]
at_risk = rfm[(rfm.R <= 2) & (rfm.F >= 4)]
print(f"R,F,M all >= 4: {len(champions)} customers, {champions.bought_next_90d.mean():.1%} bought next; "
f"R <= 2 with F >= 4 (lapsed frequent buyers): {len(at_risk)} customers, {at_risk.bought_next_90d.mean():.1%} bought next")
Output:
customers with at least one order in the history window: 2,752; bought in the next 90 days: 35.6%
share who bought in the next 90 days, by score (1 = lowest, 5 = highest):
R F M
1 0.218 0.194 0.214
2 0.278 0.233 0.280
3 0.325 0.296 0.284
4 0.495 0.418 0.425
5 0.466 0.641 0.579
R,F,M all >= 4: 579 customers, 60.1% bought next; R <= 2 with F >= 4 (lapsed frequent buyers): 158 customers, 41.1% bought next
In this simulation frequency separated future buyers best, spend came next and recency least, which is expected here because every simulated customer buys at a constant rate: a long gap tells you little beyond the rate. Real businesses with churn or seasonal habits often show recency mattering more. Which dimension leads is a property of the data, so the same holdout check on your own orders is worth more than any rule of thumb. The combined groups were sharper: customers scoring 4 or 5 on all three dimensions bought at 60%, and lapsed frequent buyers (recency 2 or lower, frequency 4 or higher) at 41%, against 36% overall.
5. Practical Guidance
Point 1: Test the Scores Before Using Them
Run the holdout comparison above on your own history. Use the result to decide the weights and which segments are worth separate treatment.
Point 2: Match the Treatment to the Segment
Different segments call for different actions: reward the best customers, prompt lapsed regulars with a reason to return, welcome new customers. Test the treatment with a control group, because a segment predicting purchases does not show that a campaign caused them.
Point 3: Handle Outliers and Skew Deliberately
Decide how to treat the largest spenders, wholesale buyers and returns before scoring, and document it. Check bin sizes after ranking.
Point 4: Refresh on a Schedule
Customers move between segments as time passes. Recompute with the same rules at a regular interval, and track how many customers move between segments to see whether the base is strengthening or weakening.
Point 5: Know the Limits
RFM uses only order history, so it says nothing about customers who have not ordered yet, product preferences or the reason behind behavior. It can be combined with other data or with a purchase-prediction model when more precision is needed.
6. Conclusion
RFM is a simple, explainable way to rank customers from order history. Its usefulness is empirical: in the simulation here the scores separated future buyers clearly, with frequency leading, and on a real customer base the result can differ. Score with rank-based bins, test against a later period, and build campaigns on the dimensions that predict in your own data.
Your turn
Bring your own data and the question you actually need answered.
MCP AnalyticsData science by email Send us your data and your question, and we will reply. ds@mcpanalytics.ai
Frequently Asked Questions
What is RFM segmentation?
A way to score customers on Recency (days since last order), Frequency (number of orders) and Monetary value (spend) in a time window, and to group them by the combined scores.
How do I calculate RFM scores?
Compute the three measures per customer, rank customers on each, and cut the ranks into groups, commonly five, scoring recency so that the most recent customers get the highest score. A customer in the top group on all three has a score of 555.
How do I know whether my RFM scores predict anything?
Score using data up to a cut-off date, then compare the share of each score group that ordered in a later period. If the groups do not differ, the scores are not useful for targeting.
Which matters most, recency, frequency or monetary value?
It depends on the business and the data. Test each against a later period rather than assuming an order.
How does RFM compare with clustering or predictive models?
RFM is simpler to explain and implement. Clustering and predictive models can use more variables and may predict better, at a cost in interpretability. Compare them on a holdout period.
References & Further Reading
- Hughes, A. M. (1994). Strategic Database Marketing. Probus Publishing.
- Fader, P. S., Hardie, B. G. S., & Lee, K. L. (2005). RFM and CLV: Using iso-value curves for customer base analysis. Journal of Marketing Research, 42(4), 415-430.