基於客觀事實的 RFM 模型(用Python進行資料分析)

背景

RFM(Recency Frequency Monetary)模型

是衡量客戶價值和客戶創利能力的重要工具和手段。在眾多的客戶關係管理(CRM)的分析模式中,RFM模型是被廣泛提到的。

RFM模型是屬於業務分析方法與模型中的部分。它的本質是使用者分類。本文將用現代最流行的程式語言——-Python語言來實踐課堂上講解的RFM模型,將使用者進行分類。

基於客觀事實的 RFM 模型(用Python進行資料分析)

本文采用Anaconda進行Python編譯,主要涉及的Python模組:

pandas

matplotlib

seaborn

datetime

本章分為三部分講解:

1.RFM模型原理與步驟

2.Python分佈實現RFM

3.總結

RFM模型原理與步驟

RFM模型的思路是:該模型是根據使用者歷史行為資料,結合業務理解選擇劃分維度,實現使用者分類,助力使用者精準營銷。此外,還學習了構建RFM模型的步驟:

獲取R、F、M三個維度下的原始資料

定義R、F、M的評估模型與判斷閾值

進行資料處理,獲取R、F、M的值

參照評估模型與閾值,對使用者進行分層

針對不同層級使用者制定運營策略

上面步驟可以知道,我們需要有RFM三個維度,根據我們在業務分析方法課程中學到的,業務分析模型離不開指標,而指標是對度量的彙總。因此,在找出RFM三個維度後,需要對每個維度下度量實現不同彙總規則。下面講述對R、F、M三個維度下的度量如何進行彙總。

基於客觀事實的 RFM 模型(用Python進行資料分析)

1。R代表最近一次消費,是計算最近一次消費時間點和當前時間點的時間差。因此,這裡需要用到多維資料透視分析中的基本透視規則——-最小值MIN求出最小的時間差。

2。F代表消費頻次,是在指定區間內統計使用者的購買次數。因此,這裡需要用到多維資料透視分析中的基本透視規則——-技術類COUNT(技術類不去重指標)統計使用者的購買次數。

3。M代表消費金額,是指在指定區間內統計使用者的消費總金額,因此,這裡需要用到求和類指標,也即基本透視規則中的合計規則——-SUM。

在對得到RFM模型中的指標值後最重要的一步就是分層,根據我們在課堂上學到的內容,大部分的使用者分層是根據經驗來分層的,本文在追求資料的客觀性下采取統計學中的等距分箱方法來進行分層,對R、F、M三個維度分成兩類。

綜上,我們大致瞭解瞭如何構建RFM模型,下面以Python實現RFM模型,並對每一步進行詳細的講解。

Python實現RFM模型

1.資料準備

本文所需的資料是一家公司對2021年10月底至今的客戶購買行為資料,(前十二行)如下:

基於客觀事實的 RFM 模型(用Python進行資料分析)

其中,

uid

代表客戶的id,是存在重複情況的。

prince

維度代表客戶每發生一次交易行為所花費的金額。

time

為客戶發生交易行為的時間。

2.資料讀取與理解

在得到一份資料之後,我們第一步就是要理解資料的業務意義,以及對資料表的EDA(探索性分析),這裡透過如下程式碼,發現以下特徵:

基於客觀事實的 RFM 模型(用Python進行資料分析)

具體程式碼(包含Python匯入包部分)如下:

# 匯入相關包import pandas as pdimport timeimport numpy as npimport seaborn as snsimport matplotlib。pyplot as pltplt。rcParams[‘font。sans-serif’] = [“SimHei”]plt。rcParams[“axes。unicode_minus”] = Falsesns。set(style=“darkgrid”)# 資料讀取與檢視data = pd。read_excel(‘data。xlsx’)data。head()data。isnull()。sum() #檢視缺失值data。duplicated()。sum() #重複值,但是不刪data。dtypes #檢視資料型別data。describe()# 建立dataframe,存放RFM各值data_rfm = pd。DataFrame()

接下來進行R、F、M指標值構建。

3.時間維度處理

從上文可以知道

time

維度,即每筆交易行為發生的時間是字串object的格式,而在Python中我們對時間作差需要的是

datetime

格式,因此利用

pandas

庫中的

pd。to_datetime

函式將時間格式進行轉換,程式碼如下:

data[‘time’] = pd。to_datetime(data[‘time’])

得到的前五行資料如圖下,可以看到資料型別變成了

datetime64[ns]

基於客觀事實的 RFM 模型(用Python進行資料分析)

統計每筆訂單產生時間與當前時間的差(這裡的當前時間是2021年12月11日),得到的差是

timedelta64[ns]

型別

基於客觀事實的 RFM 模型(用Python進行資料分析)

可以看到時間差中包含了day、時、分、秒4個維度,但是這裡我們僅需要day維度,因此我們用

astype()

函式將型別轉為僅含有day維度的

timedelta64[D]

型別。具體程式碼如下:

# 統計沒條資料與當前日期的時間差## 計算相差天數data[‘R’] = (pd。datetime。now() - data[‘time’])## 將時間差timedelta格式轉化為需要的日格式data[‘R’] = data[‘R’]。astype(‘timedelta64[D]’)。astype(‘int’)

( tips:這裡可能會報警告:

FutureWarning: The pandas。datetime class is deprecated and will be removed from pandas in a future version。 Import from datetime module instead。

讀者無需理會,這是由於我們所擁有的

pd。datetime。now()

是一個比較舊的函式,以後將會廢棄。 )

4.統計R值

在上面我們已經建立了名為

data_rfm

的表結構的資料框,因此,將下面統計的R值放入其中。R值得統計是找客戶最近發生交易行為日期與當前日期的差。換一種思路就是找所有時間差中的最小值。因此利用

pandas

中的

groupby

函式對每個使用者以上一步統計的R值作為分組依據進行分組,並求出最小值。具體程式碼如下:

data_rfm = pd。merge(data_rfm,data。groupby(‘uid’)[‘R’]。min(), left_on = ‘user_id’,right_on=‘uid’)

5.統計F值

F值得統計就是統計指定區間內的消費頻次,而指定區間一般為人為設定,這裡我們取全部資料,即2021年10月底至今作為指定區間。

本文利用

value_counts()

函式對

uid

進行統計即為每個使用者的消費頻次,同時將結果合併到

data_rfm

資料框中。

# 統計指定區間內的消費頻次data_rfm[‘user_id’] = data[‘uid’]。value_counts()。indexdata_rfm[‘F’] = data[‘uid’]。value_counts()。values

6.統計M值

本文以

uid

作為分組依據對

price

欄位進行求和,得到求和類指標M值。此外,將結果合併到一起

data_rfm

資料框中。

data_rfm = pd。merge(data_rfm,data。groupby(‘uid’)[‘price’]。sum(), left_on = ‘user_id’,right_on=‘uid’)data_rfm。rename(columns={‘price’:‘M’},inplace = True)

上述程式碼中出現了什麼

pandas

庫中的合併語法

merge()

merge()

函式採取的是橫向合併,不同於MYSQL,不需要指定左表還是右表為主表,只需要提供左表與右表的公共欄位在各表中的名稱即可。由於

data_rfm

資料表中的

user_id

是去重的,因此將其作為主鍵。而

data。groupby(‘uid’)[‘price’]。sum()

得到的表格也是去重的,因此我們可以採取多維資料模型中的連線對應關係——-一對一對兩表進行合併。公共欄位為:左表的

uid

,右表的

user_id

最終表格結果如下,展現前18行:

基於客觀事實的 RFM 模型(用Python進行資料分析)

7.資料分享

在得到R、F、M三個指標值後,我們需要對這三個指標進行分類,並將每個使用者進行分層。

本文不採取人為主觀性的經驗法則劃分,而是採取等距分箱的方式劃分,等距分箱的原理較簡單,這裡寫出步驟:

從最小值到最大值之間,均分為$N$等份(這裡$N$取為2)。

如果 $A$,$B$ 為最小最大值, 則每個區間的長度為 $W=(B−A)/N$ ,。

則區間邊界值為$A+W$,$A+2W$,…。$A+(N−1)W$ 。這裡只考慮邊界,採用左閉右開的方式,即每個等份的例項數量不等。

在Python中可以利用

pandas

庫中的

cut()

函式輕鬆實現上述等距分箱,同時將結果

R_label

F_label

M_label

合併到

data_rfm

資料框中具體程式碼如下:

# 分箱 客觀 左閉右開cut_R = pd。cut(data_rfm[‘R’],bins = 2,right = False,labels = range(1,3))。astype(‘int’)data_rfm[‘R_label’] = cut_Rcut_F = pd。cut(data_rfm[‘F’],bins = 2,right = False,labels = range(1,3))。astype(‘int’)data_rfm[‘F_label’] = cut_Fcut_M = pd。cut(data_rfm[‘M’],bins = 2,right = False,labels = range(1,3))。astype(‘int’)data_rfm[‘M_label’] = cut_M

由於利用

cut()

函式得到的是區間形式的值,因此需要賦予label值進行虛擬變數引用。label值使用1和2,對應的區間為從小到大。具體代表意思如下表:

基於客觀事實的 RFM 模型(用Python進行資料分析)

得到最終的表格形式如下:

基於客觀事實的 RFM 模型(用Python進行資料分析)

8.使用者分類

在得到每個使用者的R、F、M三個維度的label值後,最後就是需要對使用者進行分類,分類的原則如圖下:

基於客觀事實的 RFM 模型(用Python進行資料分析)

利用pandas庫中的·

terrows()

函式迴圈遍歷每個使用者行為記錄,將符合上述條件的劃分對應的類,具體程式碼如下:

for i,j in data_rfm。iterrows(): if j[‘R_label’] == 2 and j[‘F_label’] == 2 and j[‘M_label’] == 2: data_rfm。loc[i,‘使用者類別’] = ‘重要價值使用者’ if j[‘R_label’] == 2 and j[‘F_label’] == 1 and j[‘M_label’] == 2: data_rfm。loc[i,‘使用者類別’] = ‘重要發展使用者’ if j[‘R_label’] == 1 and j[‘F_label’] == 2 and j[‘M_label’] == 2: data_rfm。loc[i,‘使用者類別’] = ‘重要保持使用者’ if j[‘R_label’] == 1 and j[‘F_label’] == 1 and j[‘M_label’] == 2: data_rfm。loc[i,‘使用者類別’] = ‘重要挽留使用者’ if j[‘R_label’] == 2 and j[‘F_label’] == 2 and j[‘M_label’] == 1: data_rfm。loc[i,‘使用者類別’] = ‘一般價值使用者’ if j[‘R_label’] == 2 and j[‘F_label’] == 1 and j[‘M_label’] == 1: data_rfm。loc[i,‘使用者類別’] = ‘一般發展使用者’ if j[‘R_label’] == 1 and j[‘F_label’] == 2 and j[‘M_label’] == 1: data_rfm。loc[i,‘使用者類別’] = ‘一般保持使用者’ if j[‘R_label’] == 1 and j[‘F_label’] == 1 and j[‘M_label’] == 1: data_rfm。loc[i,‘使用者類別’] = ‘一般挽留使用者’

9.條形圖視覺化使用者類別

利用

seaborn

畫相簿對已劃分類別的使用者進行技術統計與視覺化,得到如下圖表

基於客觀事實的 RFM 模型(用Python進行資料分析)

可以看出,大部分的使用者屬於一般發展使用者與一般挽留使用者。而對於一般發展使用者而言採取的策略為挖掘需求,後者則是放棄治療。因此,可以看出該公司在10月底至今的時間段內,使用者流失較多,但是可發展的使用者同樣是非常多的,想要提高收入,對一般發展使用者入手是成本少,效率高的選擇。

總結

RFM模型同時還利用了多維資料透視分析和業務分析方法兩個模組的內容。所以說實踐是檢驗和鞏固學到的東西的最好方法。

原文連結:https://mp。weixin。qq。com/s/tNrwXC33abZ3I6KUYPX0-w