作者:黄伟呢

     来源:凹凸数据

大家好,我是黄同学

今天给大家分享的是如何用python实现RFM建模。

RFM模型的含义

  RFM模型是衡量客户价值和客户创利能力的重要工具和手段。在众多的客户关系管理(CRM)的分析模式中,RFM模型是被广泛提到的。

  该模型通过一个客户的近期购买行为(R)、购买的总体频率(F)以及花了多少钱(M)三项指标来描述该客户的价值状况,从而能够更加准确地将成本和精力更精确的花在用户层次身上,实现针对性的营销。

  详细来说,R指的是客户最后一次下单时间距离今天多少天了,该指标与客户的复购和流失直接相关。F指标指的是客户的下单频率,即客户在某个时间段内共消费了多少次,该指标用于衡量客户消费的活跃度。M指标指的是客户在该时间段内共消费了多少钱,该指标用于反应客户对于公司的贡献值。

RFM分析的前提条件:

  • 最近有过交易行为的客户,再次发生交易行为的可能性高于最近没有交易行为的客户。

  • 交易频率高的客户,比交易频率低的客户,更有可能再次发生交易行为。

  • 过去所有交易总金额较大的客户,比过去所有交易总金额较小的客户,更有消费积极性。

原始数据

  原始数据集在这里先展示一下,让你对这个数据有一个主观印象。

(点击放大)

数据处理

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

“R”表示最近一次消费时间距离今天共有多少天。什么是最近一次消费时间呢?如果同一个人在不同时间有不同多个订单,那么该时间距离当前时间的差值的最小值,就是最近一次消费时间。

“F”表示某个人一段时间内的消费频次。

“M”表示一段时间内的消费总额。

2)熟悉数据集

  熟悉数据集,就是在进行数据处理之前,应该先熟悉数据,只有对数据充分熟悉之后,才能更好的进行分析。

熟悉数据常用的方法和属性有shape、head()、tail()、sample()、info()、describe()。

df = pd.read_excel(r"C:\Users\黄伟\Desktop\RFM_Model\RFM.xlsx")
display(df.shape)
display(df.sample(5))

结果如下:

从上述结果中可以发现:这笔数据总共有28833行条记录,12列。观察上图,可以清楚地看到每一列数据代表什么含义。

3)保留有效数据

  针对此数据集,我们先说一下什么是“有效数据”。“有效数据”指的就是有效购买,也就是说对应的“订单状态”字段显示的是“交易成功”,对于“退款”的记录,我们就直接将这个数据剔除掉。

display("剔除之前共有:"+ str(df.shape[0]) + "条记录")
df = df[df["订单状态"]=="交易成功"]
display("剔除之后共有:"+ str(df.shape[0]) + "条记录")

结果如下:

4)选取有效字段

  通过上面的分析,我们知道了“R”、“F”、“M”三个指标的概念。鉴于此,我们只需要选取"买家昵称",“付款时间”,"实付金额"这三个字段,用于RFM模型的构建,其余字段用处不大,因此删除其余字段。

df1 = df[["买家昵称","付款时间","实付金额"]]
df1.index = np.arange(df1.shape[0])
display(df1.shape)
display(df1.head())

结果如下:

5)缺失值处理

df1.isnull().sum(axis=0)

结果如下:

从上述结果中可以发现:各字段中没有缺失值,因此不需要做任何处理。

RFM建模过程

1)计算RFM三个指标

① 增加“天数”字段,用于计算“R”指标

  针对上述“R”、“F”、“M”三个指标的概念,我们对数据做一定的处理。由于 “R”表示的是最近一次消费时间距离今天共有多少天。但是数据集中只有每一天的“付款时间”字段。因此计算RFM指标之前,需要事先添加一个“天数”字段,求出每个“付款时间”距今共有多少天。“天数”越小,就表示最近一次的消费时间。

  然后针对上述处理后的数据,做一个数据透视表。以“买家昵称”作为分组字段,对“天数”求最小值;对“付款昵称”计数;对“实付金额”求和,就可以得到我们想要的RFM三个指标。

df1["付款时间"] = pd.to_datetime(df1["付款时间"])
df1["天数"] = (pd.to_datetime("today")-df1["付款时间"]).dt.days
display(df1.sample(10))

结果如下:

② 计算RFM三个指标

df2 = pd.pivot_table(df1,index="买家昵称",values=["买家昵称","天数","实付金额"],aggfunc={"买家昵称":"count","天数":"min","实付金额":"sum"})
df2 = df2[["天数","买家昵称","实付金额"]]
df2.columns = ["R","F","M"]
df2.reset_index()
display(df2.shape)
display(df2.head(10))

结果如下:

2)用户分层打分

  通过上述分析,我们已经得到了每一个用户的“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)
df2.sample(10)

结果如下:

3)用户贴标签

  前面的步骤中,我们已经根据业务需求,对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()
display(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)
display(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)

结果如下:

4)可视化展示

① 绘制不同类型客户的人数对比

df3 = df2.groupby("标签").agg({"标签":"count"})
df3["不同客户的占比"] = df3["标签"].apply(lambda x:x/np.sum(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)

结果如下:

② 绘制不同类型客户人数占比图

df3 = df2.groupby("标签").agg({"标签":"count"})
df3["不同客户的占比"] = df3["标签"].apply(lambda x:x/np.sum(df3["标签"]))
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']explode = [0,0,0,0,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)

结果如下:

③ 绘制不同类型客户累计消费金额

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)

结果如下:

④ 绘制不同类型客户金额占比图

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=(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]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)

结果如下:

结论

  ① 通过上面的可视化展示可以发现,重要挽回客户7102人,虽然只占总人数的28%,但是他们的累计消费金额却是最高的,达到了639763元。重要挽回客户指的是“做出最大购买,但很久没有回来购买”,这一部分人已经濒临流失边缘,极大可能会流失,但是这一部分人对于公司的实际贡献来说,具有很大价值。因此可以采取重点联系或拜访的形式,调查回购率低的原因,从而提高留存率。

  ② 通过上面的可视化展示可以发现,新客户5002人,也占总人数的20%,他们的累计消费金额也达到了134085元。这一部分人最近有交易,交易频率不高,金额小,很容易丢失,但是有推广价值。针对这一部分群体,我们可以采取社区活动这种形式,提供免费试用产品,提高客户兴趣,对于创建品牌知名度很有必要。

  ③ 通过上面的可视化展示可以发现,流失客户8601人,具有最大占比34%,他们的累计消费金额也达到了200854元。流失客户表示最后一次购买的时间很长,金额小,订单数少,属于冬眠客户。针对上面的新客户和这里的流失客户的处理有两种办法,如果说这部分人的消费金额较大,对公司的价值较大,就需要想办法恢复这部分客户的兴趣;如果说这部分人的消费金额较小,暂时放弃无价值用户,主要将运营的中心放在如何留住核心收入来源的客户群体之上,以及通过各种方式召回“重要挽回客户”。

◆ ◆ ◆  ◆ ◆

长按二维码关注我们


数据森麟公众号的交流群已经建立,许多小伙伴已经加入其中,感谢大家的支持。大家可以在群里交流关于数据分析&数据挖掘的相关内容,还没有加入的小伙伴可以扫描下方管理员二维码,进群前一定要关注公众号奥,关注后让管理员帮忙拉进群,期待大家的加入。

管理员二维码:

猜你喜欢

● 笑死人不偿命的知乎沙雕问题排行榜

● 用Python扒出B站那些“惊为天人”的阿婆主!

● 互联网大佬学历&背景大揭秘,看看是你的老乡还是校友

● 上万条数据撕开微博热搜的真相!

● 你相信逛B站也能学编程吗?

用python轻松实现数据分析中的RFM建模相关推荐

  1. python在大数据分析中的应用

    每个人都喜欢Python,如果您打算开始从事数据科学事业,我们可以肯定Python在您心中已经占有特殊的位置.它直观且易于在任何平台上运行,并且具有大量令人惊叹的库和工具.与其他编程语言相比,Pyth ...

  2. 使用Python轻松识别音频中文字(Whisper)

    使用Python轻松识别音频中文字 一.前言 在开会或是讨论问题的时候,我们总有一些内容需要记录下来.但由于各种原因,我们无法做到全面细致的记录.事后我们可能需要补充这些细节性内容,而回放视频或是录音 ...

  3. 三种方法,用Python轻松提取PDF中的全部图片

    作者 | 陈熹.刘早起 来源 | 早起Python 头图 | 下载于视觉中国 有时我们需要将一份或者多份PDF文件中的图片提取出来,如果采取在线的网站实现的话又担心图片泄漏,手动操作又觉得麻烦,其实用 ...

  4. 三种方法,Python轻松提取PDF中全部图片

    有时我们需要将一份或者多份PDF文件中的图片提取出来,如果采取在线的网站实现的话又担心图片泄漏,手动操作又觉得麻烦,其实用Python也可以轻松搞定! 今天就跟大家系统分享几种Python提取 PDF ...

  5. python调用simulink_使用Python从dbc文件中提取simulink建模数据定义

    使用dbc文件建模完成CAN通讯是一种比较高效的开发模式,不过在建模的过程中dbc文件中描述的数据需要自己去定义.使用文本编辑工具打开dbc文件可以看到,实际上dbc文件是一个可以进行语义解析的文本. ...

  6. 用Python轻松搞定Excel中的20个常用操作

    来源 |早起Python(ID: zaoqi-python) Excel与Python都是数据分析中常用的工具,本文将使用动态图(Excel)+代码(Python)的方式来演示这两种工具是如何实现数据 ...

  7. 用 Python 轻松搞定 Excel 中的 20 个常用操作

    来源 |早起Python(ID: zaoqi-python) Excel与Python都是数据分析中常用的工具,本文将使用动态图(Excel)+代码(Python)的方式来演示这两种工具是如何实现数据 ...

  8. c#读取excel两列数据并绘制xy曲线_用Python轻松搞定Excel中的20个常用操作

    来源 |早起Python(ID: zaoqi-python) Excel与Python都是数据分析中常用的工具,本文将使用动态图(Excel)+代码(Python)的方式来演示这两种工具是如何实现数据 ...

  9. python计算消费总额_Python在校园数据分析中的应用——以一卡通消费为例

    Python 在校园数据分析中的应用--以一卡通消费为例 王全胜 [期刊名称] <电脑知识与技术> [年 ( 卷 ), 期] 2017(013)009 [摘要] 随着大数据时代的到来 ,P ...

最新文章

  1. linux将字符串转小写_Python教程第10讲:字符串的使用
  2. 我用ASP.NET缓存之OutputCache
  3. TComboBox下拉取值
  4. 重磅发布|新一代云原生数据仓库AnalyticDB「SQL智能诊断」功能详解
  5. Linux系统磁状态检测,检测Linux硬件状态
  6. python第二十八课——编码小常识
  7. 可能是最强大的【CSS】动画库
  8. php 判断用户是否刷新,ajax php 实现无刷新用户检查是否存在
  9. 李氏第二法分析稳定性matlab,9-4李雅普诺夫稳定性分析2010.ppt
  10. python信息安全书籍_2018年信息安全从业者书单推荐
  11. apple苹果IOS内购申请教程协议、税务和银行业务配置
  12. linux系统设置成中文语言
  13. HTML网页设计:二、网页的基本标签
  14. VS创建和使用C++动态链接库教程
  15. STM32F103 用CS1237 /HX711 芯片制作电子秤
  16. 如何设置快速启动栏 win7 快速启动栏 快速启动栏不见了
  17. 国际象棋棋盘 java_java绘制国际象棋与中国象棋棋盘
  18. 软件项目量化管理目标举例
  19. python copy.deepcopy()深入解读
  20. Manjaro 系统日常使用入门导引

热门文章

  1. oracle bpm 表单,Oracle BPM 安全认证
  2. BPM软件是什么?BPM软件跟BPA有关联吗?
  3. c语言联机游戏,C/C++ 游戏 贪吃蛇双人对战版
  4. 小学生五星分期,钉钉在线求饶
  5. Python核心编程(第3版)第2章网络编程中关于tcp/udp服务器和客户端实现代码的运行出错的修正
  6. 自动矢量化编译优化技术(Automatic Vectorization)
  7. Hive 高级篇(调优)
  8. python 混合整数规划_混合整数规划仓库位置(Python+GLPK)
  9. 关于js阻止冒泡时的一些坑
  10. python中 什么意思_请问python中%代表什么意思?