Marketing Thực Chiến - Phân Loại Khách Hàng Sử Dụng RFM Analysis

1. Giới thiệu RFM

  • RFM là 3 ký tự đầu tiên của Recency, frequency, monetary. Nó là công cụ phân tích được marketing sử dụng để định danh khách hàng của công ty dựa trên thói quen mua sắm tự nhiên của họ.

  • RFM phân tích và đánh giá khách hàng bằng cách tính điểm hành vi mua sắm của họ dựa trên ba tiêu chí:

    • Recency: Khoảng thời gian mua hàng gần nhất là bao lâu. Nếu họ đã mua hàng gần đây, xác suất họ sẽ mua thêm một lần nữa rất cao. Tuy nhiên, nếu khách hàng không thực hiện bất kỳ một giao dịch nào trong một khoảng thời gian dài, chúng ta có thể lôi kéo họ bằng một offer đặc biệt, hoặc giới thiệu lại thương hiệu của mình cho họ.

    • Frequency: Tần suất mua hàng của khách hàng. Nếu khách hàng có tầng suất mua dày đặc, chúng ta sẽ biết thói quen và sở thích của họ. Nếu họ chỉ mua một lần và chưa bao giờ trở lại, họ có thể là một ứng viên tốt để thực hiện bài khảo sát sự hài lòng của khách hàng.

    • Monetary: Số tiền trung bình khách hàng sử dụng trên mỗi giao dịch. Tuy nhiên, đừng quá chú trọng vào con số này. Tất cả các giao dịch mua hàng đều có giá trị. Monetary tác động trực tiếp đến doanh thu của công ty, tác động gián tiếp với 2 chỉ số ở trên kia. Nếu chúng ta gặp một khách hàng thực hiện nhiều lần mua hàng gần đây với mức giá cao, những người đó có thể là khách hàng trung thành của chúng ta.

  • RMF có thang điểm từ 1-5 ( 1 là tệ, 5 là tốt) của mỗi khách hàng cho mỗi tiêu chí.

  • RFM giúp công ty có khả năng dự đoán những khách hàng nào có khả năng cao sẽ mua lại sản phẩm của họ, doanh thu đến từ khách hàng mới là bao nhiêu, cách biến cơ hội mua hàng thành thói quen.

2. Giới thiệu data và tìm hiểu data

2.1 Giới thiệu data

Dữ liệu ở bài viết này, chúng ta sẽ sử dụng từ nguồn https://www.kaggle.com/datasets/lissetteg/ecommerce-dataset.

Code load các thư viện cần thiết

 1
 2# This Python 3 environment comes with many helpful analytics libraries installed
 3# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
 4# For example, here's several helpful packages to load in
 5
 6import numpy as np # linear algebra
 7import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
 8
 9# Input data files are available in the "../input/" directory.
10
11import time, warnings
12import datetime as dt
13
14#visualizations
15import matplotlib.pyplot as plt
16from pandas.plotting import scatter_matrix
17%matplotlib inline
18import seaborn as sns
19
20warnings.filterwarnings("ignore")

Code load data và in ra 20 dòng đầu tiên

1
2#load the dataset
3retail_df = pd.read_csv('../input/data.csv',encoding="ISO-8859-1",dtype={'CustomerID': str,'InvoiceID': str})
4retail_df.head(20)

Hình 1: Tổng quan về dữ liệu Hình 1: Tổng quan về dữ liệu

2.2 Thực hiện một số phép thống kê trên dữ liệu

Sau khi nhận dữ liệu, chúng ta cần xem xét sơ lược tổng quan về dữ liệu bằng một số hàm thống kê cơ bản

1
2print(retail_df.describe())
3print(retail_df.info())

Hình 2 Hình 2: Phân tích xác suất về dữ liệu

Dựa vào kết quả hình 2, chúng ta thấy rằng data có tổng cộng 541909 dòng, 8 cột, trong đó có một số chỗ có giá trị null. Cột CustomerID có giá trị null nhiều nhất.

2.3 Phân tích dữ liệu

2.3.1 Tính doanh thu theo tháng

Doanh thu của một đơn hàng bằng số lượng nhân đơn giá.

Công việc cần làm:

  • Tạo một key chung đại diện cho biến tháng trong năm ( ở đây mình đặt tên là MonthKey)
  • Tính doanh thu
  • Group doanh thu theo tháng
  • In ra màn hình doanh thu theo tháng
  • Vẽ chart doanh thu theo tháng

Đoạn code mẫu mô tả các bước cần làm ở trên

 1
 2#converting the type of Invoice Date Field from string to datetime.
 3retail_df['InvoiceDate'] = pd.to_datetime(retail_df['InvoiceDate'])
 4
 5#creating MonthKey field for reporting and visualization
 6retail_df['MonthKey'] = retail_df['InvoiceDate'].map(lambda date: 100*date.year + date.month)
 7
 8#calculate Revenue for each row and create a new dataframe with MonthKey - Revenue columns
 9retail_df['Revenue'] = retail_df['UnitPrice'] * retail_df['Quantity']
10revenue_by_month = retail_df.groupby(['MonthKey'])['Revenue'].sum().reset_index()
11print(revenue_by_month)
12
13# plot data
14revenue_by_month['MonthKey'] = revenue_by_month['MonthKey'].apply(str)
15%matplotlib inline
16plt.rcParams["figure.figsize"] = [20, 10]
17plt.plot('MonthKey', 'Revenue', data=revenue_by_month, linestyle='-', marker='o')
18plt.title("Revenue by Month")
19plt.show()

Kết quả chúng mình nhận được

 1
 2
 3	MonthKey	Revenue
 40	201012	748957.020
 51	201101	560000.260
 62	201102	498062.650
 73	201103	683267.080
 84	201104	493207.121
 95	201105	723333.510
106	201106	691123.120
117	201107	681300.111
128	201108	682680.510
139	201109	1019687.622
1410	201110	1070704.670
1511	201111	1461756.250
1612	201112	433668.010

Hình 3 Hình 3: Doanh thu theo tháng

Nhìn vào hình 3 ở trên, chúng ta thấy rằng, doanh thu bắt đầu tăng từ tháng 8, đạt đỉnh điểm ở tháng 11, tháng 12 doanh thu siêu thấp, ngó qua tháng 12 năm ngoái thì doanh thu khá ổn, nên có thể tạm kết luận là data tháng 12 năm hiện tại có thể chưa đủ tháng. Chúng ta có thể bỏ data tháng 12 ra khỏi dataset để tránh bị nhiễu.

2.3.2 Thống kê tăng trưởng của doanh thu

Để tính tăng trưởng doanh thu, ta lấy doanh thu tháng hiện tại chia cho doanh thu tháng trước -1

Trong pandas, chúng ta sử dụng hàm pct_change

 1
 2revenue_by_month['MonthlyGrowth'] = revenue_by_month['Revenue'].pct_change()
 3
 4
 5# Plot data
 6
 7plt.rcParams["figure.figsize"] = [20, 10]
 8plt.plot('MonthKey', 'MonthlyGrowth', data=revenue_by_month, linestyle='-', marker='o')
 9plt.plot(range(1,len(revenue_by_month.index)+1),[0 for i in range(len(revenue_by_month.index))], color="k", lw=2.5)
10plt.title("Monthly Revenue Growth Rate")
11plt.show()

Hình 4 Hình 4: Biến động doanh thu theo tháng

Qua sơ đồ hình 4, chúng ta thấy rằng ở tháng 4 có sự sụt giảm mạnh về doanh thu, nhóm kinh doanh cần phải phân tích kỹ hơn các yếu tố ảnh hưởng đến sự sụt giảm nghiêm trọng về mặt doanh thu trong tháng này.

2.3.3 Phân tích số lượng khách hàng tháng

Để tính lượt khách mua hàng hằng tháng, chúng ta đếm không trùng mã khách hàng trong tháng

 1
 2customer_by_month = retail_df.groupby(['MonthKey'])['CustomerID'].nunique().reset_index()
 3customer_by_month
 4
 5
 6customer_by_month['MonthKey'] = customer_by_month['MonthKey'].apply(str)
 7%matplotlib inline
 8plt.rcParams["figure.figsize"] = [20, 10]
 9plt.plot('MonthKey', 'CustomerID', data=customer_by_month, linestyle='-', marker='o')
10plt.title("Customer by Month")
11plt.show()
 1
 2
 3	MonthKey	CustomerID
 40	201012	948
 51	201101	783
 62	201102	798
 73	201103	1020
 84	201104	899
 95	201105	1079
106	201106	1051
117	201107	993
128	201108	980
139	201109	1302
1410	201110	1425
1511	201111	1711
1612	201112	686

Hình 5 Hình 5: Lượt khách theo tháng

Nhận xét rằng, lượt khách tăng từ tháng 8 trở về sau, từ tháng 5 đến tháng 8 thì lượt khách giảm nhẹ, đều. Tháng 1 và 2 lượt khách rất thấp.

2.3.4 Số đơn đặt hàng trong tháng

Cũng giống như lượt khách, chúng ta sẽ đếm số lượng InvoiceNo trong từng tháng

1
2order_by_month = retail_df.groupby(['MonthKey'])['InvoiceNo'].count().reset_index()
3order_by_month
4order_by_month['MonthKey'] = order_by_month['MonthKey'].apply(str)
5%matplotlib inline
6plt.rcParams["figure.figsize"] = [20, 10]
7plt.plot('MonthKey', 'InvoiceNo', data=order_by_month, linestyle='-', marker='o')
8plt.title("Count total order in Month")
9plt.show()

Hình 6 Hình 6: Số lượng đơn đặt hàng trong tháng

Từ tháng 5 đến tháng 7, số lượng đơn đặt hàng tăng nhẹ, tỷ lệ nghịch với lượt khách

Từ tháng 8 trở đi, số đơn đặt hàng tăng cao, tỷ lệ thuận với lượt khách

2.3.5 Doanh thu trung bình mỗi đơn hàng

Trong pandas, chúng ta chỉ cần gọi hàm mean để tính trung bình

 1
 2avg_order_revenue = retail_df.groupby(['MonthKey'])['Revenue'].mean().reset_index()
 3
 4avg_order_revenue['MonthKey'] = avg_order_revenue['MonthKey'].apply(str)
 5
 6# Plot regression line
 7
 8plt.rcParams["figure.figsize"] = [20, 10]
 9plt.plot('MonthKey', 'Revenue', data=avg_order_revenue, linestyle='-', marker='o')
10plt.title("Average Revenue per Order")
11plt.show()

Hình 7 Hình 7: Doanh thu trung bình mỗi đơn hàng

Nhận xét rằng, tháng 10, 11, lượt khách tăng, số lượng đơn hàng tăng, nhưng trung bình mỗi đơn hàng lại thấp.

2.3.6 Số lượng khách hàng mới/ cũ theo từng tháng

Khách hàng mới và khách hàng cũ đều đóng vai trò rất quan trọng trong chiến lược marketing. Việc giữ chân khách hàng cũ giúp chúng ta hiểu hơn về họ và phục vụ họ tốt hơn. Việc phát triển khách hàng mới giúp chúng ta phát triển lớn lên.

Trong ngữ cảnh bài này, chúng ta sẽ xét yếu tốt khách hàng mới/cũ như sau

  • Khách hàng mới là khách hàng trước đó chưa từng mua hàng. Không quan tâm tháng hiện tại khách đã mua bao nhiêu đơn.

  • Khách hàng cũ là khách hàng đã mua ít nhất 1 đơn hàng ở tháng trước đó.

  • Do đơn vị chúng ta thống kê tính bằng tháng, cho nên nếu 1 khách hàng có mua 2 hoặc nhiều hơn đơn hàng ở tháng hiện tại, chưa từng mua đơn hàng nào ở các tháng trước đó, khách hàng đó được coi là khách hàng mới.

Kỹ thuật lập trình ở đây như sau:

  • Lấy ra danh sách khách hàng và ngày mua hàng đầu tiên của họ

  • Quy đổi ngày mua hàng đầu tiên thành tháng mua hàng đầu tiên

  • Tạo thêm cột loại khách hàng cho từng đơn hàng (UserType). Gán mặc định UserType = New. Nếu tháng lên đơn lớn hơn tháng mua đầu tiên -> đơn hàng của khách cũ (UserType=Existing).

 1
 2create a dataframe contaning CustomerID and first purchase date
 3df_min_date_purchase =retail_df.groupby('CustomerID').InvoiceDate.min().reset_index()
 4df_min_date_purchase.columns = ['CustomerID','MinPurchaseDate']
 5df_min_date_purchase['MinMonthKey'] = df_min_date_purchase['MinPurchaseDate'].map(lambda date: 100*date.year + date.month)
 6
 7#merge first purchase date column to our main dataframe (tx_uk)
 8retail_new_df = pd.merge(retail_df, df_min_date_purchase, on='CustomerID')
 9
10retail_new_df.head()
11
12#create a column called User Type and assign Existing
13#if User's First Purchase Year Month before the selected Invoice Year Month
14retail_new_df['UserType'] = 'New'
15retail_new_df.loc[retail_new_df['MonthKey']>retail_new_df['MinMonthKey'],'UserType'] = 'Existing'
16
17#calculate the Revenue per month for each user type
18revenue_per_month = retail_new_df.groupby(['MonthKey','UserType'])['Revenue'].sum().reset_index()
19
20#filtering the dates and plot the result
21revenue_per_month = revenue_per_month.query("MonthKey != 201012 and MonthKey != 201112")
22
23revenue_per_month['MonthKey'] = revenue_per_month['MonthKey'].apply(str)
24revenue_per_month.set_index('MonthKey',inplace=True)
25# Plot regression line
26
27plt.rcParams["figure.figsize"] = [20, 10]
28fig, ax = plt.subplots()
29for label, grp in revenue_per_month.groupby('UserType'):
30    grp.plot(x = grp.index, y = 'Revenue',ax = ax, label = label,style='.-')
31plt.title("Old and New user")
32plt.show()

Hình 8 Hình 8: Số lượng khách hàng mới/ cũ theo từng tháng

Nhận xét rằng, doanh thu cho khách cũ tăng dần theo thời gian, còn doanh thu cho khách mới có vẻ giảm. Để chắc chắn, chúng ta thử vẽ ra tỷ lệ tăng trưởng khách hàng mới xem sao

2.3.7 Tỷ lệ tăng trưởng khách hàng mới

Ta tính tỷ lệ khách hàng mới / khách hàng cũ theo từng tháng

Trong pandas, chúng ta sẽ sử dụng hàm crosstab

 1
 2new_user_ratio = retail_new_df.query("UserType == 'New'").groupby(['MonthKey'])['CustomerID'].nunique()/retail_new_df.query("UserType == 'Existing'").groupby(['MonthKey'])['CustomerID'].nunique()
 3new_user_ratio = new_user_ratio.reset_index()
 4new_user_ratio = new_user_ratio.dropna()
 5new_user_ratio.columns = ["MonthKey","NewCustomerRatio"]
 6
 7new_user_ratio = new_user_ratio.query("MonthKey != 201012 and MonthKey != 201112")
 8new_user_ratio['MonthKey'] = new_user_ratio['MonthKey'].apply(str)
 9
10# Plot regression line
11
12plt.rcParams["figure.figsize"] = [20, 10]
13plt.plot('MonthKey', 'NewCustomerRatio', data=new_user_ratio, linestyle='-', marker='o')
14plt.title("New Customer Ratio")
15plt.show()

Hình 9 Hình 9: Tỷ lệ tăng trưởng khách hàng mới

Như hình trên, chúng ta thấy rằng tỷ lệ khách hàng mới / khách hàng cũ giảm dần theo thời gian

2.3.8 Tỷ lệ giữ chân khách hàng cũ hàng tháng

Khách hàng cũ được hiểu theo nghĩa là khách hàng tháng trước có mua, tháng này có mua

Tỷ lệ giữ chân khách hàng là tỷ lệ khách hàng cũ mua hàng / tổng khách hàng trong tháng

Chúng ta sử dụng hàm crosstab trên khách hàng và tháng, để xem thử tháng đó khách có mua hàng hay không.

 1#identify which users are active by looking at their revenue per month
 2df_user_purchase = retail_df.groupby(['CustomerID','MonthKey'])['Revenue'].sum().reset_index()
 3
 4#create retention matrix with crosstab
 5df_retention = pd.crosstab(df_user_purchase['CustomerID'], df_user_purchase['MonthKey']).reset_index()
 6
 7print(df_retention.head())
 8
 9#create an array of dictionary which keeps Retained & Total User count for each month
10months = df_retention.columns[2:]
11retention_array = []
12for i in range(len(months)-1):
13    retention_data = {}
14    selected_month = months[i+1]
15    prev_month = months[i]
16    retention_data['MonthKey'] = int(selected_month)
17    retention_data['TotalUserCount'] = df_retention[selected_month].sum()
18    retention_data['RetainedUserCount'] = df_retention[(df_retention[selected_month]>0) & (df_retention[prev_month]>0)][selected_month].sum()
19    retention_array.append(retention_data)
20
21#convert the array to dataframe and calculate Retention Rate
22df_retention = pd.DataFrame(retention_array)
23df_retention['RetentionRate'] = df_retention['RetainedUserCount']/df_retention['TotalUserCount']
24
25df_retention = df_retention.query("MonthKey != 201012 and MonthKey != 201112")
26df_retention['MonthKey'] = df_retention['MonthKey'].apply(str)
27
28# Plot regression line
29
30plt.rcParams["figure.figsize"] = [20, 10]
31plt.plot('MonthKey', 'RetentionRate', data=df_retention, linestyle='-', marker='o')
32plt.title("Monthly Retention Rate")
33plt.show()

Kết quả

 1# hàm crosstab trả ra ma trận tương quan giữa khách hàng và tháng, ví dụ như khách hàng 12346 tháng 201012 không có mua hàng, nhưng 201101 lại có
 2>> print(df_retention.head())
 3MonthKey CustomerID  201012  201101  201102  201103  201104  201105  201106  \
 40             12346       0       1       0       0       0       0       0
 51             12347       1       1       0       0       1       0       1
 62             12348       1       1       0       0       1       0       0
 73             12349       0       0       0       0       0       0       0
 84             12350       0       0       1       0       0       0       0
 9
10MonthKey  201107  201108  201109  201110  201111  201112
110              0       0       0       0       0       0
121              0       1       0       1       0       1
132              0       0       1       0       0       0
143              0       0       0       0       1       0
154              0       0       0       0       0       0

Hình 10 Hình 10: Tỷ lệ giữ chân khách hàng cũ

Nhìn hình, ta thấy rằng khách hàng cũ mua lại khá nhiều ở giai đoạn tháng 6 đến tháng 8, sau đó tỷ lệ lại trở lại bình thường.

3. Phân Khúc Khách Hàng

Ở mục trên, chúng ta đã phân tích dữ liệu của công ty bán lẻ trực tuyến và tìm ra yếu tố ảnh hưởng đến doanh thu của công ty. Ở mục này, chúng ta sẽ tiến hành phân loại khách hàng theo nhóm, để phục vụ cho nhu cầu marketing sau này.

Chúng ta phải tiến hành phân loại khách hàng, bởi vì chúng ta không thể đối xử với tất cả khách hàng giống nhau được. Ví dụ là không thể gửi chiến dịch marketing về thịt cho người ăn chay. Hoặc bán lược cho nhà sư (đây là ví dụ minh hoạ của mình nha, còn trên có vài case-study về bán các sản phẩm đó cho đối tượng đó, mình không nói về những trường hợp đó nha).

Ở phần này, chúng ta sẽ tìm hiểu nhu cầu khách hàng sử dụng mô hình RFB.

Như đã đề cập ở mục 1, mô hình RFB bao gồm Recency, Frequency and Monetary

3.1 Clean data

Để mô hình chính xác hơn, chúng ta sẽ clean data, trải qua các bước sau:

  • Loại ra các đơn hàng có Quantity <=0

  • Loại bỏ những đơn hàng CustomerID NA

  • Loại bỏ những đơn hàng bán tháng 12 năm 2010

  • Loại bỏ những đơn hàng bán tháng 12 năm 2011, do phân tích ở trên là data tháng 12 không đủ.

1retail_rfm_df = retail_df.copy()
2#remove canceled orders
3retail_rfm_df = retail_rfm_df[retail_rfm_df['Quantity']>0]
4#remove rows where customerID are NA
5retail_rfm_df.dropna(subset=['CustomerID'],how='all',inplace=True)
6retail_rfm_df = retail_rfm_df[retail_rfm_df['InvoiceDate']> "2010-12-31"]
7retail_rfm_df = retail_rfm_df[retail_rfm_df['InvoiceDate']< "2011-12-01"]

3.1 Tính Recency

Để tính thông số này, chúng ta cần tìm ra ngày mua gần nhất của khách hàng, và số ngày không mua hàng, kể từ ngày mua cuối đến hiện tại.

Kỹ thuật lập trình ở đây:

  • Gán ngày hiện tại là ngày 30 tháng 11 năm 2011

  • Lấy ra ngày mua hàng cuối cùng của mỗi user

  • Tính ra khoảng thời gian kể từ lần mua hàng cuối cùng đến thời điểm hiện tại

 1now = dt.date(2011,11,30)
 2#create a new column called date which contains the date of invoice only
 3retail_rfm_df['date'] = pd.DatetimeIndex(retail_rfm_df['InvoiceDate']).date
 4
 5#group by customers and check last date of purshace
 6recency_df = retail_rfm_df.groupby(by='CustomerID', as_index=False)['date'].max()
 7recency_df.columns = ['CustomerID','LastPurshaceDate']
 8
 9#calculate recency
10recency_df['Recency'] = recency_df['LastPurshaceDate'].apply(lambda x: (now - x).days)
11recency_df.drop('LastPurshaceDate',axis=1,inplace=True)
12print(recency_df.head())

Kết quả

 1>> recency_df.head()
 2  CustomerID  Recency
 30      12346      316
 41      12347       30
 52      12348       66
 63      12349        9
 74      12350      301
 8
 9>> recency_df.Recency.describe()
10count    4174.000000
11mean       82.557499
12std        88.535941
13min         0.000000
1425%        15.000000
1550%        45.000000
1675%       128.000000
17max       330.000000

Chỉ số thống kê cho thấy, giá trị trung bình của Recency là 82, 50% người dùng lặp lại chu kỳ mua hàng trong vòng 45 ngày

3.2 Tính Frequency

Tần suất giúp chúng ta biết được khách hàng đã mua hàng bao nhiêu lần

Kỹ thuật lập trình ở đây khá đơn giản, gom nhóm đơn hàng theo user và đếm

1
2# drop duplicates
3retail_rfm_df_copy = retail_rfm_df
4retail_rfm_df_copy.drop_duplicates(subset=['InvoiceNo', 'CustomerID'], keep="first", inplace=True)
5#calculate frequency of purchases
6frequency_df = retail_rfm_df_copy.groupby(by=['CustomerID'], as_index=False)['InvoiceNo'].count()
7frequency_df.columns = ['CustomerID','Frequency']
8frequency_df.head()

Kết quả

1	CustomerID	Frequency
20	12346	1
31	12347	5
42	12348	3
53	12349	1
64	12350	1

3.3 Tính Monetary

Monetary là tổng tiền khách hàng đã sử dụng

Do đã tính doanh thu từ trước, nên giờ chúng ta sử dụng lại, chỉ cần gom nhóm theo mã khách hàng là được

1
2monetary_df = retail_rfm_df.groupby(['CustomerID'])['Revenue'].sum().reset_index()
3monetary_df.columns = ['CustomerID','Monetary']
4monetary_df.head()

Kết quả

1	CustomerID	Monetary
20	12346	77183.60
31	12347	120.56
42	12348	291.76
53	12349	15.00
64	12350	25.20

3.4 Tạo bảng RFM

Cái này thì siêu đơn giản, chúng ta merge 3 bảng trên lại là xong

1
2#merge recency dataframe with frequency dataframe
3temp_df = recency_df.merge(frequency_df,on='CustomerID')
4#merge with monetary dataframe to get a table with the 3 columns
5rfm_df = temp_df.merge(monetary_df,on='CustomerID')
6#use CustomerID as index
7rfm_df.set_index('CustomerID',inplace=True)
8#check the head
9rfm_df.head()

Kết quả

1
2	Recency	Frequency	Monetary
3CustomerID
412346	316	1	77183.60
512347	30	5	120.56
612348	66	3	291.76
712349	9	1	15.00
812350	301	1	25.20

3.5 Phân nhóm khách hàng sử dụng RFM

Cách đơn giản nhất để phân nhóm khách hàng là sử dụng Quartiles. Chúng ta có thể chia tập khách hàng thành 3 hoặc 4 hoặc 5 nhóm gì đó, tuỳ mục đích kinh doanh.

Ở đây, giả sử mình chia làm 4 nhóm, sử dùng hàm quantile của pandas

Kỹ thuật lập trình như sau:

  • Chia các giá trị của Recency, Frequency, Monetary thành 4 nhóm, có miền giá trị từ 0 đến 3, được 4 cái phần tư vị cho mỗi nhóm

  • Giá trị Recency càng nhỏ càng tốt, trong khi đó, giá trị Frequency và Monetary càng lớn càng tốt, để thống nhất chung, chúng ta sẽ đổi dấu của Recency, để cả 3 cùng thoả tính chất càng lớn càng tốt.

 1
 2#RFM Quartiles
 3rfm_df['Recency'] = -rfm_df['Recency']
 4quantiles = rfm_df.quantile(q=[0.25,0.5,0.75])
 5print(quantiles)
 6quantiles.to_dict()
 7
 8### Creation of RFM Segments
 9
10# Arguments (x = value, p = recency, monetary_value, frequency, k = quartiles dict)
11def FMScore(x,p,d):
12    if x <= d[p][0.25]:
13        return 0
14    elif x <= d[p][0.50]:
15        return 1
16    elif x <= d[p][0.75]:
17        return 2
18    else:
19        return 3
20
21#create rfm segmentation table
22rfm_segmentation = rfm_df
23rfm_segmentation['R_Quartile'] = rfm_segmentation['Recency'].apply(FMScore, args=('Recency',quantiles,))
24rfm_segmentation['F_Quartile'] = rfm_segmentation['Frequency'].apply(FMScore, args=('Frequency',quantiles,))
25rfm_segmentation['M_Quartile'] = rfm_segmentation['Monetary'].apply(FMScore, args=('Monetary',quantiles,))
26
27rfm_segmentation.head()
28
29
30rfm_segmentation['RFMScore'] = rfm_segmentation.R_Quartile.map(str) \
31                            + rfm_segmentation.F_Quartile.map(str) \
32                            + rfm_segmentation.M_Quartile.map(str)
33rfm_segmentation.head()
34
35
36#How many customers do we have in each segment?
37
38print("Best Customers: ",len(rfm_segmentation[rfm_segmentation['RFMScore']=='333']))
39print('Loyal Customers: ',len(rfm_segmentation[rfm_segmentation['F_Quartile']==3]))
40print("Big Spenders: ",len(rfm_segmentation[rfm_segmentation['M_Quartile']==3]))
41print('Almost Lost: ', len(rfm_segmentation[rfm_segmentation['RFMScore']=='133']))
42print('Lost Customers: ',len(rfm_segmentation[rfm_segmentation['RFMScore']=='033']))
43print('Lost Cheap Customers: ',len(rfm_segmentation[rfm_segmentation['RFMScore']=='000']))

Kết quả

 1>> print(quantiles)
 2>> quantiles.to_dict()
 3
 4     Recency  Frequency  Monetary
 50.25     15.0        1.0   17.4000
 60.50     45.0        2.0   43.5000
 70.75    128.0        4.0  119.6625
 8{'Frequency': {0.25: 1.0, 0.5: 2.0, 0.75: 4.0},
 9 'Monetary': {0.25: 17.399999999999999, 0.5: 43.5, 0.75: 119.66250000000001},
10 'Recency': {0.25: 15.0, 0.5: 45.0, 0.75: 128.0}}
11
12>>rfm_segmentation.head()
13
14	Recency	Frequency	Monetary	R_Quartile	F_Quartile	M_Quartile	RFMScore
15CustomerID
1612346	316	1	77183.60	3	0	3	303
1712347	30	5	120.56	1	3	3	133
1812348	66	3	291.76	2	2	3	223
1912349	9	1	15.00	0	0	0	000
2012350	301	1	25.20	3	0	1	301
21
22Best Customers:  10
23Loyal Customers:  980
24Big Spenders:  1044
25Almost Lost:  188
26Lost Customers:  374
27Lost Cheap Customers:  101

Tham khảo

https://blog.hubspot.com/service/rfm-analysis

https://www.investopedia.com/terms/r/rfm-recency-frequency-monetary-value.asp

Cảm ơn các bạn đã dành thời gian đọc bài. Nếu có bất kỳ vấn đề gì, hãy để lại comment bên dưới hoặc email cho mình qua địa chỉ [email protected]. Hẹn gặp lại các bạn ở bài viết tiếp theo.

Source code mình có để ở https://www.kaggle.com/code/alexblack2202/customer-segmentation-using-rfm-analysis

Comments