Python之RFM建模分析

news/2024/10/23 11:25:35/

1、RFM模型的含义

  RFM模型是衡量客户价值和客户创利能力的重要工具和手段。在众多的客户关系管理(CRM)的分析模式中,RFM模型是被广泛提到的。
  该模型通过一个客户的近期购买行为®、购买的总体频率(F)以及花了多少钱(M)三项指标来描述该客户的价值状况,从而能够更加准确地将成本和精力更精确的花在用户层次身上,实现针对性的营销。
  详细来说,R指的是客户最后一次下单时间距离今天多少天了,该指标与客户的复购和流失直接相关。F指标指的是客户的下单频率,即客户在某个时间段内共消费了多少次,该指标用于衡量客户消费的活跃度。M指标指的是客户在该时间段内共消费了多少钱,该指标用于反应客户对于公司的贡献值。

在这里插入图片描述

2、RFM分析的前提条件

  • 最近有过交易行为的客户,再次发生交易行为的可能性高于最近没有交易行为的客户。
  • 交易频率高的客户,比交易频率低的客户,更有可能再次发生交易行为。
  • 过去所有交易总金额较大的客户,比过去所有交易总金额较小的客户,更有消费积极性。

3、原始数据

  本文数据集

RFM淘宝建模数据集免费版-机器学习文档类资源-CSDN下载

如果有需要的话,可以留言获取。如果觉得本文写的还不错,可以关注一下,获取更多精彩文章。
  原始数据集在这里先展示一下,让你对这个数据有一个主观印象。

在这里插入图片描述

4、数据处理

1)什么是R、F、M呢?

  • “R”表示最近一次消费时间距离今天共有多少天。什么是最近一次消费时间呢?如果同一个人在不同时间有不同多个订单,那么该时间距离当前时间的差值的最小值,就是最近一次消费时间。
  • “F”表示某个人一段时间内的消费频次。
  • “M”表示一段时间内的消费总额。
  • 在这里插入图片描述

 

 2)所有代码来了

from operator import index
from pickle import FALSE
from numpy import loadtxt
from numpy import sort
from matplotlib import pyplot
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt#熟悉数据
df = pd.read_excel(r'C:\Users\Administrator\Desktop\RFM.xlsx')
print(df.shape)
print(df.sample(5))print('-------------------------保留有效数据---------------------------------------------------------')
'''
针对此数据集,我们先说一下什么是“有效数据”。“有效数据”指的就是有效购买,也就是说对应的“订单状态”字段显示的是“交易成功”,对于“退款”的记录,我们就直接将这个数据剔除掉。
'''
#保留有效数据
print("剔除之前共有:"+ str(df.shape[0]) + "条记录")
df = df[df["订单状态"]=="交易成功"]
print("剔除之后共有:"+ str(df.shape[0]) + "条记录")print('----------------------------选取有效字段 ------------------------------------------------------')
'''
通过上面的分析,我们知道了“R”、“F”、“M”三个指标的概念。鉴于此,我们只需要选取"买家昵称",“付款时间”,"实付金额"这三个字段,用于RFM模型的构建,其余字段用处不大,因此删除其余字段。
'''
#选取有效字段 
df1 = df[["买家昵称","付款时间","实付金额"]]
df1.index = np.arange(df1.shape[0])
print(df1.shape)
print(df1.head())print('--------------------------缺失值处理--------------------------------------------------------')
#缺失值处理
df1.isnull().sum(axis=0)print('--------------------------计算RFM三个指标--------------------------------------------------------')
'''
针对上述“R”、“F”、“M”三个指标的概念,我们对数据做一定的处理。由于 “R”表示的是最近一次消费时间距离今天共有多少天。但是数据集中只有每一天的“付款时间”字段。因此计算RFM指标之前,需要事先添加一个“天数”字段,求出每个“付款时间”距今共有多少天。“天数”越小,就表示最近一次的消费时间。然后针对上述处理后的数据,做一个数据透视表。以“买家昵称”作为分组字段,对“天数”求最小值;对“付款昵称”计数;对“实付金额”求和,就可以得到我们想要的RFM三个指标。
'''#增加“天数”字段,用于计算“R”指标
df1["付款时间"] = pd.to_datetime(df1["付款时间"])
df1["天数"] = (pd.to_datetime("today")-df1["付款时间"]).dt.days
print(df1.sample(10))df2 = pd.pivot_table(df1,index="买家昵称",values=["买家昵称","天数","实付金额"],aggfunc={"买家昵称":"count","天数":"min","实付金额":"sum"})
df2 = df2[["天数","买家昵称","实付金额"]]
df2.columns = ["R","F","M"]
df2.reset_index()
print(df2.shape)
print(df2.head(10))print('-------------------------建立打分机制--------------------------------------------------------')
'''
通过上述分析,我们已经得到了每一个用户的“R”、“F”、“M”值。接下来要做的,就是给每一个用户进行分层。这里我们需要建立一个评判标准,由于RFM模型本身就是需要根据不同场景和业务需求来建立的,因此这个分层标准,也是需要我们沟通业务后,得到最后的分层标准。以R指标为例进行说明,根据上表我们知道,R表示每个用户最后一次购买时间距离今天共经历了多少天。当这个值越小,说明用户近期又回购了此产品;当这个值越大,说明用户已经好久没有再次购买产品了,这个用户很有可能流失掉了(猜测)。基于上述分析,我们采用通用的5分制打分法,对RFM进行分类打分。说明:由于这个数据集时间较早,因此计算出来的最近一次购买时间距离今天的天数,会特别大,但是没有关系,我们演示这个案例只是为了说明RFM模型的建模过程,实际中,肯定是过几个月进行一次RFM建模是比较好的,这里你只需要知道原理就好。对于R指标来说:我们可以求出,R指标最小值是660天,我们以30天作为时间间隔,660-690天,打5分;690-720,打4分;720-750打3分;750-780打2分;>780,打1分。对于F指标来说:我们可以求出,F指标最小值是1次,我们以1次作为时间间隔,0-2,打1分;2-3,打2分;3-4,打3分;4-5,打4分;>5,打5分。对于M指标来说:我们可以求出,M指标最小值是0.005元,我们以500元作为时间间隔,0-50,打1分;50-100,打2分;100-150,打3分;150-200,打4分;>200,打5分。至此,我们已经建立好了打分标准,下面我们开始对每个用户进行分类打分。
'''def func1(x):if x>=660 and x<690:return 5elif x>=690 and x<720:return 4elif x>=720 and x<750:return 3elif x>=750 and x<780:return 2elif x>=780:return 1def func2(x):if x>=0 and x<2:return 1elif x>=2 and x<3:return 2elif x>=3 and x<4:return 3elif x>=4 and x<5:return 4elif x>=5:return 5def func3(x):if x>=0 and x<50:return 1elif x>=50 and x<100:return 2elif x>=100 and x<150:return 3elif x>=150 and x<200:return 4elif x>=200:return 5df2["R-SCORE"] = df2["R"].apply(func1)
df2["F-SCORE"] = df2["F"].apply(func2)
df2["M-SCORE"] = df2["M"].apply(func3)
print(df2)
df2.sample(10)print('-------------------------用户贴标签--------------------------------------------------------')
'''
前面的步骤中,我们已经根据业务需求,对RFM指标进行了分类打分,得到了R-SCORE、F-SCORE、M-SCORE三个指标。接下来,我们需要给每个用户贴标签,这里有两种方式可以进行用户贴标签。第一种:根据业务场景和业务来分配全重,对于RFM这3个指标,你更看重哪个指标,就赋予它相应较大一点的权重,比如说赋予的权重是3:1:2。第二种:完全根据单独的RFM标签来计算,比如说:R-SCORE>avg(R-SCORE)、F-SCORE>avg(F-SCORE)、M-SCORE>avg(M-SCORE),表示一个客户近期有购买,购买频率高于所有客户平均购买频率,购买金额高于所有客户的平均购买金额,因此我们贴上一个“重要挽留客户”的标签。下面以第二种方法进行说明。根据上述叙述,每个指标有两种情况,要么>avg(),要么<avg()。由排列组合的知识,共有8种组合情况,当指标>avg(),我们记为1;当指标<avg(),我们记为0。因此可以得到如下的二维表格。
'''avg_r = df2["R-SCORE"].mean()
avg_f = df2["F-SCORE"].mean()
avg_m = df2["M-SCORE"].mean()
print(avg_r,avg_f,avg_m)def func1(x):if x>avg_r:return 1else:return 0def func2(x):if x>avg_f:return 1else:return 0def func3(x):if x>avg_m:return 1else:return 0df2["R-SCORE是否大于均值"] = df2["R-SCORE"].apply(func1)
df2["F-SCORE是否大于均值"] = df2["F-SCORE"].apply(func1)
df2["M-SCORE是否大于均值"] = df2["M-SCORE"].apply(func1)
print(df2.sample(10))def functions(x):if x.iloc[0]==1 and x.iloc[1]==1 and x.iloc[2]==1:return "重要价值客户"elif x.iloc[0]==1 and x.iloc[1]==1 and x.iloc[2]==0:return "潜力客户"elif x.iloc[0]==1 and x.iloc[1]==0 and x.iloc[2]==1:return "重要深耕客户"elif x.iloc[0]==1 and x.iloc[1]==0 and x.iloc[2]==0:return "新客户"elif x.iloc[0]==0 and x.iloc[1]==1 and x.iloc[2]==1:return "重要唤回客户"elif x.iloc[0]==0 and x.iloc[1]==1 and x.iloc[2]==0:return "一般客户"elif x.iloc[0]==0 and x.iloc[1]==0 and x.iloc[2]==1:return "重要挽回客户"elif x.iloc[0]==0 and x.iloc[1]==0 and x.iloc[2]==0:return "流失客户"
df2["标签"] = df2[["R-SCORE是否大于均值","F-SCORE是否大于均值","M-SCORE是否大于均值"]].apply(functions,axis=1)
df2.sample(10)
print(df2)print('-------------------------可视化展示--------------------------------------------------------')
print('-------------------------绘制不同类型客户的人数对比-----------------------------------------------------')
df3 = df2.groupby("标签", as_index=FALSE).agg({"标签":"count"}).rename(columns={'标签': '汇总数'})
df3["不同客户的占比"] = df3["汇总数"].apply(lambda x:x/np.sum(df3["汇总数"]))
print(df3)
df3 = df3.sort_values(by="汇总数",ascending=True)
plt.figure(figsize=(6,4),dpi=100)x = df3.index
y = df3["汇总数"]
plt.barh(x,height=0.5,width=y,align="center")
plt.title("不同类型客户的人数对比")
for x,y in enumerate(y):plt.text(y+450,x,y,ha="center",va="center",fontsize=14)
plt.xticks(np.arange(0,10001,2000))
plt.tight_layout()
plt.savefig("不同类型客户的人数对比",dpi=300)
plt.rcParams['font.sans-serif']=['SimHei']print('-------------------------绘制不同类型客户人数占比图--------------------------------------------------------')df3 = df3.sort_values(by="汇总数",ascending=True)plt.figure(figsize=(7,4),dpi=100)
x = df3["不同客户的占比"]# labels = ['潜力客户', '一般客户', '重要价值客户', '重要唤回客户', '重要深耕客户', '新客户', '重要挽回客户', '流失客户']
# colors = ['#9999ff','#ff9999','#7777aa','#2442aa','#dd5555','deeppink','yellowgreen','lightskyblue']
labels = ['一般客户',  '重要唤回客户',  '重要挽回客户', '流失客户']  #根据实际情况来
colors = ['#9999ff','#ff9999','#7777aa','#2442aa']
explode = [0,0,0,0]patches,l_text = plt.pie(x,labels=labels,colors=colors,explode=explode,startangle=90,counterclock=False)
for t in l_text:t.set_size(0)
plt.axis("equal")
plt.legend(loc=(0.001,0.001),frameon=False)plt.title("不同类型客户人数占比图")plt.savefig("不同类型客户人数占比图",dpi=300)print('-------------------------绘制不同类型客户累计消费金额-------------------------------------------------------')df3 = df2.groupby("标签").agg({"M":"sum"})
df3["M"] = df3["M"].apply(lambda x:round(x))
df3["不同客户的占比"] = df3["M"].apply(lambda x:x/np.sum(df3["M"]))
df3 = df3.sort_values(by="M",ascending=True)plt.figure(figsize=(6,4),dpi=100)
x = df3.index
y = df3["M"]plt.barh(x,height=0.5,width=y,align="center")
plt.title("不同类型客户累计消费金额")for x,y in enumerate(y):plt.text(y+45000,x,y,ha="center",va="center",fontsize=14)plt.xticks(np.arange(0,700001,100000))
plt.tight_layout()
plt.savefig("不同类型客户累计消费金额",dpi=300)print('-------------------------绘制不同类型客户金额占比图-------------------------------------------------------')plt.figure(figsize=(7,4),dpi=100)
x = df3["不同客户的占比"]# labels = ['潜力客户', '一般客户', '重要价值客户', '重要唤回客户', '重要深耕客户', '新客户', '重要挽回客户', '流失客户']
# colors = ['#9999ff','#ff9999','#7777aa','#2442aa','#dd5555','deeppink','yellowgreen','lightskyblue']# explode = [0,0,0,0,0,0,0,0]labels = ['一般客户',  '重要唤回客户',  '重要挽回客户', '流失客户']  #根据实际情况来
colors = ['#9999ff','#ff9999','#7777aa','#2442aa']
explode = [0,0,0,0]patches,l_text= plt.pie(x,labels=labels,colors=colors,explode=explode,startangle=90,counterclock=False)
for t in l_text:t.set_size(0)plt.axis("equal")
plt.legend(loc=(0.001,0.001),frameon=False)plt.title("不同类型客户金额占比图")plt.savefig("不同类型客户金额占比图",dpi=300)plt.show()


http://www.ppmy.cn/news/752176.html

相关文章

pandas基础数据结构

一、数据框计算 &#xff08;一&#xff09;基础运算函数 方法描述add加&#xff08;&#xff09;sub减&#xff08;-&#xff09;mul乘&#xff08;*&#xff09;div除&#xff08;/&#xff09;floordiv整除&#xff08;//&#xff09;pow幂次方&#xff08;**&#xff09;…

pandas数据处理

pandas在处理一维度数据和二维数据很是在行&#xff0c;在实际生产环境中应用十分广泛。我们直奔主题,本文主要讲解它的两个核心数据结构&#xff1a;Series 和 DataFrame。 一,Series (一维&#xff0c;带有标签的数组) ta是个定长的字典序列。说是定长是因为在存储的时候&am…

Sphinx 错误 ‘md‘ \u7684 source_parser \u5df2\u6ce8\u518c

今天用read the docs的时候出现了下面的错误&#xff1a; Extension error: md \u7684 source_parser \u5df2\u6ce8\u518c Command exited with exit code: 2 The server will continue serving the build folder, but the contents being served are no longer in sync with …

系统重温Pandas笔记:(六)连接

文章目录 写在前面一、关系型连接1. 连接的基本概念2. 值连接【练一练】 3. 索引连接 二、方向连接1. concat2. 序列与表的合并 三、类连接操作1. 比较2. 组合【练一练】【练一练】 四、练习Ex1&#xff1a;美国疫情数据集Ex2&#xff1a;实现join函数 写在前面 本文内容源自D…

Python科学计算:Pandas

Pandas简介 在数据分析工作中&#xff0c;Pandas 的使用频率是很高的&#xff0c;一方面是因为 Pandas 提供的基础数据结构 DataFrame 与 json 的契合度很高&#xff0c;转换起来就很方便。另一方面&#xff0c;如果我们日常的数据清理工作不是很复杂的话&#xff0c;你通常用…

【Python】【pandas】合并两个dataframe:df1和df2,保留df1和df2的所有列,按照df2的列排序在前,df1中未包含在df2的列在后

合并df1和df2时保留df1和df2的所有列&#xff0c;并且按照df2的列顺序排序&#xff0c;可以按照以下步骤进行操作&#xff1a; import pandas as pd# 示例数据 data1 {F: [1, 2, 3],A: [1, 2, 3],B: [4, 5, 6],E: [4, 5, 6]} df1 pd.DataFrame(data1)data2 {C: [7, 8, 9],A…

[ICCV2019]DF2Net: A Dense-Fine-Finer Network for Detailed 3D Face Reconstruction

标题&#xff1a;DF2Net: A Dense-Fine-Finer Network for Detailed 3D Face Reconstruction 链接&#xff1a;https://openaccess.thecvf.com/content_ICCV_2019/papers/Zeng_DF2Net_A_Dense-Fine-Finer_Network_for_Detailed_3D_Face_Reconstruction_ICCV_2019_paper.pdf 这…

论文阅读26 | DF2AM: Dual-level Feature Fusion and Affinity Modeling for RGB-Infrared reid

论文&#xff1a;DF2AM: Dual-level Feature Fusion and Affinity Modeling for RGB-Infrared Cross-modality Person Re-identification 创新点 本文的创新点在于&#xff0c;引入了局部特征分块加权求和再和全局特征相加计算损失&#xff1b;还有亲和力建模每个图像和该批所…