1 模型原理
RFM模型是衡客户价值和客户创造利益能力的重要工具和手段。在众多的客户关系管理(CRM)的分析模式中,RFM模型是被广泛提到的。该模型通过一个客户的近期购买行为、购买的总体频率以及花了多少钱3项指标来描述该客户的价值状况。
模型指标:
R(Recency): 最近一次消费
F(Frequency): 消费频率
M(Monetary): 消费金额
对RFM的各个维度分别进行二分,最终形成8种不同的组合,并对8种组合进行不同的定义。
最终形成模型如下:
2 运营策略
- 重要价值用户:最近一次消费时间近、消费频次和消费金额都高,属于优质用户,需要保持,定期提供VIP服务。
- 重要发展用户:最近一次消费时间近、消费金额高,但消费次数少,忠诚度不够,需要通过相关激励,提高复购频率,定期用户回访,提高用户黏性。
- 重要保持用户:消费金额和消费频次都高,但最近一次消费时间远,属于很长时间没来的忠实用户,需要主动和其进行互动,及时唤回。
- 重要挽留用户:消费金额高,但最近一次消费时间远、消费频次低,说明消费能力强,是潜在的价值客户,需要重点维持。
- 一般价值用户:最近一次消费时间近、消费频次高,但消费金额低,属于低客单价群体,可以尝试逐步推广消费金额比较高的产品。
- 一般发展用户:最近一次消费时间近,但消费频次和消费金额低,说明属于意向用户,属于探索期用户,可以主动介绍产品,保持联络。
- 一般保持用户:消费频次多,最近一次消费时间远、消费金额低,总体贡献不大,一般维持即可。
- 一般挽留用户:最近一次消费时间远、消费频次和消费金额也都低,贡献度最小,如果不需要额外的运营预算和精力,也可适当进行维护
3 模型实现
3.1 实现思路
- 对单个用户原始数据进行计算R、F、M三个指标值;
- 对R、F、M三个指标分别进行价值计算,并将其分为1到5个段;
- 分别单个用户的R、F、M的各个指标的价值进行判断,如果低于总用户平均分则标记为“低”,高于平均分则“高”;
- 根据分类规则表将用户打上相应的标签;
3.2 具体实现
3.2.1 数据源
工作台 - Heywhale.comhttps://www.heywhale.com/mw/dataset/63f995627f5ec36e16e810be/file
3.2.2 数据预处理
- 过滤掉有退款交易;
- 将付款时间转换成订单日期;
- 过滤付款金额小于0的交易;
- 按用户进行汇总聚合,单个用户取最后交易时间,交易总条数,总金额;
import pandas as pd
from matplotlib import pyplot as plt
data = pd.read_excel("/Users/yiche1/Desktop/数据分析/study-data/order2021.xlsx")
data = data[data['是否退款']=='否']
data = data[['订单号','用户名','付款金额','付款时间']]
data['订单日期'] = pd.to_datetime(data['付款时间'],format='%Y-%m-%d').dt.date
data = data[data['付款金额'] >=0]
data1 = data.groupby(['用户名','订单日期']).agg(amount = ('付款金额','sum')).reset_index()
data_rfm = data1.groupby(['用户名']).agg(R = ('订单日期','max'),F = ('订单日期','count'), M =('amount','sum')).reset_index()
3.2.3 计算R的分布值
data_rfm['R'] = data_rfm['R'].apply(lambda x: date - x)
data_rfm['R'] = data_rfm['R'].dt.days
R_bin_list = [0 + i * 10 for i in range(54)] #生成R划分列表,以10为划分区间
data_rfm_R = data_rfm[['用户名','R']]
data_rfm_R.loc[:,'R_type'] = pd.cut(data_rfm_R['R'],bins=R_bin_list,right=False)
data_rfm_Rcount = data_rfm_R.groupby('R_type')['用户名'].count()
print(data_rfm_Rcount)
# 画R柱形分布图
plt.figure(figsize=(30,8))
data_rfm_Rcount.plot(kind='bar', color='g', alpha=0.8, width=0.4, rot=0)
# R的累计分布图
lj = data_rfm_Rcount.cumsum()/data_rfm_Rcount.sum()
lj.plot(style='--ko',secondary_y=True)
plt.show()
3.2.4 计算F的分布值
data_rfm_F = data_rfm[['用户名','F']]
F_bin_list = [1,2,3,4,5,6,7,8]
data_rfm_F.loc[:,'F_type'] = pd.cut(data_rfm_F['F'], bins=F_bin_list, right=False)
data_rfm_Fcount = data_rfm_F.groupby('F_type')['用户名'].count()
plt.figure(figsize=(30,8))
data_rfm_Fcount.plot(kind='bar', color='g', alpha=0.8, width=0.4, rot=0)
lj = data_rfm_Fcount.cumsum()/data_rfm_Rcount.sum()
lj.plot(style='--ko',secondary_y=True)
plt.show()
3.2.5 计算M的分布值
M_bin_list = [0 + i * 200 for i in range(51)]
M_bin_list.append(1000000)
data_rfm_M = data_rfm[['用户名','M']]
data_rfm_M.loc[:,'M_type'] = pd.cut(data_rfm_M['M'], bins=M_bin_list, right=False)
data_rfm_Mcount = data_rfm_M.groupby('M_type')['用户名'].count()
plt.figure(figsize=(30,8))
data_rfm_Mcount.plot(kind='bar', color='g', alpha=0.8, width=0.4, rot=0)
lj = data_rfm_Mcount.cumsum()/data_rfm_Mcount.sum()
lj.plot(style='--ko',secondary_y=True)
plt.show()
3.2.6 数据打标
根据拐点法定义数据价值区间,对R、F、M分别进行区间划分;比较价值分与总用户平均分的大小,打上“高、低”价值标签;通过影射表关联用户标签;
# 定义区间边界
r_bins = [-1,30,60,150,240,370]
f_bins = [0,1,2,3,4,7]
m_bins = [-1,600,1400,2600,5000,1000000]
# RFM分箱得分
data_rfm['R_score'] = pd.cut(data_rfm['R'], r_bins, labels=[i for i in range(len(r_bins)-1,0,-1)]).astype('int') #计算R得分
data_rfm['F_score'] = pd.cut(data_rfm['F'], f_bins, labels=[i+1 for i in range(len(f_bins)-1)]).astype('int') #计算F得分
data_rfm['M_score'] = pd.cut(data_rfm['M'], m_bins, labels=[i+1 for i in range(len(m_bins)-1)]).astype('int') #计算M得分
data_rfm['R_value'] = data_rfm['R_score'].apply(lambda x:'1' if x>=data_rfm['R_score'].mean() else '0')
data_rfm['F_value'] = data_rfm['F_score'].apply(lambda x:'1' if x>=data_rfm['F_score'].mean() else '0')
data_rfm['M_value'] = data_rfm['M_score'].apply(lambda x:'1' if x>=data_rfm['M_score'].mean() else '0')
data_rfm['result'] = data_rfm['R_value']+data_rfm['F_value']+data_rfm['M_value']
data_label = pd.DataFrame([['111','重要价值用户'],
['101','重要发展用户'],
['011','重要保持用户'],
['001','重要挽留用户'],
['110','一般价值用户'],
['100','一般发展用户'],
['010','一般保持用户'],
['000','一般挽留用户']],
columns=['result','user_label'])
# 数据与标签join
data_rfm_result = pd.merge(data_rfm,data_label, on='result', how='left')
print(data_rfm_result)