7. RFM用户分析模型

2023-10-12 11:59
文章标签 用户 分析模型 rfm

本文主要是介绍7. RFM用户分析模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RFM,是一种经典到头皮发麻的用户分类、价值分析模型,同时,这个模型以直白著称,直白到把需要的字段写在了脸上:

  • R:Rencency,即每个客户有多少天没回购了,可以理解为最近一次购买到现在隔了多少天
  • F:Frequency,是每个客户购买了多少次
  • M:Monetary,代表每个客户平均购买金额,这里也可以是累计购买金额

这三个维度,是RFM模型的精髓所在,帮助我们把混杂一体的客户数据分成标准的8类,然后根据每一类用户人数占比、金额贡献等不同的特征,进行人、货、场三重匹配的精细化运营。

用Python建立RFM模型,整体建模思路分为五步,一言蔽之——五步在手,模型你有,分别是数据概览数据清洗维度打分分值计算客户分层

1. 数据概览

我们的源数据是订单表,记录着用户交易相关的字段:
在这里插入图片描述
有个细节需要注意,订单每一行代表着单个用户的单次购买行为,什么意思呢?如果一个用户在一天内购买了4次,订单表对应记录着4行,而在实际的业务场景中,一个用户在一天内的多次消费行为,应该从整体上看作一次

比如,我今天10点在必胜客天猫店买了个披萨兑换券,11点又下单了饮料兑换券,18点看到优惠又买了两个冰淇淋兑换券。这一天内虽然我下单了3次,但最终这些兑换券我会一次消费掉,应该只算做一次完整的消费行为,这个逻辑会指导后面F值的计算。

我们发现在订单状态中,除了交易成功的,还有用户退款导致交易关闭的,那还包括其他状态吗?
在这里插入图片描述
只有这两种状态,其中退款订单对于我们模型价值不大,需要在后续清洗中剔除。接着再观察数据的类型和缺失情况
在这里插入图片描述
订单一共28833行,没有任何缺失值,类型方面,付款日期是时间格式,实付金额、邮费和购买数量是数值型,其他均为字符串类型。

2. 数据清洗

剔除退款

在观察阶段,我们明确了第一个清洗的目标,就是剔除退款数据:
在这里插入图片描述

关键字段提取

剔除之后,觉得我们订单的字段还是有点多,而RFM模型只需要买家昵称付款时间实付金额这3个关键字段,所以提取之:
在这里插入图片描述

关键字段构造

上面的基础清洗告一段落,这一步关键在于构建模型所需的三个字段:R(最近一次购买距今多少天),F(购买了多少次)以及M(平均或者累计购买金额)。

R值获取

首先是R值,即每个用户最后一次购买时间距今多少天。如果用户只下单过一次,用现在的日期减去付款日期即可;若是用户多次下单,需先筛选出这个用户最后一次付款的时间,再用今天减去它。

因此,要拿到所有用户最近一次付款时间,只需要按买家昵称分组,再选取付款日期的最大值即可:
在这里插入图片描述
在这里插入图片描述

F值计算

接着来搞定F值,即每个用户累计购买频次。在前面数据概览阶段,我们明确了·把单个用户一天内多次下单行为看作整体一次·的思路,所以,引入一个精确到天的日期标签,依照买家昵称日期标签进行分组,把每个用户一天内的多次下单行为合并,再统计购买次数:

#引入日期标签辅助列
df['日期标签'] = df['付款日期'].astype(str).str[:10]#把单个用户一天内订单合并 主要是将单日的付款日期设置为1,因为一个客户不可能在同一时刻下单多次
dup_f = df.groupby(['买家昵称','日期标签'])['付款日期'].count().reset_index()#对合并后的用户统计频次
f = dup_f.groupby('买家昵称')['付款日期'].count().reset_index()
f.columns = ['买家昵称','F']
f.head()

在这里插入图片描述

M值计算

上一步计算出了每个用户购买频次,这里我们只需要得到每个用户总金额,再用总金额除以购买频次,就能拿到用户平均支付金额:

sum_m = df.groupby('买家昵称')['实付金额'].sum().reset_index()
sum_m.columns = ['买家昵称','总支付金额']
com_m = pd.merge(sum_m,f,left_on = '买家昵称',right_on = '买家昵称',how = 'inner')#计算用户平均支付金额
com_m['M'] = com_m['总支付金额'] / com_m['F']
com_m.head()

在这里插入图片描述
最后 三个指标合并:

rfm = pd.merge(r,com_m,left_on = '买家昵称',right_on = '买家昵称',how = 'inner')
rfm = rfm[['买家昵称','R','F','M']]
rfm.head()

在这里插入图片描述

3. 维度打分

维度确认的核心是分值确定,按照设定的标准,我们给每个消费者的R/F/M值打分,分值的大小取决于我们的偏好,即我们越喜欢的行为,打的分数就越高

  • 以R值为例,R代表了用户有多少天没来下单,这个值越大,用户流失的可能性越大,我们当然不希望用户流失,所以R越大,分值越小。

  • F值代表了用户购买频次,M值则是用户平均支付金额,这两个指标是越大越好,即数值越大,得分越高。

RFM模型中打分一般采取5分制,有两种比较常见的方式,一种是按照数据的分位数来打分,另一种是依据数据和业务的理解,进行分值的划分。这里希望同学们加深对数据的理解,进行自己的分值设置,所以讲述过程中使用的是第二种,即提前制定好不同数值对应的分值。

R值根据行业经验,设置为30天一个跨度,区间左闭右开:
在这里插入图片描述
F值和购买频次挂钩,每多一次购买,分值就多加一分:
在这里插入图片描述

我们可以先对M值做个简单的区间统计,然后分组,这里我们按照50元的一个区间来进行划分:
在这里插入图片描述
确定了一个打分框架,每一位用户的每个指标,都有了与之对应的分值。

4. 分值计算

分值的划分逻辑已经确定,看着好像有点麻烦。但是用pandas的 cut 相当容易。

rfm['R-SCORE'] = pd.cut(rfm['R'],bins = [0,30,60,90,120,1000000],labels = [5,4,3,2,1],right = False).astype(float)
rfm['F-SCORE'] = pd.cut(rfm['F'],bins = [1,2,3,4,5,1000000],labels = [1,2,3,4,5],right = False).astype(float)
rfm['M-SCORE'] = pd.cut(rfm['M'],bins = [0,50,100,150,200,1000000],labels = [1,2,3,4,5],right = False).astype(float)
rfm.head()

在这里插入图片描述
现在R-SCORE、F-SCORE、M-SCORE在1-5几个数之间,如果把3个值进行组合,像111,112,113…这样可以组合出125种结果,过多的分类和不分类本质是一样的。所以,我们通过判断每个客户的R、F、M值是否大于平均值,来简化分类结果。

因为每个客户和平均值对比后的R、F、M,只有0和1(0表示小于平均值,1表示大于平均值)两种结果,整体组合下来共有8个分组,是比较合理的一个情况。我们来判断用户的每个分值是否大于平均值:

rfm['R是否大于均值'] = (rfm['R-SCORE'] > rfm['R-SCORE'].mean()) * 1
rfm['F是否大于均值'] = (rfm['F-SCORE'] > rfm['F-SCORE'].mean()) * 1
rfm['M是否大于均值'] = (rfm['M-SCORE'] > rfm['M-SCORE'].mean()) * 1
rfm.head()

在这里插入图片描述
Python中判断后返回的结果是True和False,对应着数值1和0,只要把这个布尔结果乘上1,True就变成了1,False变成了0,处理之后更加易读。

5. 客户分层

回顾一下前几步操作,清洗完之后我们确定了打分逻辑,然后分别计算每个用户的R、F、M分值(SCORE),随后,用分值和对应的平均值进行对比,得到了是否大于均值的三列结果。至此,建模所需的所有数据已经准备就绪,剩下的就是客户分层了。

RFM经典的分层会按照R/F/M每一项指标是否高于平均值,把用户划分为8类,我们总结了一下,具体像下面表格这样:
在这里插入图片描述
参考机器学习中的 One-Hot 思路 先引入一个人群数值的辅助列,把之前判断的R\F\M是否大于均值的三个值给串联起来:

rfm['人群数值'] = (rfm['R是否大于均值'] * 100) + (rfm['F是否大于均值'] * 10) + (rfm['M是否大于均值'] * 1)
rfm.head()
```![在这里插入图片描述](https://img-blog.csdnimg.cn/20200707161733230.png#pic_center)
人群数值是数值类型,所以位于前面的0就自动略过,比如1代表着“001”的高消费唤回客户人群,10对应着“010”的一般客户。
为了得到最终人群标签,再定义一个判断函数,通过判断人群数值的值,来返回对应的分类标签:**基于指标给客户打标签**
```python
#判断R/F/M是否大于均值
def transform_label(x):if x == 111:label = '重要价值客户'elif x == 110:label = '消费潜力客户'elif x == 101:label = '频次深耕客户'elif x == 100:label = '新客户'elif x == 11:label = '重要价值流失预警客户'elif x == 10:label = '一般客户'elif x == 1:label = '高消费唤回客户'elif x == 0:label = '流失客户'return label

最后把标签分类函数应用 apply 到人群数值列:

rfm['人群类型'] = rfm['人群数值'].apply(transform_label)
rfm.head()

在这里插入图片描述

6. RFM模型结果分析

其实到上一步,已经走完了整个建模流程,但是呢,一切模型结果最终都要服务于业务,所以,最后我们基于现有模型结果做一些拓展、探索性分析。
查看各类用户占比情况 value_counts:

count = rfm['人群类型'].value_counts().reset_index()
count.columns = ['客户类型','人数']
count['人数占比'] = count['人数'] / count['人数'].sum()
count

在这里插入图片描述
探究不同类型客户消费金额贡献占比:

rfm['购买总金额'] = rfm['F'] * rfm['M']
mon = rfm.groupby('人群类型')['购买总金额'].sum().reset_index()
mon.columns = ['客户类型','消费金额']
mon['金额占比'] = mon['消费金额'] / mon['消费金额'].sum()
mon

在这里插入图片描述
汇总:

result = pd.merge(count,mon,left_on = '客户类型',right_on = '客户类型')
result

在这里插入图片描述
最终模型封装:

#输入源数据文件名
def get_rfm(name = 'PYTHON-RFM实战数据.xlsx'):df = pd.read_excel(name)df = df.loc[df['订单状态'] == '交易成功',:]print('剔除退款后还剩:%d行' % len(df))df = df[['买家昵称','付款日期','实付金额']]r = df.groupby('买家昵称')['付款日期'].max().reset_index()r['R'] = (pd.to_datetime('2019-7-1') - r['付款日期']).dt.daysr = r[['买家昵称','R']]#引入日期标签辅助列df['日期标签'] = df['付款日期'].astype(str).str[:10]#把单个用户一天内订单合并dup_f = df.groupby(['买家昵称','日期标签'])['付款日期'].count().reset_index()#对合并后的用户统计频次f = dup_f.groupby('买家昵称')['付款日期'].count().reset_index()f.columns = ['买家昵称','F']sum_m = df.groupby('买家昵称')['实付金额'].sum().reset_index()sum_m.columns = ['买家昵称','总支付金额']com_m = pd.merge(sum_m,f,left_on = '买家昵称',right_on = '买家昵称',how = 'inner')#计算用户平均支付金额com_m['M'] = com_m['总支付金额'] / com_m['F']rfm = pd.merge(r,com_m,left_on = '买家昵称',right_on = '买家昵称',how = 'inner')rfm = rfm[['买家昵称','R','F','M']]rfm['R-SCORE'] = pd.cut(rfm['R'],bins = [0,30,60,90,120,1000000],labels = [5,4,3,2,1],right = False).astype(float)rfm['F-SCORE'] = pd.cut(rfm['F'],bins = [1,2,3,4,5,1000000],labels = [1,2,3,4,5],right = False).astype(float)rfm['M-SCORE'] = pd.cut(rfm['M'],bins = [0,50,100,150,200,1000000],labels = [1,2,3,4,5],right = False).astype(float)rfm['R是否大于均值'] = (rfm['R-SCORE'] > rfm['R-SCORE'].mean()) * 1rfm['F是否大于均值'] = (rfm['F-SCORE'] > rfm['F-SCORE'].mean()) * 1rfm['M是否大于均值'] = (rfm['M-SCORE'] > rfm['M-SCORE'].mean()) * 1rfm['人群数值'] = (rfm['R是否大于均值'] * 100) + (rfm['F是否大于均值'] * 10) + (rfm['M是否大于均值'] * 1)rfm['人群类型'] = rfm['人群数值'].apply(transform_label)count = rfm['人群类型'].value_counts().reset_index()count.columns = ['客户类型','人数']count['人数占比'] = count['人数'] / count['人数'].sum()rfm['购买总金额'] = rfm['F'] * rfm['M']mon = rfm.groupby('人群类型')['购买总金额'].sum().reset_index()mon.columns = ['客户类型','消费金额']mon['金额占比'] = mon['消费金额'] / mon['消费金额'].sum()result = pd.merge(count,mon,left_on = '客户类型',right_on = '客户类型')return result#判断R/F/M是否大于均值
def transform_label(x):if x == 111:label = '重要价值客户'elif x == 110:label = '消费潜力客户'elif x == 101:label = '频次深耕客户'elif x == 100:label = '新客户'elif x == 11:label = '重要价值流失预警客户'elif x == 10:label = '一般客户'elif x == 1:label = '高消费唤回客户'elif x == 0:label = '流失客户'return label

启动:

res = get_rfm(name = 'PYTHON-RFM实战数据.xlsx')
res

在这里插入图片描述
在这里插入图片描述

  • 客户流失情况严峻,高消费唤回客户、流失客户占比超过50%,怎么样制定针对性唤回策略迫在眉睫。

  • 重要价值客户占比仅2.97%,还有三个客户占比甚至不足2%,我们模型打分可能不够科学,可以进一步调整打分区间进行优化。

在这里插入图片描述

  • 高消费唤回客户人数占比28.87%,金额占比上升到了38.11%,这部分客户是消费的中流砥柱,他们为什么流失,应结合订单和购买行为数据进一步展开挖掘。

  • 频次深耕客户金额占比紧随其后,这部分客户的特征是近期有消费、消费频次低、消费金额高,和高消费唤回客户仅有购买时间上的不同,如何避免这部分客户向高消费唤回客户的流转是我们要思考的主要命题。

  • 流失客户人数占比26.28%,金额占比仅12.66%,这部分客户中有多少是褥羊毛用户,有多少是目标用户,对我们引流策略能够进行怎么样的指导和调整?

至此,我们基于订单源数据,按照五步法用Python完成了RFM模型的建立,并对结果进行了简单的分析。最后,只要把上述代码封装成函数,对于新的数据源,只要一个回车就能够撸出模型,So Easy!

参考

提取码:7kyt

这篇关于7. RFM用户分析模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/195668

相关文章

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

vue2实践:el-table实现由用户自己控制行数的动态表格

需求 项目中需要提供一个动态表单,如图: 当我点击添加时,便添加一行;点击右边的删除时,便删除这一行。 至少要有一行数据,但是没有上限。 思路 这种每一行的数据固定,但是不定行数的,很容易想到使用el-table来实现,它可以循环读取:data所绑定的数组,来生成行数据,不同的是: 1、table里面的每一个cell,需要放置一个input来支持用户编辑。 2、最后一列放置两个b

家庭和学生用户笔记本电脑配置方案

2.6.1  家庭和学生用户笔记本电脑配置方案   2.6.1  家庭和学生用户笔记本电脑配置方案   普通家庭用户、学生用户主要用于上网、娱乐、学习等,这类用户要求笔记本电脑的各方面 功能比较均衡。在选购此类笔记本电脑时,主要考虑外观设计方面要比较时尚,而且性能上也要 够强,一些大型复杂的软件以及目前的主流游戏都要能够流畅地运行才行。   对于CPU方面,可以考虑目前主流的第二

Ubuntu ftp搭建--配置不同用户不同权限

一、安装VSFTP sudo apt-get install vsftpd 二、添加FTP用户 sudo mkdir /etc/vsftpdsudo useradd -m -d /home/vsftpd vsftpd --用户名为vsftpd,目录和用户名可以自己更改sudo vi /etc/vsftpd/ftpuser.txt --这个到时与vsftp的配置文件对应建立一

利用PL/SQL工具如何给指定用户分配权限

选中指定的表--右键--编辑--就出现右边的内容了,选择权限,分配用户某个权限就行了;

配置JAVA环境的时候,环境变量中administrator的用户变量和系统变量的区别?

迁移项目到新的服务器上: 需要Java运行环境时,经常要配置环境变量,如图所示 这里有administrator的用户变量(U),和系统变量(S), 那么,它们之间有什么区别呢? 简单的说,一个是当前用户使用,你用其它用户登陆,这个环境变量就不起作用了。 系统变量,是对所有用户都可使用的。 简单的说: 系统变量:不管以哪个用户名登陆到计算机都能使

mysql用户管理 存储过程

1. 查看MySql的当前用户名 select user(); status;看看一下当前的一些状态 2.MYSQL中所有的用户名和其信息 mysql数据库的user表 3. grant 权限 on 应用范围(数据库表,方法等) to 用户(用@隔开,前面是用户名后面是主机名’ 用户名’@’主机名’) identified by 密码 require 要求什么的 with 对用

基于开源链动 2 + 1 模式、AI 智能名片与 S2B2C 商城小程序的用户忠诚度计划

摘要:本文深入探讨了在商业环境中执行用户忠诚度计划的创新途径。通过整合开源链动 2 + 1 模式、AI 智能名片以及 S2B2C 商城小程序等先进元素,从提供福利、解决问题和创造赚钱机会三个核心方面展开详细阐述。研究表明,这些新技术和新模式的有机结合,能够为企业打造更具吸引力和影响力的用户忠诚度计划,从而实现商业效益的最大化与可持续发展。 一、引言 在当今竞争激烈且市场环境快速变化的时代,

通过RTCPeerConnection接口来获取用户的IP地址

该方法在chrome78以上不再适用,想要获取真实IP可以通过后端获取,如果中间有nginx或者其他负载均衡会对真实IP隐藏的话,可以配置http的x-forwarded-for参数,具体请参考相关文章 RTCPeerConnection接口相当于一个由本地计算机到远端的WebRTC连接,接口提供了创建,保持,关闭连接的方法。 RTCPeerConnection.onicecandidat