Sitemap
Murat Arın

Murat Arın

RFM Analysis with Python

4 min readJun 23, 2022
Press enter or click to view image in full size

In this article, we’ll take a look at the Monetary Analysis of Frequency of Innovation based on the behavior of customer groups (or segments).

What are these R, F, M value :

Typically, the Recency metric value represents the time the customer first signed up for the website or first download time app or last shopping time.

Frequency metric value shows how often shopping is done in these applications.

Monetary metric value at the end shows how much money a customer has spent on this app

Process of RFM Analysis

Press enter or click to view image in full size
RFM metrics sample chart

Segment Buckets for RFM Score

Users who are showing similar behavior on R, F, M and RFM scores are grouped into the same RFM buckets or segments. These segments are named with respect to user behavior. The list of segments and the respective description is provided below-

  • Champions — User visited most recently, visited most often and spend the highest
  • Loyal Customers — User visited recently, visited often and spent a great amount
  • Potential Loyalist — Recent user, spent a good amount
  • Recent Users — User visited most recently, but not often, has not spent much
  • Promising — Average recency, frequency, and monetary scores
  • Needs Attention — User has spent good amount but long ago (not visited recently)
  • About To Sleep — Below average recency, frequency, and monetary values
  • Can’t Lose Them — User has spent great amount and visited often but long ago (not visited recently)
  • Hibernating — User’s last visit was long back, visits are not ofter and has not spent much

Engagement Strategies for RFM Segments

The RFM segment predicts user behavior and accordingly, marketers can take actions to make the best of these user segments. Here are some basic strategies to be used for different RFM Segments -

  • Champions — Reward these users. They promote your products, they can be early adopters for your new launches.
  • Loyal Customers — These user are responsive to your promotions, suggest them higher-value products. Also, ask them for reviews.
  • Potential Loyalist — Engage them with long term offers like loyalty programs or membership rewards. Suggest other categories of products to them.
  • Recent Users — For new users, make their onboarding experience smooth, provide assistance when needed.
  • Promising — Make them loyal by creating brand awareness and giving free trials.
  • Needs Attention — Need to bring back these customers, provide limited period offers, recommend products using purchase history.
  • About To Sleep — User will be lost if not reactivated. Recommend them popular products provide discounts for memberships.
  • Can’t Lose Them — Listen to their feedback, suggest them newer products and make them stick to your platform.
  • Hibernating — Recommendations products for other categories and provide personalized offers.

Let’s try to create an RFM Score with this data set : online_retail_II.xlsx

Get Murat Arın’s stories in your inbox

Join Medium for free to get updates from this writer.

Discarding Canceled order (Cancel order started “C” In dataset):

# Data Prepairing
df.dropna(inplace=True)
df = df[(df['Quantity'] > 0)]
df = df[~df["Invoice"].astype(str).str.contains("C", na=False)]

We need to analyze times , so we’ll find a max Invoice date and add some days , in this example added 2 days :

df["InvoiceDate"].max()
#Timestamp('2010-12-09 20:01:00')
today_date = dt.datetime(2010, 12, 11)

We filtered some properties.According to this dataset ;

  • RECENCY : InvoiceDate,
  • FREQUENCY : Invoice,
  • MONETARY : Total price per Customer ID
import pandas as pd
import numpy as np
import datetime as dt
from sklearn.preprocessing import MinMaxScalery
df = pd.read_excel("/online_retail_II.xlsx", sheet_name="Year 2009-2010")
rfm = df.groupby("Customer ID").agg({"InvoiceDate": lambda last_shopping_date: (today_date - last_shopping_date.max()).days,
"Invoice": lambda invoice_num: invoice_num.nunique(),
"TotalPrice": lambda total_price: total_price.sum()})
rfm.columns = ["RECENCY", "FREQUENCY", "MONETARY"]

Checked datas and monetary min. value “0” and filtered orders greater than 0.

#              Min                                    Max
#MONETARY 0.00000 110.43650 705.55000 6235.12050 20136.78250 349164.35000
rfm = rfm[rfm["MONETARY"] > 0]
# Min Max
#MONETARY 2.95000 110.70000 706.02000 6237.60350 20137.23750 349164.35000

Calculating RFM Scores:

# The more new purchases a user has made, the better the recency value should be for us. In this regard, the user with the fewest days will have a high score.
rfm["RECENCY_SCORE"] = pd.qcut(rfm["RECENCY"], 5, labels=[5, 4, 3, 2, 1])
# The higher the number of purchases, the higher the score
rfm["FREQUENCY_SCORE"] = pd.qcut(rfm["FREQUENCY"].rank(method="first"), 5, labels=[1, 2, 3, 4, 5])
# The higher the price the user makes, the higher the rating will be.(we use RF values but just observation values)
rfm["MONETARY_SCORE"] = pd.qcut(rfm["MONETARY"], 5, labels=[1, 2, 3, 4, 5])
rfm["RFM_SCORE"] = (rfm["RECENCY_SCORE"].astype(str) +
rfm["FREQUENCY_SCORE"].astype(str))
# In Summary we 've RFM Scores :) According to 55 is champions.
Press enter or click to view image in full size

Creating And Analysing RFM Segments :

# Creating And Analysing RFM Segments
seg_map = {
r'[1-2][1-2]': 'hibernating',
r'[1-2][3-4]': 'at_risk',
r'[1-2]5': 'cant_loose',
r'3[1-2]': 'about_to_sleep',
r'33': 'need_attention',
r'[3-4][4-5]': 'loyal_customers',
r'41': 'promising',
r'51': 'new_customers',
r'[4-5][2-3]': 'potential_loyalists',
r'5[4-5]': 'champions'
}

rfm['SEGMENT'] = rfm['RFM_SCORE'].replace(seg_map, regex=True)
rfm[["RECENCY", "FREQUENCY", "MONETARY", "SEGMENT"]].groupby("SEGMENT").agg(["mean", "count"])
Press enter or click to view image in full size
rfm[‘SEGMENT’]
rfm[[“RECENCY”, “FREQUENCY”, “MONETARY”, “SEGMENT”]].groupby(“SEGMENT”).agg([“mean”, “count”])

Dataset Resource :https://www.kaggle.com/datasets/muratarin/online-retail-iixlsx

Thank you for reading…

--

--