RFM 模型是一种常用于客户细分与营销分析 的模型,特别是在电子商务、市场营销和用户分析中广泛应用。RFM 代表的是**Recency(最近一次购买时间)、Frequency(购买频率)和Monetary(消费金额)**这三个指标,用来衡量客户行为并帮助企业制定针对性的营销策略。
RFM 模型的核心思想
通过对客户的购买行为进行分析,将客户按最近一次购买时间、购买频率和消费金额 三个维度进行分组,从而识别出高价值客户 、潜在客户 、流失客户等群体,帮助企业在不同的客户群体中制定个性化的营销策略。
具体的三个维度
- Recency(R)最近一次购买时间
- 定义:客户上次购买的时间距离当前有多久。
- 意义:最近购买的客户可能对品牌更感兴趣,可能是活跃客户。
- 如何计算:可以根据当前日期减去客户上次购买的日期,得到的天数越小,说明客户越活跃。
- Frequency(F)购买频率
- 定义:客户在一定时间内购买的次数。
- 意义:购买频率高的客户通常是忠实客户,可能具有较高的品牌粘性。
- 如何计算:在一定时间内(例如:过去 6 个月内)客户的购买次数。
- Monetary(M)消费金额
- 定义:客户在一定时间内的总消费金额。
- 意义:消费金额高的客户通常是高价值客户,企业应该重点关注。
- 如何计算:在一定时间内(例如:过去 6 个月)客户的累计消费金额。
RFM 模型的应用步骤
- 数据收集:首先收集客户的历史购买数据,包括每次购买的时间、金额、次数等信息。
- 数据处理与计算 :根据数据计算每个客户的 R、F、M 三个指标。
- Recency:计算当前时间与客户最近一次购买的时间差。
- Frequency:计算客户在一定时间内的购买次数。
- Monetary:计算客户在一定时间内的总消费金额。
- 客户分群 :根据 R、F、M 的值将客户进行分组。通常使用量化打分 的方法,将每个指标分为几个等级(如:高、中、低)。
- Recency:时间越近,分数越高。
- Frequency:购买频率越高,分数越高。
- Monetary:消费金额越高,分数越高。
- 营销策略 :根据不同的客户分群,制定相应的营销策略:
- 高 R、F、M:忠诚客户,可以发送定制的优惠券、会员福利等,保持他们的活跃度。
- 高 R,低 F 和 M:新客户或潜在客户,需要通过邮件、推送等方式进行培养,提高频次和金额。
- 低 R,低 F 和 M:流失客户,可能需要通过重新激活的策略(如限时优惠、促销活动等)来恢复关系。
数据预处理
在一个excel文件中,有多个表格。如何一次性加载多个工作表,此时如下,会报错,需要用到 openpyxl 库。
py
## pip install openpyxl
import pandas as pd
sheet_names = ['2015', '2016', '2017', '2018', '会员等级']
sheet_dicts = pd.read_excel('./sales.xlsx', sheet_name=sheet_names)
print(type(sheet_dicts)) # 是字典类型
sheet_dicts['2015'] # 获取2015年的数据
排除无效值和空值
py
for i in sheet_names[:-1]:
# 删除缺失值
sheet_dicts[i] = sheet_dicts[i].dropna()
# 过滤掉余额过低的
sheet_dicts[i] = sheet_dicts[i][sheet_dicts[i]['订单金额'] > 1]
# 新增一列,表示固定时间
sheet_dicts[i]['max_year_date'] = sheet_dicts[i]['提交日期'].max()
合并值
py
# 合并数据集
# 将前四个表的数据,拼接成 dataFrame
data_merge = pd.concat(list(sheet_dicts.values())[:-1], ignore_index=True)
# 给表新增一列,表示年
data_merge['year'] = data_merge['max_year_date'].dt.year
# 间隔时间
data_merge['data_interval'] = data_merge['max_year_date'] - data_merge['提交日期']
# 把间隔时间变成天数
data_merge['data_interval'] = data_merge['data_interval'].dt.days
聚合运行,计算统计信息
py
# 按照 year 和 会员ID分组,分别计算(r 最近购买时间)f(频次) m(金额)三项
rmf_fb = data_merge.groupby(['year', '会员ID'], as_index=False).agg(
r=('data_interval', 'min'),
f=('订单号', 'count'),
m=('订单金额', 'sum')
)
规则约束,数据处理
我们往往会根据实际的场景,做一些限制。叫做定义边界。已知
- r和m的数据分布相对较为离散,表现在min、25%、50%、75%和max的数据没有特别集中
- 大部分用户的分布都趋近于1,表现是从min到75%的分段值都是1且mean(均值)才为1.365
- 计划选择25%和75%作为区间划分的2个边界值
- 与业务部门沟通,划分时可以使用2和5来作为边界
- 业务部门认为当年购买>=2次可被定义为复购用户(而非累计订单的数量计算复购用户)
- 业务部门认为普通用户购买5次已经是非常高的次数,超过该次数就属于非常高价值用户群体
此时设计,已知 R为,0,79,255,365。 百分之50 不在规则里。
为了使,0~1 的数据也能被正常,设置为,-1,并不是真的有负数,只是为了能包含0左右的数据。所以结果为,-1,79,255,365。
第二组数据,是f表示频率,规则里也说了,采用,2,5法。原值为,1,1,1,130。定义边界后,0,2,5,130.
第三组,没有限制,全包了就可以,定义前,1.5,69.0,189.0,1199.0,206251.8 定义后 0, 69, 1199, 206252
问题就来了,究竟什么时候才能加 -1呢?这就要看第一个区间了。 由图得知,第一个区间是,79~156,那么包含 min 的值 0 吗?肯定是不包含了啊,所以需要加。第二个f,肯定不会了,第三个加 0 就可以了。
py
# 自定义区间
r_bins = [-1, 79, 255, 365]
f_bins = [0, 2, 5, 130]
m_bins = [0, 69, 1199, 206252]
# 自动划分区间,给点区间数,由 pandas 进行具体划分
pd.cut(rmf_fb['r'], bins=3).unique()
# [(121.667, 243.333], (243.333, 365.0], (-0.365, 121.667]]
# Categories (3, interval[float64, right]): [(-0.365, 121.667] < (121.667, 243.333] < (243.333, 365.0]]
# 自定义区间。include_lowest=True 参数可以包左。
pd.cut(rmf_fb['r'], bins=r_bins).unique()
# [(79, 255], (255, 365], (-1, 79]]
# Categories (3, interval[int64, right]): [(-1, 79] < (79, 255] < (255, 365]]
# 自定义区间 + 评分,会根据每一组进行评分。比如,-1~79,第一组,结果是3.
pd.cut(rmf_fb['r'], bins=r_bins, labels=[3, 2, 1])
完整,项目完整代码继续
py
# 自定义区间
r_bins = [-1, 79, 255, 365]
f_bins = [0, 2, 5, 130]
m_bins = [0, 69, 1199, 206252]
# 自定义区间 + 评分,R是最后一次购买时间,越小越好,评分是3,2,1
rmf_fb['r_label'] = pd.cut(rmf_fb['r'], bins=r_bins, labels=[i for i in range(len(r_bins) - 1, 0, -1)])
# F是购买频率,越大越好,评分是,1,2,3
rmf_fb['f_label'] = pd.cut(rmf_fb['f'], bins=f_bins, labels=[i for i in range(1, len(f_bins))])
# M是购买金额,越大越好,评分是,1,2,3
rmf_fb['m_label'] = pd.cut(rmf_fb['m'], bins=m_bins, labels=[i for i in range(1, len(m_bins))])
评分加权
我们计算出来了结果,希望对三项进行合并成一个字段。
思路1:r_label * 权重 + f_label * 权重 + m_label * 权重
思路2:拼接思路,即全部相加,不需要 * 权重
py
rmf_fb['r_label'] = rmf_fb['r_label'].astype(str)
rmf_fb['f_label'] = rmf_fb['f_label'].astype(str)
rmf_fb['m_label'] = rmf_fb['m_label'].astype(str)
rmf_fb['rfm_group'] = rmf_fb['r_label'] + rmf_fb['f_label'] + rmf_fb['m_label']
数据保存
py
import pandas as pd
from sqlalchemy import create_engine
from sqlalchemy import create_engine
# 保存到xlsx
rmf_fb.to_excel('./rfm结果.xlsx', index=False)
# 保存到mysql
engin = create_engine('mysql+pymysql://root:123456@localhost:3306/demo?charset=utf8')
rmf_fb.to_sql('demo', engin, if_exists='replace', index=False)
数据可视化,3D 柱状图
数据处理,统计分析
py
# 1. 安装用户类型,年份分组,统计会议总数
# 思路1. value_counts()
# rmf_fb.groupby(['rfm_group', 'year'])['会员ID'].value_counts()
# 思路2. groupby + 聚合函数
display_data = rmf_fb.groupby(['rfm_group', 'year'], as_index=False).agg(
number=('会员ID', 'count')
)
# 修改字段类型
display_data['rfm_group'] = display_data['rfm_group'].astype(int)
执行完下面的代码,会生成一个html,可以打开查看
py
import pandas as pd
from pyecharts.charts import Bar3D
import pyecharts.options as opts
# 显示图形
# 颜色池
range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf',
'#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
range_max = int(display_data['number'].max())
c = (
Bar3D()#设置了一个3D柱形图对象
.add(
"",#图例
[d.tolist() for d in display_data.values],#数据
xaxis3d_opts=opts.Axis3DOpts(type_="category", name='分组名称'),#x轴数据类型,名称,rfm_group
yaxis3d_opts=opts.Axis3DOpts(type_="category", name='年份'),#y轴数据类型,名称,year
zaxis3d_opts=opts.Axis3DOpts(type_="value", name='会员数量'),#z轴数据类型,名称,number
)
.set_global_opts( # 全局设置
visualmap_opts=opts.VisualMapOpts(max_=range_max, range_color=range_color), #设置颜色,及不同取值对应的颜色
title_opts=opts.TitleOpts(title="RFM分组结果"),#设置标题
)
)
c.render() #数据保存到本地的网页中.
# c.render_notebook() #在notebook中显示

总结
会员价值度模型介绍
-
会员价值度用来评估用户的价值情况,是区分会员价值的重要模型和参考依据,也是衡量不同营销效果的关键指标之一。
-
价值度模型一般基于交易行为产生,衡量的是有实体转化价值的行为。常用的价值度模型是RFM
-
RFM模型是根据会员
- 最近一次购买时间R(Recency)
- 购买频率F(Frequency)
- 购买金额M(Monetary)计算得出RFM得分
- 通过这3个维度来评估客户的订单活跃价值,常用来做客户分群或价值区分
- RFM模型基于一个固定时间点来做模型分析,不同时间计算的的RFM结果可能不一样
R F M 用户类别 高 高 高 重要价值用户 高 低 高 重要发展用户 低 高 高 重要保持用户 低 低 高 重要挽留用户 高 高 低 一般价值用户 高 低 低 一般发展用户 低 高 低 一般保持用户 低 低 低 一般挽留用户 -
RFM模型的基本实现过程:
- 设置要做计算时的截止时间节点(例如2017-5-30),用来做基于该时间的数据选取和计算。
- 在会员数据库中,以今天为时间界限向前推固定周期(例如1年),得到包含每个会员的会员ID、订单时间、订单金额的原始数据集。一个会员可能会产生多条订单记录。
- 数据预计算。从订单时间中找到各个会员距离截止时间节点最近的订单时间作为最近购买时间;以会员ID为维度统计每个用户的订单数量作为购买频率;将用户多个订单的订单金额求和得到总订单金额。由此得到R、F、M三个原始数据量。
- R、F、M分区。对于F和M变量来讲,值越大代表购买频率越高、订单金额越高;但对R来讲,值越小代表离截止时间节点越近,因此值越好。对R、F、M分别使用五分位法做数据分区(三分位也可以,分位数越多划分得越详细)。需要注意的是,对于R来讲需要倒过来划分,离截止时间越近的值划分越大。这样就得到每个用户的R、F、M三个变量的分位数值。
- 将3个值组合或相加得到总的RFM得分。对于RFM总得分的计算有两种方式,一种是直接将3个值拼接到一起,例如RFM得分为312、333、132;另一种是直接将3个值相加求得一个新的汇总值,例如RFM得分为6、9、6。
-
在得到不同会员的RFM之后,根据步骤⑤产生的两种结果有两种应用思路
- 思路1:基于3个维度值做用户群体划分和解读,对用户的价值度做分析
- 比如,RFM得分为212的会员的F是1,往往购买频率较低,那就可以针对购买频率低的客户应定期发送促销活动邮件
- 比如,RFM得分为321的会员虽然购买频率高但是订单金额低等,这些客户往往具有较高的购买黏性,可以考虑通过关联或搭配销售的方式提升订单金额。
- 思路2:基于RFM的汇总得分评估所有会员的价值度,并可以做价值度排名。同时,该得分还可以作为输入维度与其他维度一起作为其他数据分析和挖掘模型的输入变量,为分析建模提供基础。
- 思路1:基于3个维度值做用户群体划分和解读,对用户的价值度做分析
-
RFM小结:
-
R就是距离自定义的时间点最近一次购买的时间间隔、间隔越小得分越高
-
F就是自定义的时间范围内购买频率、次数越多得分越高
-
M就是自定义的时间范围内购买总金额,总额越大得分越高
-
RFM的区间和其对应的得分由我们自定义
-
RFM用户特征分析
经过上面的分析,得到了要分析的重点客户群体。可根据用户的量级分为两类
- 第1类是用户群体占比超过10%的群体
- 第2类是占比在个位数的群体。这两类人由于量级不同,因此需要分别有针对性的策略场景。
- 除此以外,我们还会增加第3类人群,虽然从用户量级上小,但是单个人的价值度非常高。
- 第1类人群:212、211、312、112、213;占比超过10%的群体。由于这类人群基数大,必须采取批量操作和运营的方式落地运营策略,一般需要通过系统或产品实现,而不能主要依赖于人工
- 212:可发展的一般性群体。这类群体购买新近度和订单金额一般,且购买频率低。考虑到其最大的群体基础,以及在新近度和订单金额上都可以,因此可采取常规性的礼品兑换和赠送、购物社区活动、签到、免运费等手段维持并提升其消费状态。
- 211:可发展的低价值群体。这类群体相对于212群体在订单金额上表现略差,因此在211群体策略的基础上,可以增加与订单相关的刺激措施,例如组合商品优惠券发送、积分购买商品等
- 312:有潜力的一般性群体。这类群体购买新近度高,说明最近一次购买发生在很短时间之前,群体对于公司尚有比较熟悉的接触渠道和认知状态;购物频率低,说明对网站的忠诚度一般;订单金额处于中等层级,说明其还具有可提升的空间。因此,可以借助其最近购买的商品,为其定制一些与上次购买相关的商品,通过向上销售等策略提升购买频次和订单金额
- 112:可挽回的一般性群体。这类群体购买新近度较低,说明距离上次购买时间较长,很可能用户已经处于沉默或预流失、流失阶段;购物频率低,说明对网站的忠诚度一般;订单金额处于中等层级,说明其还可能具有可提升的空间。因此,对这部分群体的策略首先是通过多种方式(例如邮件、短信等)触达客户并挽回,然后通过针对流失客户的专享优惠(例如流失用户专享优惠券)措施促进其消费。在此过程中,可通过增加接触频次和刺激力度的方式,增加用户的回访、复购以及订单价值回报
- 213:可发展的高价值群体。这类人群发展的重点是提升购物频率,因此可指定不同的活动或事件来触达用户,促进其回访和购买,例如不同的节日活动、每周新品推送、高价值客户专享商品等。
- 第2类人群:占比为1%~10%的群体。这部分人群数量适中,在落地时无论是产品还是人工都可接入
- 311:有潜力的低价值群体。这部分用户与211群体类似,但在购物新近度上更好,因此对其可采取相同的策略。除此以外,在这类群体的最近接触渠道上可以增加营销或广告资源投入,通过这些渠道再次将客户引入网站完成消费。
- 111:这是一类在各个维度上都比较差的客户群体。一般情况下,会在其他各个群体策略和管理都落地后才考虑他们。主要策略是先通过多种策略挽回客户,然后为客户推送与其类似的其他群体,或者当前热销的商品或折扣非常大的商品。在刺激消费时,可根据其消费水平、品类等情况,有针对性地设置商品暴露条件,先在优惠券及优惠商品的综合刺激下使其实现消费,再考虑消费频率以及订单金额的提升。
- 313:有潜力的高价值群体。这类群体的消费新近度高且订单金额高,但购买频率低,因此只要提升其购买频次,用户群体的贡献价值就会倍增。提升购买频率上,除了在其最近一次的接触渠道上增加曝光外,与最近一次渠道相关的其他关联访问渠道也要考虑增加营销资源。另外,213中的策略也要组合应用其中
- 113:可挽回的高价值群体。这类群体与112群体类似,但订单金额贡献更高,因此除了应用112中的策略外,可增加部分人工的参与来挽回这些高价值客户,例如线下访谈、客户电话沟通等
- 第3类群体:占比非常少,但却是非常重要的群体
- 333:绝对忠诚的高价值群体。虽然用户绝对数量只有355,但由于其各方面表现非常突出,因此可以倾斜更多的资源,例如设计VIP服务、专享服务、绿色通道等。另外,针对这部分人群的高价值附加服务的推荐也是提升其价值的重点策略
- 233、223和133:一般性的高价值群体。这类群体的主要着手点是提升新近购买度,即促进其实现最近一次的购买,可通过DM、电话、客户拜访、线下访谈、微信、电子邮件等方式直接建立用户挽回通道,以挽回这部分高价值用户
- 322、323和332:有潜力的普通群体。这类群体最近刚完成购买,需要提升的是购买频次及购买金额。因此可通过交叉销售、个性化推荐、向上销售、组合优惠券、打包商品销售等策略,提升其单次购买的订单金额及促进其重复购买
案例应用
针对上述得到的分析结论,会员部门采取了以下措施
- 分别针对3类群体,按照公司实际运营需求和当前目标,制定了不同的群体落地的排期
- 录入数据库的RFM得分数据已经应用到其他数据模型中,成为建模输入的关键维度特征之一
案例注意点
R 最近一次消费的间隔时间
F 消费频率
M 消费总额
-
不同品类、行业对于RFM的依赖度是有差异的,即使是一个公司在不同的发展阶段和周期下,3个维度的优先级上也会有调整
- 大家电等消费周期较长的行业,R和M会更重要一些
- 快消等消费周期短且快的行业,更看重R和F
- 具体要根据当前运营需求与业务部门沟通
-
对R、F、M区间的划分是一个离散化的过程,具体需要划分为几个区间需要与业务方确认
- 本案例划分为3个区间,结果对于业务分析而言有些多,意味着业务方需要制定十几套甚至更多的策略
- 如果业务方要求简化,也可以划分为2个区间,这样出来的分组数最多有8组,策略制定更加简单
- 具体是划分为2个还是3个,取决于当前业务方有多少资源可以投入到这个事情中来。
-
R、F、M的权重打分
- 除了案例中提到的建模方式外,结合业务经验的专家打分法也是常用的思路,这时推荐结合AHP层次分析法打分,这样出来的权重结果更加科学、严谨。
- 虽然订单数据库中的数据质量相对较高,但可能由于数据采集、数据库同步、ETL、查询、误操作等问题,还是会导致NA值的出现,而NA值的处理非常重要。
- R、F、M三个维度的处理(包括计算、离散化、组合、转换)之前都需要注意其数据类型和格式,尤其是有关时间项的转换操作应提前完成
小结
- RFM模型是经典的一种用户分群方法,操作起来比较简单,如果数据量不是很大的时候,直接使用Excel就可以实现
- RFM并不是在所有业务场景下都可以使用,一般用于零售行业(复购率相对高的行业)
- 使用Python的cut方法对数据进行分组,需要注意分组区间默认是左开右闭
- 使用Pyecharts可以方便的绘制出可以交互的3D图