RFM - Introduction"

Introduction

library(rfm)
library(dplyr)
library(rlang)
library(scales)
library(knitr)
library(kableExtra)
library(magrittr)
library(ggplot2)
library(DT)
library(grDevices)
library(RColorBrewer)
options(knitr.table.format = "html")

This article provides a brief introduction to RFM analysis and customer segmentation. If you are looking for a detailed guide, check out our free online course or YouTube tutorial or blog post.

RFM (recency, frequency, monetary) analysis is a behavior based technique used to segment customers by examining their transaction history such as

It is based on the marketing axiom that 80% of your business comes from 20% of your customers. RFM helps to identify customers who are more likely to respond to promotions by segmenting them into various categories.

Data

To calculate the RFM score for each customer we need data for a particular time frame and should include the following:

Data can be at customer level or transaction level i.e. each row in the data may represent a single transaction of a customer or summary of all transactions of a customer. rfm package includes two sample data sets:

head(rfm_data_orders)
head(rfm_data_customer)

You can take a look at them to understand the difference between customer and transaction level data. Remember, the data sets are different and the final results will not match.

RFM Score

So how is the RFM score computed for each customer? The below steps explain the process:

The customers with the highest RFM scores are most likely to respond to an offer. Now that we have understood how the RFM score is computed, it is time to put it into practice. Use rfm_table_order() to generate the score for each customer from the sample data set rfm_data_orders.

analysis_date <- as.Date("2006-12-31")
rfm_result <- rfm_table_order(rfm_data_orders, customer_id, order_date, revenue, analysis_date)
rfm_result
analysis_date <- as.Date("2006-12-31")
rfm_result <- rfm_table_order(rfm_data_orders, customer_id, order_date, revenue, analysis_date)
rfm_result$rfm[1:10, ] %>%
  select(customer_id, recency_days, transaction_count, amount, rfm_score, recency_score, frequency_score, monetary_score, first_name, last_name, email) %>% 
  kable() %>%
  kable_styling()

Segments

Let us segment our customers based on the individual recency, frequency and monetary scores. Keep in mind that creating segments based on RFM score is a very subjective endeavour. Having good business and domain knowledge will allow the user to generate effective segments. There is no one size fits all solution here.

segment <- c("Champions", "Potential Loyalist", "Loyal Customers", 
             "Promising", "New Customers", "Can't Lose Them", 
             "At Risk", "Need Attention", "About To Sleep", "Lost")
description <- c(
  "Bought recently, buy often and spend the most",
  "Recent customers, spent good amount, bought more than once",
  "Spend good money. Responsive to promotions",
  "Recent shoppers, but haven't spent much",
  "Bought more recently, but not often",
  "Made big purchases and often, but long time ago",
  "Spent big money, purchased often but long time ago",
  "Above average recency, frequency & monetary values",
  "Below average recency, frequency & monetary values",
  "Bought a long time ago, average amount spent"
)
recency <-   c("5", "3 - 5", "2 - 4", "3 - 4", "4 - 5", "1 - 2", "1 - 2", "1 - 3", "2 - 3", "1 - 1")
frequency <- c("5", "3 - 5", "2 - 4", "1 - 3", "1 - 3", "3 - 4", "2 - 5", "3 - 5", "1 - 3", "1 - 5")
monetary <-  c("5", "2 - 5", "2 - 4", "3 - 5", "1 - 5", "4 - 5", "4 - 5", "3 - 5", "1 - 4", "1 - 5")
segments <- data.frame(
  Segment = segment, Description = description,
  R = recency, `F` = frequency, M = monetary
)

segments %>%
  kable() %>%
  kable_styling(full_width = FALSE, font_size = 12)

Segmented Customer Data

We can use the segmented data to identify

Once we have segmented a customer, we can take appropriate action to increase his/her lifetime value.

segment_names <- c("Champions", "Potential Loyalist", "Loyal Customers", 
                   "Promising", "New Customers", "Can't Lose Them", 
                   "At Risk", "Need Attention", "About To Sleep", "Lost")

recency_lower <-   c(5, 3, 2, 3, 4, 1, 1, 1, 2, 1)
recency_upper <-   c(5, 5, 4, 4, 5, 2, 2, 3, 3, 1)
frequency_lower <- c(5, 3, 2, 1, 1, 3, 2, 3, 1, 1)
frequency_upper <- c(5, 5, 4, 3, 3, 4, 5, 5, 3, 5)
monetary_lower <-  c(5, 2, 2, 3, 1, 4, 4, 3, 1, 1)
monetary_upper <-  c(5, 5, 4, 5, 5, 5, 5, 5, 4, 5)

segments <- rfm_segment(rfm_result, segment_names, recency_lower, recency_upper,
frequency_lower, frequency_upper, monetary_lower, monetary_upper)

segments %>%
  head(10) %>%
  kable() %>%
  kable_styling()

Let us quickly summarize the segments to get an overview of the number of customers, orders and average order value in each of them.

Segment Summary

rfm_segment_summary(segments)

rfm package offers visualization tools to validate the segments generated from the RFM score. Below are a few of them:

Segmentation Plot

segments %>%
  rfm_segment_summary() %>%
  rfm_plot_segment()

Segment Summary Plot

segments %>%
  rfm_segment_summary() %>%
  rfm_plot_segment_summary()

Revenue Distribution

segments %>%
  rfm_segment_summary() %>%
  rfm_plot_revenue_dist()


Try the rfm package in your browser

Any scripts or data that you put into this service are public.

rfm documentation built on May 29, 2024, 11:50 a.m.