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