数据分析实战项目3:RFM用户分群

news2025/6/9 17:25:45

目录

      • 1、RFM模型介绍
      • 2、Excel实际RFM划分案例
      • 3、RFM案例
        • 3.1 数据加载和基本信息查看
        • 3.2 数据预处理和RFM的初始值计算
        • 3.3 RFM区间和划分和分值计算
        • 3.4 RFM计算结果保存
          • 3.4.1 保存到excel
          • 3.4.2 保存到数据库
        • 3.5 RFM计算结果可视化
        • 3.6 结果分析(营销建议)
        • 3.7 案例注意点
      • 4、总结

1、RFM模型介绍

RFM客户价值模型详细介绍

  • R最近一次购买时间R(recenty)

  • 购买频率F(frequency)

  • 购买金额M(monetary)
    通过这三个维度来评估客户的订单活跃价值,用来做客户分群或价值区分
    在这里插入图片描述
    RFM模型基于一个固定的时间点做的分析
    RFM模型的实习过程:

  • 设置做计算的截止时间点

  • 以时间点为截止时间节点,向前推固定周期

  • 数据预计算,初始RFM:(最近的订单时间R,订单数量F,订单总金额M)

  • R,F,M区间分组。(F,M越大越好,R越小越好),得到一个分数值

  • 将三个维度值,组合或者相加得到总的RFM分
    R,M,F分别为2,3,1 则拼接RFM= 231 求和RFM=6

2、Excel实际RFM划分案例

在这里插入图片描述
在这里插入图片描述
RFM划分过程:
1)提取用户最近一次的交易时间,算出距离计算时间的差值
当前时间=TODAY()
在这里插入图片描述
2)计算最近一次交易时间距当前时间的间隔
时间间隔 = Days(后时间,前时间)
3)根据间隔天数长度赋予对应的R值
if(条件,满足条件师输出内容,不满足时输出内容)
在这里插入图片描述
4)从历史数据中提取所有用户的购买次数,根据次数多少赋予对应的F值
5)从历史数据中汇总,求得该用户的交易总额,根据金额大小赋予对应的M值
在这里插入图片描述
6)求出RFM的中值,例如中位数,用中值和用户的实际值进行比较,高于中值的为高,否则为低
在这里插入图片描述
7)在得到不同会员的RFM之后,根据步骤5产生的两种结果有两种应用思路
思路1:基于3个维度值做用户群体划分和解读,对用户的价值度做分析
思路2:基于RFM的汇总得分评估价值度
在这里插入图片描述
基于不同群体用户做不同的策略

RFM数值可以作为一些数据挖掘的输入信息

3、RFM案例

用户价值细分是了解用户价值度的重要途经,针对交易数据分析最主要用的就是RFM模型
一般对每个维度分三个划分,最多333=27种
在这里插入图片描述

数据sales.xlsx。密码gi7b
数据介绍:
在这里插入图片描述
在这里插入图片描述

3.1 数据加载和基本信息查看

import pandas as pd
import numpy as np
import time
import pymysql
from pyecharts.charts import Bar3D
#忽略警告
import warnings
warnings.filterwarnings('ignore')

数据是一个有五个sheet的excel表格
在这里插入图片描述
如何处理多sheet的excel表,导入python:

#加载数据
#数据是一个有五个sheet的excel表格
sheet_names = ['2015','2016','2017','2018','会员等级']
sheet_datas = [pd.read_excel('./data/sales.xlsx',sheet_name=i) for i in sheet_names]
#每个sheet数据都读出来放在列表中

#zip将两个列表的元素组合起来
for each_name,each_data in zip(sheet_names,sheet_datas):
	print('[data summary for ========{}=======]'.format(each_name)) #打印是哪个sheet,表名
	print('Overview:','\n',each_data.head(4))#打印前四行
	print('DESC:','\n',each_data.describe())#数据的描述性信息
	print('NA records',each_Data.isnull().any(axis=1).sum())#缺失值记录数
	print('Dtypes',each_data.dtypes)#数据类型

在这里插入图片描述
结论:日期列已经自动识别日期格式
订单金额的分布不均匀,有明显的极大值
有的表存在缺失值,但缺失量不大
等等

3.2 数据预处理和RFM的初始值计算

思路:缺失值异常值处理–添加每年的最大日期—四年数据拼接—增加间隔列和日期列—计算RFM各值

1)缺失值,异常值处理

for i,each_data in enumerate(sheet_datas[:]-1):#只要前四个表数据,会员等级那个不要
	#删除含有缺失值的行,这些行不多,而原数据大量--所以直接删
	each_data = each_data.dropna()#删除缺失行dropna
	#剔除订单金额小于1的数据,这些很可能是异常的
	sheet_data[i] =each_data[each_data['订单金额']>1]
	#添加提交订单日期最大值这一列,方便后面计算时间间隔
	sheet_datas[i]['max_year_data']= sheet_datas[i]['提交日期'].max()

sheet_datas[0] #先查看一下

在这里插入图片描述
2)数据拼接----pd.concat()
四年的数据合并一下,后面就不用再循环读取了

#将四年的数据合并一下,按行拼接
data_merge = pd.concat(sheet_datas[:-1])
data_merge

在这里插入图片描述
虽然把四年的数据合并在了一起,但是还是分年进行分析的

3)增加两列:
date_interval(当年中,此提交日期和最大的日期之间的差值),是当年的最后日期
year(年份)

#订单数据处理:增加两列date_interval、year
data_merge['date_interval'] = data_merge['max_year_date'] - date_merge['提交日期']
data_merge['year'] = date_merge['提交日期'].dt.year
date_merge.head()

在这里插入图片描述
在这里插入图片描述
此时,date_interval类型是两日期相减后的,我们想要改成数字类型

data_merge['date_intervl'] = data_merge['date_intervl'].dt.days
data_merge.info

在这里插入图片描述
此时改好了,

4)计算RFM数据
R:date_interval列分组后计算最小值
F:频率,按照年和会员id分组后,计数
M:按照年和会员id分组后,对订单金额求和
此时的数据:
在这里插入图片描述

data_merge.groupby(['year','会员ID']).agg(('date_interval':'min','订单号':'count','订单金额':'sum'))

在这里插入图片描述

data_merge.groupby(['year','会员ID'],as_index=False).agg(('date_interval':'min','订单号':'count','订单金额':'sum'))
#分组列不作为行标签:as_index=False

在这里插入图片描述

#修改列名
rfm_gb.columns = ['year','会员ID','r','f','m']
rfm_gb.head()

在这里插入图片描述

3.3 RFM区间和划分和分值计算

上面已经得到RFM具体值,但我们是需要划分区间,333个区间
如何定区间的边界值?
先看一下数值的统计值

em=fm_gb.iloc[:,2:].describe().T #T转置一下

在这里插入图片描述
可以划定的三个区间:最小值-1/4分位数,1/4分位数-3/4分位数,3/4分位数-最大值
和业务部门沟通确定,结合业务确定

#定义区间边界
r_bins = [-1,79,255,365]#左开右闭,所以边界小于最小值
f_bins = [0,2,5,130]
m_bins = [0,69,1199,206252]

下面用pd.cut进行分割

pd.cut(rfm_gb['r'],bins=r_bins)

在这里插入图片描述
进行了区间分割,并且打了分数:

rfm_gb['r_score'] = pd.cut(rfm_gb['r'],bins=r_bins,labels=[3,2,1])#给三个区间给定分数,1,2,3
rfm_gb['f_score'] = pd.cut(rfm_gb['f'],bins=f_bins,labels=[1,2,3])
rfm_gb['m_score'] = pd.cut(rfm_gb['m'],bins=m_bins,labels=[1,2,3])
rfm_gb

在这里插入图片描述

将RFM的值进行拼接

先将默认类型int,转化成str类型:

rfm_gb['r_score'] = rfm_gb['r_score'].astype(np.str)
rfm_gb['f_score'] = rfm_gb['f_score'].astype(np.str)
rfm_gb['m_score'] = rfm_gb['m_score'].astype(np.str)
rfm_gb.info()

进行拼接:输出212这种,增加一列
str.cat()

rfm_gb['rfm_group'] = rfm_gb['r_score'].str.cat(rfm_gb['f_score']).str.cat(rfm_gb['m_score'])
rfm_gb

在这里插入图片描述
有了上述数据,需要进行保存

3.4 RFM计算结果保存

3.4.1 保存到excel

to_excel

#保存到excel
rfm_gb.to_excel('./data/sales_rfm.xlsx')
3.4.2 保存到数据库

2.1 创建sale_rfm_score数据表
配置参数信息:
在这里插入图片描述
建表操作:
在这里插入图片描述
2.2 写入数据到sales_rfm_score数据表
在这里插入图片描述

3.5 RFM计算结果可视化

未来更好地了解各组RFM人数的变化,绘制3D柱形图
三个维度:年份、、

#汇总结果:统计不同不同年份的不同rfm分值的会员数量
display_data = rfm_gb.groupby(['rfm_group','year'],as_index=False)['会员ID'].count()
display_data['rfm_group'] = ['rfm_group','year','number']
display_data['rfm_group'].astype(np.int32)  #转化类型成int32
display_data.head()

在这里插入图片描述
数据拿到后,准备绘图:

from pyecharts.commons.utils import JsCode
from pyecharts import options as opts

range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf','#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
range_max = int(display_data['number'].max())

# 绘制 3D 图形
bar = Bar3D().add(
    series_name='',
    data=[d.tolist() for d in display_data.values],
    xaxis3d_opts=opts.Axis3DOpts(type_='category', name='分组名称'), 
    yaxis3d_opts=opts.Axis3DOpts(type_='category', name='年份'),
    zaxis3d_opts=opts.Axis3DOpts(type_='value', name='会员数量')
).set_global_opts(
    visualmap_opts=opts.VisualMapOpts(max_=range_max, range_color=range_color),
    title_opts=opts.TitleOpts(title="RFM分组结果")
)

#xaxis3d_opts是对x轴,visualmap_opts缩放条,图片也可以旋转
bar.render_notebook()

在这里插入图片描述
理解上面的作图代码:

[d.tolist() for d in display_data.values]
#将display_data中数值遍历,后放在list列表中

在这里插入图片描述

3.6 结果分析(营销建议)

根据上面的图,能发现2018年212群体的数量最多。
从2016到2017年用户群体数量变化不大,但到了2018年增长了近一倍,作为重点分析人群
除212外,312,213,211及112人群都在各个年份占据很大数量
有很大分组人数很少,甚至没有

根据用户的量级可以分成两类:
第一类:用户群体占比超过10%的群体
在这里插入图片描述
第二类:占比在个位数的群体(1%-10%)
在这里插入图片描述

第三类:占比非常少,但却非常重要的群体
在这里插入图片描述
企业可以针对3类群体,按照公司实际运营需求,制定针对不同群体的策略
录入数据库或者保存下来的数据,可以应用到其他模型当中去,成为模型输入的关键维度特征

3.7 案例注意点

1,不同品类、行业对于RFM的依赖度是有差异的,甚至不同阶段也有影响
例如:
大型家电消费周期长的企业,R和M更重要
快消等短而快的,更看重R和F

2,RFM的区间划分,需要结合业务情况

4、总结

  1. RFM模型是经典的一种用户分群方法,如果数据量不大,可以直接用excel实现
  2. RFM并非适用所有行业,多用于复购率较高的行业

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/334232.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[docker]笔记-基础配置

1、docker启动和设置开机启动 [rootlocalhost ~]# systemctl start docker [rootlocalhost ~]# systemctl enable docker 2、更换docker镜像网站,默认docker镜像网站是国外网站,下载镜像非常慢,需要更换为国内网站,以阿里云为例…

android多渠道打包(只编译一次)

众所周知,android 默认工具gradle可以配置多个productFlavors,以此实现配置多个不同版本,渠道的app应用,笔者认为这个编译速度很慢,于是乎有了今天的方案。希望能抛砖引玉为大家带来不一样的思路,废话不多说…

基于蜣螂算法改进的DELM预测-附代码

基于蜣螂算法改进的深度极限学习机DELM的回归预测 文章目录基于蜣螂算法改进的深度极限学习机DELM的回归预测1.ELM原理2.深度极限学习机(DELM)原理3.蜣螂算法4.蜣螂算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1…

QT基础入门【布局篇】消除控件之间的间隔

一、相关参数 layoutLeftMargin: layout内的布局距离边框左端的距离。 layoutTopMargin: layout内的布局距离边框顶端的距离。 layoutRightMargin: layout内的布局距离边框右端的距离。 layoutBottomMargin: layout内的布局距离边框底端的距离。 layoutHorizontalSpacing: layo…

【每日阅读】前端了解的HTTP协议知识(二)

HTTP 简介 HTTP 协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议; HTTP工作原理 HTTP协议工作于客户端-服务端架构上&#xf…

算法导论—近似算法

近似算法基础1. 近似算法的基本概念2. 近似算法的性能分析1. 近似算法的基本概念 很多实际应用问题都是NP-完全问题,这类问题很可能不存在多项式时间算法。一般而言,NP-完全问题可采用以下三种方式处理。 如果问题的输入规模较小,则可以利用…

利用IO工具包拷贝文件夹或者文件

引入依赖 <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version> </dependency> code 拷贝文件夹 PostMapping("/findB00List") CrossOrigin public Result …

(考研湖科大教书匠计算机网络)第三章数据链路层-第十节:以太网交换机的生成树协议STP

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;以太网故障导致的网络问题二&#xff1a;利用冗余链路提高稳定性&#xff08;1&#xff09;概述&#xff08;2&#xff09;冗余链路带来的问题三&a…

Swagger2 3.0的使用

前言 今天使用了以下swagger2 的3.0.0版本&#xff0c;好家伙&#xff0c;好多坑。在这里记录一下&#xff0c;方便查阅。 一、Swagger的简介 官网&#xff1a;https://swagger.io/ Swagger 是一个规范且完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的…

应用监控以及告警实现

前言 一个Java应用 可以不优秀&#xff0c;但是一定不能没有监控方案。否则极大影响排查线上问题的效 以及系统故障的及时告警 。试想 核心应用挂了一个 但是没有配置告警 理想情况几个小时 被自己人发现了 但是万一自己人也没看到或者没关注 那难道让服务一直挂下去么 &#…

Vue框架学习篇(五)

Vue框架学习篇(五) 1 组件 1.1 组件的基本使用 1.1.1 基本流程 a 引入外部vue组件必须要的js文件 <script src"../js/httpVueLoader.js"></script>b 创建.vue文件 <template><!--公共模板内容--></template><script><!…

LaoCat带你认识容器与镜像(实践篇二上)

实践篇主要以各容器的挂载和附加命令为主。 本章内容 本文实操全部基于Ubuntu 20.04 宿主机 > linux服务器本身 Docker > 20.10.22 在开始本章内容之前&#xff0c;我解答一个问题&#xff0c;有小伙伴问我说&#xff0c;有的容器DockerHub官网并没有提供任何可参考的文…

可信AI年度观察 | 智能语音产业需求不断升级,评测重点由技术转向产品

自《新一代人工智能发展规划》发布以来&#xff0c;人工智能发展已上升为国家战略&#xff0c;在“十四五”规划中&#xff0c;更是将人工智能列为科技前沿领域的“最高优先级”&#xff0c;国家政策支持为人工智能产业发展提供良好环境。同时&#xff0c;各行业逐渐重视改善价…

ChatGPT 支持的搜索引擎 Bing 究竟什么样?

微软于2月8日北京时间凌晨在 Redmond 线下举办一场媒体活动&#xff0c;围绕微软的产品以及 AI&#xff0c;公布最新消息。这里我们先回顾一下微软在 AI 上的布局。 2019年&#xff0c;微软向 OpenAI 投资10亿美元&#xff0c;成为了 OpenAI 紧密的合作伙伴&#xff0c;而微软…

Git学习笔记-详细使用教程

一、定义 Git&#xff08;读音为/gɪt/&#xff09;是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的。 二、Git与SVN的最主要的区别&#xff1f; SVN是集中式版本控制系统&#xff0c;版本库是集中放在中央服务器的&#xff0c;而干活的时…

分享:提升你工作幸福感的11个工具软件!

今天给大家分享11个非常好用的资源、工具网站。不论你是做运营、设计&#xff0c;还是个人生活中的应用&#xff0c;甚至只是提升你在线冲浪的快乐感&#xff0c;你都值得拥有它们。 1&#xff0c;在线一键抠图 https://www.remove.bg/ 免费的软件&#xff0c;自动抠图&…

【官方 | 计算机二级Python教程】第八章:Python计算生态

【官方 | 计算机二级Python教程】第八章&#xff1a;Python计算生态参考书目第八章&#xff1a;Python计算生态本章知识导图8.1 计算思维8.2 程序设计方法论8.3 计算生态与生态式编程8.4 基本的Python内置函数习题本文代码编译环境及版本更新日志参考书目 拜读的是计算机等级考…

mysql安装指定版本详细教程mysql 8.0.28示例

之前出过一版安装mysql5.7和安装mysql8.x最新版本的文档今天根据需求出一版指定版本的安装教程以8.0.28为例https://dev.mysql.com/downloads/mysql/ 下载mysql的官网下载好后上传到服务器安装时会报错公钥URL错误rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 …

Python中关于@修饰符、yeild关键词、next()函数的基本功能简述

关于修饰符&#xff1a;其实就是将修饰符下面的函数当成参数传给它上面的函数。 def a(x):print(a)adef b():print(b) 其效果等价为&#xff1a; def a(x):print(a)def b():print(b)a(b())有个记忆诀窍&#xff0c;的下面哪个函数最近&#xff0c;谁就是儿子&#xff0c;谁就…

Windows环境下使用MySQL:实现自动定时备份

一、编写备份脚本 1 2 3 4 5 6 7 8 9 rem auther:www.yumi-info.com rem date:20230209 rem ******MySQL backup start******** echo off forfiles /p "E:\mysql\MySQL BackUp" /m backup_*.sql -d -30 /c "cmd /c del /f path" set "Ymd%date:~0,4%…