R语言 RFM分析

article/2025/10/2 15:49:05

目录

一、RFM分析的定义:

二、RFM分析的假设

三、RFM分析的步骤

四、RMF分析实例

4.1 数据准备

4.2 计算R/F/M

4.3 将R、F、M分组打分赋值

4.4 计算RFM综合分值

4.5 客户分类

4.6 完整代码


注:个人学习笔记--谁说菜鸟不会数据分析 R语言篇

一、RFM分析的定义:

RFM分析,是指根据客户活跃程度和交易金额贡献进行客户价值细分的一种客户细分方法。RFM分析主要由3个指标组成,分别为R(Recency,近度)F(Frequency频度)M(Monetary,额度)组成

指标解释意义
R(Recency,近度)客户最近一次交易时间到当前时间的间隔

R越大,表示客户越久为发生交易

R越小,表示客户越近有交易发生

F(Frequency,频度)客户在最近一段时间内交易的次数

F越大,表示客户交易越频繁

F越小,表示客户交易越少

M(Monetary,额度)客户在最近一段时间内交易的金额

M越大,表示客户价值越高

M越小,表示客户价值越低

依据如上三项指标,划分为6,8,11等几种模型。最常见的为8种:

 二、RFM分析的假设

1、假设最近有过交易行为的客户比最近没有交易行为的客户,更有可能再次发生交易行为。

2、假设交易频率较高的客户比交易频率较低的客户,更有可能中再次发生交易行为。

3、假设过去所有交易总金额更多的客户比交易总金额较少的客户,更有消费积极性。

三、RFM分析的步骤

RFM分析,我的理解就是根据用户的行为,从三个层次角度分被构建指标,分别打分,然后计算RFM综合分值,最后将客户进行分类,最后对不同的客户采用不同的营销手段,实现留存高价值客户、发展重点发展客户,挖掘潜在客户的目的。

因此,RFM分析可以分为如下五个步骤:

1.数据准备

2.计算R、F、M

3.将R、F、M分组打分赋值

4.计算RFM综合分值

5.客户分类

四、RMF分析实例

4.1 数据准备

data = read.csv('C:/Users/ABC/Desktop/书籍源代码和配套资源/谁说菜鸟不会数据分析(R语言篇)--数据/第五章/5.7 RFM分析/RFM分析.csv',fileEncoding="utf8",stringsAsFactors=FALSE)

 数据第一列为OrderID(订单ID)、第二列为CustomerID(客户ID)、第三列DealDataTime(交易日期)第四列为Sales(交易金额)

由于交易日期不利于数据之间的对比,这就需要我们根据交易日期计算出交易日期距当前日期的间隔天数,主要分为如下四个步骤:

1.将日期处理为时间型

2.将当前日期与交易日期相减得到交易日期距离当前日期的时间差

3.使用as.numeric函数将时间

差转换为以日为单位的数值

4.使用floor函数将数据向下取整得到天数。

#1.数据准备#将时间处理为时间型
data$DealDateTime = strptime(data$DealDateTime, format ='%Y-%m-%d')
#求交易日期至当前日期的时间差
data$DateDiff = Sys.time() - data$DealDateTime
#根据时间差获取天数
data$DateDiff = floor(as.numeric(data$DateDiff, units = "days"))

4.2计算R/F/M

R:使用CustomerID作为分组列,最近一次交易日期距离当前日期的间隔天数Days作为统计列,统计函数使用最小值函数min

 F:使用CustomerID作为分组列,OrderID作为统计列,统计函数使用计数函数length

M:使用CustomerID作为分组列,Sales作为统计列,统计函数使用求和函数sum

如下:

#2.计算R、F、M
#统计每个客户的最近一次交易日期距离当前日期的间隔天数,即找出最近消费距离
R = tapply(data$DateDiff, data$CustomerID, min)
#统计每个客户交易的总次数,即对订单计数
F = tapply(data$OrderID, data$CustomerID, length)
#统计每个客户交易的总额,即对每次的交易金额求和
M = tapply(data$Sales, data$CustomerID, sum)
#查看变量
View(R)
View(F)
View(M)
#将R、F、M合并成一个数据框
#使用row.names函数获取R向量的索引以生成CustomerID列
RFMData = data.frame('CustomerID' = row.names(R), 'R' = R, 'F' = F, 'M' = M)

4.3 将R、F、M分组打分赋值

 如果没有特别的分组标准,通常按照平均值划分为两个组,并分别赋值1,2

定义

说明

取值

说明

R_score

近度得分,最近一次交易日期距离指定日期越近,R_score越大

2

R<=平均值

1

R>=平均值

F_score

频度得分,交易频率越高,F_score越大

2

F>=平均值

1

F<=平均值

M_score

额度得分,交易金额越高,M_score越大

2

M>=平均值

1

M<=平均值

#3.将R、F、M合并为一个数据框
#判断R列是否大于或等于自身的平均值,将符合条件的位置赋值为1,否则赋值为2
RFMData$R_score = ifelse(RFMData$R >= mean(RFMData$R), 1, 2)
#赋值方法同上,对F_score,M_score进行赋值,但与R相反
RFMData$F_score = ifelse(RFMData$F >= mean(RFMData$F), 2, 1)
RFMData$M_score = ifelse(RFMData$M >= mean(RFMData$M), 2, 1)

4.4计算RFM综合分值

在得到R_score、F_score、M_score的分组分值后,就可以计算RFM综合分值了,RFM综合分值计算公式为

RFM = 100×R_score + 10×F_score + 1×M_score

这样设置的原因是用百十个位的组合,构造一个RFM分值。

#4.计算RFM综合分值
RFMData$RFM = 100*RFMData$R_score + 10*RFMData$F_score + 1*RFMData$M_score

 

4.5客户分类

本例采用与RFM综合分值和客户类型的对应关系表进行匹配合并的方式实现客户分类。

首先将各个RFM综合分值和客户类型的对应关系定义为一个数据框。然后使用merge函数的内连接方法,将RFMData数据框与港定义的RFM综合分值和客户类型的对应关系表,根据管理案例额名RFM匹配合并为一个数据框,这样就完成了客户分类的操作。

#5.客户分类
#定义RFM综合分值和客户类型的对应关系表
CustomerType = data.frame('RFM' = c(111, 112, 121, 122, 211, 212, 221, 222),'Type' = c('潜在客户', '重点挽留客户', '一般保持客户','重点保持客户', '一般发展客户', '重点发展客户', '一般价值客户', '高价值客户')
)
#将RFMData与RFM综合分值和客户类型的对应关系表合并为一个数据框
RFMData = merge(RFMData, CustomerType)

最后统计各个类型的客户数量

#按Type进行分组,统计各个类型的客户数量
count = tapply(RFMData$CustomerID, RFMData$Type, length)
View(count)
CustomerTypeSum = data.frame('数量' = count)
View(CustomerTypeSum)

4.6 完整代码

#R语言 - RFM分析
data = read.csv('C:/Users/ABC/Desktop/书籍源代码和配套资源/谁说菜鸟不会数据分析(R语言篇)--数据/第五章/5.7 RFM分析/RFM分析.csv',fileEncoding="utf8",stringsAsFactors=FALSE)
#1.数据准备#1.将时间处理为实践型
data$DealDateTime = strptime(data$DealDateTime, format ='%Y-%m-%d')
#求交易日期至当前日期的时间差
data$DateDiff = Sys.time() - data$DealDateTime
#根据时间差获取天数
data$DateDiff = floor(as.numeric(data$DateDiff, units = "days"))#2.计算R、F、M
#统计每个客户的最近一次交易日期距离当前日期的间隔天数,即找出最近消费距离
R = tapply(data$DateDiff, data$CustomerID, min)
#统计每个客户交易的总次数,即对订单计数
F = tapply(data$OrderID, data$CustomerID, length)
#统计每个客户交易的总额,即对每次的交易金额求和
M = tapply(data$Sales, data$CustomerID, sum)
#查看变量
View(R)
View(F)
View(M)
#将R、F、M合并成一个数据框
#使用row.names函数获取R向量的索引以生成CustomerID列
RFMData = data.frame('CustomerID' = row.names(R), 'R' = R, 'F' = F, 'M' = M)#3.将R、F、M合并为一个数据框
#判断R列是否大于或等于自身的平均值,将符合条件的位置赋值为1,否则赋值为2
RFMData$R_score = ifelse(RFMData$R >= mean(RFMData$R), 1, 2)
#赋值方法同上,对F_score,M_score进行赋值,但与R相反
RFMData$F_score = ifelse(RFMData$F >= mean(RFMData$F), 2, 1)
RFMData$M_score = ifelse(RFMData$M >= mean(RFMData$M), 2, 1)#4.计算RFM综合分值
RFMData$RFM = 100*RFMData$R_score + 10*RFMData$F_score + 1*RFMData$M_score#5.客户分类
#定义RFM综合分值和客户类型的对应关系表
CustomerType = data.frame('RFM' = c(111, 112, 121, 122, 211, 212, 221, 222),'Type' = c('潜在客户', '重点挽留客户', '一般保持客户','重点保持客户', '一般发展客户', '重点发展客户', '一般价值客户', '高价值客户')
)
#将RFMData与RFM综合分值和客户类型的对应关系表合并为一个数据框
RFMData = merge(RFMData, CustomerType)
#按Type进行分组,统计各个类型的客户数量
count = tapply(RFMData$CustomerID, RFMData$Type, length)
View(count)
CustomerTypeSum = data.frame('数量' = count)
View(CustomerTypeSum)


http://chatgpt.dhexx.cn/article/SyJ30gIQ.shtml

相关文章

[数据分析] RFM分析方法

美图欣赏2022/06/08 RFM分析方法 作用:对用户分类&#xff0c;识别出有价值的用户&#xff0c;对不同价值的用户使用不同的运营决策&#xff0c;把公司有限的资源发挥到最大的效果(用于用户价值细分&#xff0c;精细化运营) RFM是3个指标的缩写:最近1次消费时间间隔(Recency)…

深入解读RFM模型-实战应用干货

今天想先谈谈传统企业和电商谈的较多的RFM模型&#xff0c;在众多的客户细分模型中&#xff0c;RFM模型是被广泛提到和使用的。 一、RFM模型概述 RFM模型是网点衡量当前用户价值和客户潜在价值的重要工具和手段。RFM是Rencency&#xff08;最近一次消费&#xff09;&#xff…

如何进行有效的RFM模型搭建和分析?

“ RFM分析&#xff0c;是用户精细化运营中比较常见的分析方法了。” 今天和大家分享一篇历史文章&#xff0c;内容做了微调。是数据分析中比较常用的一个分析框架&#xff1a;RFM分析。该模型用的很多&#xff0c;说明有模型自身的优势&#xff1b;但同时也存在很多的问题。今…

概念+实战讲解,一文带你了解RFM模型【kaggle项目实战分享】数据分析

大家早上好&#xff0c;本人姓吴&#xff0c;如果觉得文章写得还行的话也可以叫我吴老师。欢迎大家跟我一起走进数据分析的世界&#xff0c;一起学习&#xff01; 感兴趣的朋友可以关注我或者我的数据分析专栏&#xff0c;里面有许多优质的文章跟大家分享哦。 &#xff08;有需…

三线性插值(三维线性插值)

三线性插值&#xff08;trilinear interpolation&#xff09;主要是用于在一个3D的立方体中&#xff0c;通过给定顶点的数值然后计算立方体中其他点的数值的线性插值方法。 具体推导过程见参考资料1&#xff0c;这里直接给出最终公式&#xff1a; 其中&#xff0c;坐标(x,y,z…

快速三线性插值

转载自https://lianera.github.io/post/2018/fast-trilinear-interpolation/ 快速三线性插值 最近需要对一个体素进行插值&#xff0c;并且应用到一张大图像上。这个本来用三线性插值很容易就实现了&#xff0c;但是体素的尺寸很小&#xff0c;长宽高大概20x15x10的大小&#x…

线性插值、双线性插值、双三次插值学习笔记-图像处理

缺失值之线性插值 interpolate用法 在series中有两个空值 用图的方式表示出四个点 使用线性插值后的结果如下 使用代码演示 线性插值后的结果 再加入一条数据 结果如下 使用pandas中的DataFrame 运行结果&#xff0c;默认在垂直方向上使用线性插值 设置水平方向上的线性插值 …

插值(Interpolation)

前言 插值计算普遍存在于图像处理中,最近在做畸变优化时,看了一些资料中提到了插值&双线性插值,开始没明白,觉得一定很难,直接跳过,到最终写代码时,又不得不使用.于是就这里对这个功能进行学习,记录,并使用vs2017进行实际验证,验证后发现这个原理其实并不复杂. 插值 插值…

三点线性插值

问题&#xff1a; 在三角形的三个顶点具有3个不同颜色&#xff0c;如何通过插值计算出三角形中每个点的颜色&#xff1f; 应用实例&#xff1a;高洛德着色使用3个顶点的颜色进行线性插值&#xff0c;结果如下图&#xff1a; 解决方案&#xff1a; 显然&#xff0c;无论是线性…

线性插值和双线性插值

最近在学数字图像处理中旋转变换的问题,发现旋转以后图片有一些不连续点,于是试着用双线性插值法进行解决。下面就介绍下插值的原理: 线性插值 如果你只处理分离的数据、想知道分离点之间的某些值,需要用到某种类型的插值。这种情况如图5-17坐标所示。对某些分离的(整数)…

没想到会用到:线性插值(Linear Interpolation)原理及使用

各位博友们大家好&#xff0c;小弟遇到一些问题经常会去看大家的博客&#xff0c;所以也想加入大伙的阵营&#xff0c;每每看到一些好的东西&#xff0c;有些心得体会什么的也想与大伙分享。 1.关于插值 插值&#xff0c;它根据已知的数据序列&#xff08;也可以理解为坐标中一…

线性插值 多项式插值 样条插值 牛顿插值总结

项目github地址&#xff1a;bitcarmanlee easy-algorithm-interview-and-practice 欢迎大家star&#xff0c;留言&#xff0c;一起学习进步 1.什么是插值 在数值分析中&#xff0c;插值(interpolation)是一种通过已知的、离散的数据点&#xff0c;在范围内推求新数据点的过程…

常用线性插值的介绍和应用(双线性插值,三线性插值,平滑曲线插值)

常用线性插值的介绍和应用 线性插值 插值是计算机图形学中非常常用的技术。通常&#xff0c;数据是在常规网格上指定的&#xff08;值写在2D或3D网格的顶点位置&#xff09;或在线上&#xff08;在一维的情况下&#xff09;&#xff0c;但是程序需要在该网格上的随机位置求值。…

线性插值 np.interp()

线性插值是指插值函数为一次多项式的插值方式&#xff0c;其在插值节点上的插值误差为零。线性插值相比其他插值方式&#xff0c;如抛物线插值&#xff0c;具有简单、方便的特点。线性插值的几何意义即为概述图中利用过A点和B点的直线来近似表示原函数。 线性插值法是认为现象…

我与插值萍水相逢:线性插值(Linear Interpolation)原理及使用

各位博友们大家好&#xff0c;小弟遇到一些问题经常会去看大家的博客&#xff0c;所以也想加入大伙的阵营&#xff0c;每每看到一些好的东西&#xff0c;有些心得体会什么的也想与大伙分享。 1.关于插值 插值&#xff0c;它根据已知的数据序列&#xff08;也可以理解为坐标中一…

对线性插值的理解

【插值】 插值是用已知点求未知点的一种方法&#xff0c;而且通常是用两个已知点求一个未知点。&#xff08;如果是用很多已知点求未知点一般用曲线拟合&#xff09; 既然是用两个已知点求一个未知点&#xff0c;那么两个已知点之间的距离要尽可能的小&#xff0c;这样求出来…

python判断是否为数字类型_python判断字符串是否为数字

以下实例通过创建自定义函数 is_number() 方法来判断字符串是否为数字:# -*- coding: UTF-8 -*- # Filename : test.py # author by : www.runoob.com def is_number(s): try: float(s) return True except ValueError: pass try: import unicodedata unicodedata.…

使用正则表达式判断字符串是否为数字类型

java 判断字符串是否是数字 1.用JAVA自带的函数 publicstaticbooleanisNumeric(Stringstr){ for(inti0;i System.out.println(str.charAt(i)); if(!Character.isDigit(str.charAt(i))){ returnfalse; returntrue; 2.用正则表达式 首先要importjava.util.regex.Pattern和java.ut…

java判断字符串是否为数字

一&#xff1a;判断java中的字符串是否为数字&#xff0c;可以通过正则表达式来判断&#xff1b;其判断逻辑如下&#xff1a; 1、根据阿里巴巴代码规范&#xff0c;将Pattern设置为全局常量&#xff0c;通过 -?[0-9](\\\\.[0-9])? 进行匹配是否为数字 private static final P…