IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Task02 会员RFM模型的学习和运用 -> 正文阅读

[Python知识库]Task02 会员RFM模型的学习和运用

前言

配合 Task01,数据的百度云盘的链接在里面,完整代码的见本文末尾链接

1 RFM模型介绍

???????RFM模型是衡量客户价值和客户创利能力的重要工具和手段。在众多的客户关系管理(CRM)的分析模式中,RFM模型是被广泛提到的。该机械模型通过一个客户的近期购买行为、购买的总体频率以及花了多少钱3项指标来描述该客户的价值状况。<百度百科>
最近一次消费 (Recency)
消费频率 (Frequency)
消费金额 (Monetary)

2 代码实践

(1) 导入库

import numpy as np 
import pandas as pd 
import time

# 引入机器学习包sklearn
from sklearn.ensemble import RandomForestClassifier

这里用到4个库:time、numpy、pandas、sklearn

  • time:用来记录插入数据库时的当前日期
  • numpy:用来做基本数据处理等
  • pandas:有关日期转换、数据格式化处理、主要RFM计算过程等
  • sklearn:使用其中的随机森林库

(2) 读取数据

# 创建sheet-names列表,与表格数据相对应
sheet_names = ['2015','2016','2017','2018','会员等级']
# 利用pandas库中的read_excel()函数,根据每一列的sheet_names,从一行到最后一行依次读取每一行的数
sheet_datas = [pd.read_excel('./data/sales.xlsx',sheet_name=i) for i in sheet_names]

先定义一个列表sheet_names,目的是方便后续制定sheet名称;然后再通过列表推导式配合pandas的read_excel批量读取sales.xlsx中所有的数据到列表中,形成sheet_datas。该过程会比较耗时。

(3) 数据审查

  • 前N条数据主要查看不同数据列的数据格式,尤其是有特定转换操作之后是否符合源数据文件的格式或得到目标转换要求,以及数据的长度、组成规律、类型等是否与真实数据一致。
  • 数据描述性信息主要分析数据分布规律,包括记录数、极值、标准差、分位数结果等,可用于数据集的使用模型、极值的处理等后续计算的辅助判断依据。
  • 缺失值信息帮助我们判断数量以及后续应对策略。
  • 数据类型用于判断目标类型当前状态,以及后续是否需要做特殊处理。
# 对表格数据做显示,以审查一下我们的数据是否有误
for each_name,each_data in zip(sheet_names,sheet_datas):    # 函数用于将可迭代的对象作为参数
    print('[data summary for {0:=^50}]'.format(each_name))  #显示各年份之间的分割线
    print('Overview:','\n',each_data.head(4))               #展示数据前4条
    print('DESC:','\n',each_data.describe())                # 数据描述性信息
    print('NA records',each_data.isnull().any(axis=1).sum())#缺失值记录数
    print('Dtypes',each_data.dtypes)                        #数据类型
    print('数据类型与大小:',each_data.info())
[data summary for =======================2015=======================]
Overview: 
           会员ID         订单号       提交日期    订单金额
0  15278002468  3000304681 2015-01-01   499.0
1  39236378972  3000305791 2015-01-01  2588.0
2  38722039578  3000641787 2015-01-01   498.0
3  11049640063  3000798913 2015-01-01  1572.0
DESC: 
                会员ID           订单号           订单金额
count  3.077400e+04  3.077400e+04   30774.000000
mean   2.918779e+10  4.020414e+09     960.991161
std    1.385333e+10  2.630510e+08    2068.107231
min    2.670000e+02  3.000305e+09       0.500000
25%    1.944122e+10  3.885510e+09      59.000000
50%    3.746545e+10  4.117491e+09     139.000000
75%    3.923593e+10  4.234882e+09     899.000000
max    3.954613e+10  4.282025e+09  111750.000000
NA records 0
Dtypes 会员ID             int64
订单号              int64
提交日期    datetime64[ns]
订单金额           float64
dtype: object
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 30774 entries, 0 to 30773
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   会员ID    30774 non-null  int64         
 1   订单号     30774 non-null  int64         
 2   提交日期    30774 non-null  datetime64[ns]
 3   订单金额    30774 non-null  float64       
dtypes: datetime64[ns](1), float64(1), int64(2)
memory usage: 961.8 KB
数据类型与大小: None
[data summary for 

部分
使用for循环,配合zip函数来读取sheet_names和sheet_datas中的每个值,然后分别输出以下内容:

  • 数据展示:使用数据框的head方法,显示前4条数据
  • 描述性信息:使用数据框的describe方法,显示所有的描述性统计结果
  • 缺失值记录:使用数据框的isnull().any(axis=1)来判断含有缺失值的记录,然后用sum获取总记录数
  • 数据类型:使用数据框的dtypes方法获取所有字段数据类型信息。

输出结果如上面代码cell所示。

通过上述结果我们可以得到如下结论:

  • 每个sheet中的数据都能正常读取和识别,无任何错误。
  • 日期列(提交日期)已经被自动识别为日期格式,这省去了后期做转换的过程。
  • 订单金额的分布是不均匀的,里面有明显的极大值,例如2016年的数据中,最大值为174900,最小值仅为0.1。这样的分布状态,数据会受到极值影响。
  • 订单中的最小值竟然包括0、0.1这样的金额,显然不是正常订单。经过与业务方沟通后确认,最大值的订单金额有效,通常是客户一次性购买多个大家电商品;而订单金额为0.1这类是使用优惠券支付的订单,并没有实际意义。除此之外,所有低于1元的订单均有这个问题,因此需要在后续处理中去掉。
  • 有的表中存在缺失值记录,但数量不多,因此选择丢弃或填充都可以。

(4) 数据预处理,去除缺失值和异常值

通过for循环配合enumerate方法,获得每个可迭代元素的索引和具体值。由于处理缺失值和异常值只针对订单数据,因此sheet_datas通过索引实现不包含最后一个对象(即会员等级表)。

  • 直接将each_data使用dropna丢弃缺失值后的数据框替代原来sheet_datas中的数据框。
  • 使用each_data[each_data[‘订单金额’]>1]来过滤出包含订单金额>1的记录数,然后替换原来sheet_datas中的数据框。
  • 最后一行代码的目的是在每个年份的数据中新增一列max_year_date,通过each_data[‘提交日期’].max()获取一年中日期的最大值,这样方便后续针对每年的数据分别做RFM计算,而不是针对4年的数据统一做RFM计算。
# 去除异常值与缺失值    
for ind,each_data in enumerate(sheet_datas[:-1]):
    print(ind)
    print(each_data)
    sheet_datas[ind] = each_data.dropna()  # 丢弃缺失值记录   axis: 默认axis=0。0为按行删除,1为按列删除
    sheet_datas[ind] = each_data[each_data['订单金额'] > 1]   
    sheet_datas[ind]['max_year_date'] = each_data['提交日期'].max()  # 增加一列最大日期值
0
              会员ID         订单号       提交日期    订单金额
0      15278002468  3000304681 2015-01-01   499.0
1      39236378972  3000305791 2015-01-01  2588.0
2      38722039578  3000641787 2015-01-01   498.0
3      11049640063  3000798913 2015-01-01  1572.0
4      35038752292  3000821546 2015-01-01    10.1
...            ...         ...        ...     ...
30769  39368100847  4281994827 2015-12-31   828.0
30770       409757  4282010457 2015-12-31   199.0
30771  38380526114  4282017675 2015-12-31   208.0
30772     28074988  4282019440 2015-12-31    89.0
30773  39460363230  4282025309 2015-12-31   719.0

[30774 rows x 4 columns]
1
              会员ID         订单号       提交日期     订单金额
0      39288120141  4282025766 2016-01-01    76.00
1      39293812118  4282037929 2016-01-01  7599.00
2      27596340905  4282038740 2016-01-01   802.00
3      15111475509  4282043819 2016-01-01    65.00
4      38896594001  4282051044 2016-01-01    95.00
...            ...         ...        ...      ...
41273  35336052906  4324910145 2016-12-31    99.00
41274  39305835721  4324910148 2016-12-31   238.89
41275  39296945352  4324910770 2016-12-31   765.00
41276  14791026234  4324911025 2016-12-31    45.80
41277  16779755770  4324911048 2016-12-31   119.00

[41278 rows x 4 columns]
2
              会员ID         订单号       提交日期    订单金额
0      38765290840  4324911135 2017-01-01  1799.0
1      39305832102  4324911213 2017-01-01   369.0
2      34190994969  4324911251 2017-01-01   189.0
3      38986333210  4324911283 2017-01-01   169.0
4          4271359  4324911355 2017-01-01    78.0
...            ...         ...        ...     ...
50834  39155833075  4338762307 2017-12-31    96.0
50835  29523124076  4338762514 2017-12-31    99.0
50836      7807573  4338762906 2017-12-31   258.0
50837  36642530033  4338762958 2017-12-31   286.0
50838  39155901156  4338763879 2017-12-31   249.0

[50839 rows x 4 columns]
3
              会员ID         订单号       提交日期    订单金额
0      39229691808  4338764262 2018-01-01  3646.0
1      39293668916  4338764363 2018-01-01  3999.0
2      35059646224  4338764376 2018-01-01    10.1
3          1084397  4338770013 2018-01-01   828.0
4          3349915  4338770121 2018-01-01  3758.0
...            ...         ...        ...     ...
81344  39229485704  4354225182 2018-12-31   249.0
81345  39229021075  4354225188 2018-12-31    89.0
81346  39288976750  4354230034 2018-12-31    48.5
81347     26772630  4354230163 2018-12-31  3196.0
81348  39455580335  4354235084 2018-12-31  2999.0

[81349 rows x 4 columns]

汇总所有数据

data_merge = pd.concat(sheet_datas[:-1],axis=0)
data_merge['date_interval'] = data_merge['max_year_date'] - data_merge['提交日期']  #计算各年份与提交日期的间隔
data_merge['year'] = data_merge['提交日期'].dt.year  # 增加一段新的字段,为每个记录行为发生的年份
# 将日期间隔转化成文字
data_merge['date_interval'] = data_merge['date_interval'].apply(lambda x:x.days)
rfm_gb = data_merge.groupby(['year','会员ID'],as_index=False).agg({'date_interval':'min', # 计算最近一次订单时间
                                                              '提交日期':'count',  # 计算订单的频率
                                                              '订单金额':'sum'})   # 计算订单的总金额
rfm_gb
year会员IDdate_interval提交日期订单金额
020152671972105.0
12015282251129.7
2201528334015398.0
320153433001118.0
42015525373213.0
..................
148586201839538034299272149.0
14858720183953803466218913558.0
14858820183953803572917913699.0
148589201839545237824275149.0
148590201839546136285163119.9

148591 rows × 5 columns

# 重新名列名
rfm_gb.columns = ['year','会员ID','r','f','m']
rfm_gb.head() # 预览并打印
year会员IDrfm
020152671972105.0
12015282251129.7
2201528334015398.0
320153433001118.0
42015525373213.0

(5) 确定RFM划分区间

在做RFM划分时,基本逻辑是分别对R、F、M做分箱或者离散化操作,然后才能得到得分离散化后的结果。而离散化本身有多种方法可选,由于我们要对数据做RFM离散化,因此需要先看下数据的基本分布状态。

查看数据分布:

# 查看数据分布
desc_pd = rfm_gb.iloc[:,2:].describe().T
desc_pd
countmeanstdmin25%50%75%max
r148591.0165.524043101.9884720.079.0156.0255.0365.0
f148591.01.3650022.6269531.01.01.01.0130.0
m148591.01323.7413293753.9068831.569.0189.01199.0206251.8

??????有一个问题在于,r和m本身能较好区分用户特征,但f则无法区分(大量的用户只有1个订单) 针对该问题我们与业务部门进行了沟通,结论是由于行业属性(大家电)的原因,用户发送复购确实很少,1年购买1次是比较普遍(其中包含新客户以及老客户在当年的第1次购买),因此划分是可以用2和5作为边界,选择2是因为一般的业务部门认为当年购买2次及2次以上就可以定义为复购用户(而非累计的数量计算复购用户).选择5是因为业务部门认为购买5次已经是非常高的次数,超过该次数就属于非常高价值的用户群体,这个值是基于业务经验和日常数据报表而获得的

设置区间边界

r_bins = [-1,79,255,365]  # 注意起始边界小于最小值
f_bins = [0,2,5,130]
m_bins = [0,69,1199,206252]
  • 在边界上的数据归属有一个基本原则,要么属于区间左侧,要么属于区间右侧
  • 使用pd.cut方法中,对于自定义边界,实行的是左开右闭的原则,即数据属于右侧区间,所以上面的划分才这样,像f_bins最小值是1,要是[0,2]划分,包括1,2这样,不能是[1,2,5,130],因为这样就不能取到1了,这是左开右闭的

(6)计算RFM因子权重

机器学习数据挖掘是解决
在计算RFM组合得分时,我们可以直接将结果组合为一个新的分组,例如322/132。但在加权求和得到一个新的RFM得分指标时,则必须要确定一个权重值。如何确定RFM三个维度的权重呢?
这里面提供一个思路。其实在每个公司中,涉及到会员数据时,一般都会有会员体系,而会员体系中有一个维度,是衡量会员价值度高低的,这个维度是——会员等级。在指定会员等级时,各个公司都已经综合考虑到了多种与公司整体利益相关的因素,设置各种会员权益都与会员等级有关。例如,免运费门槛、优惠券使用、特殊商品优惠价格、会员活动和营销等。因此我们可以基于会员等级来确定RFM三者的权重,基本思路是,建立一个rfm三个维度与会员等级的分类模型,然后通过模型输出维度的权重。

匹配会员等级和RFM得分:

rfm_merge = pd.merge(rfm_gb,sheet_datas[-1],on='会员ID',how='inner')

将会员的订单数据与等级数据匹配,使用merge方法合并两个数据框,关联主键是会员ID,匹配方式是内部匹配。

# rf 获得rfm因子得分
clf = RandomForestClassifier() #调用随机森林分类器模型
clf = clf.fit(rfm_merge[['r','f','m']],rfm_merge['会员等级'])
weights = clf.feature_importances_   # 返回'r','f','m'  三部分权重
print('feature importance:',weights)
feature importance: [0.4080503  0.00656342 0.58538628]
上述过程非常简单,先建立rf模型对象,然后将rfm三列作为特征,将会员等级作为目标输入模型中进行训练,最后通过模型的feature_importances_获得权重信息。结果如上。

由上述结果可知,在这3个维度中,用户的等级首先侧重于会员的价值贡献度(实际订单的贡献),其次是新近程度,最后是频次。这种逻辑与很多公司的整体会员等级一致。例如某国内电商的会员等级,是基于历史累计订单金额进行升级,如果最近一段时间(例如1年内)没有购物,则会降低会员等级。

(7)RFM计算过程

RFM分箱得分:

rfm_gb['r_score'] = pd.cut(rfm_gb['r'],r_bins,labels=[i for i in range(len(r_bins)-1,0,-1)])
rfm_gb['f_score'] = pd.cut(rfm_gb['f'],f_bins,labels=[i+1 for i in range(len(f_bins)-1)])
rfm_gb['m_score'] = pd.cut(rfm_gb['m'],m_bins,labels=[i+1 for i in range(len(m_bins)-1)])

每个rfm的过程使用了pd.cut方法,基于自定义的边界区间进行划分,labels用来显示每个离散化后的具体值。F和M的规则是值越大,等级越高;而R的规则是值越小,等级越高。因此关于R的labels的规则与F和M相反。在labels指定时需要注意,4个区间的结果是划分为3份,因此labels的数量上通过减1实现边界数量与区间数量的平衡,而i+1则实现了区间从1开始,而不是0。
计算总得分
方法1 加权得分

rfm_gb = rfm_gb.apply(np.int32)   # case转数值
rfm_gb['rfm_score'] = rfm_gb['r_score'] * weights[0] +rfm_gb['f_score'] * weights[1] +rfm_gb['m_score'] *weights[2]

方法2 RFM组合

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['rfm_group'] = rfm_gb['r_score'].str.cat(rfm_gb['f_score']).str.cat(rfm_gb['m_score'])
rfm_gb['rfm_group']
0         212
1         211
2         113
3         112
4         322
         ... 
148586    111
148587    213
148588    213
148589    111
148590    211
Name: rfm_group, Length: 148591, dtype: object

这种方式是传统的做会员分组的方式。目标是将3列作为字符串组合为新的分组。
代码中,现针对3列使用astype方法将数值型转换为字符串类型,然后使用pandas的字符串处理库中str的cat方法做字符串合并,该方法可以将右侧的数据合并到左侧,再连续使用两个str.cat方法得到总的R、F、M字符串组合。

关 于 p a n d a s 的 s t r 方 法 关于pandas的str方法 pandasstr
这里str库中cat方法,用于字符串对象合并,语法如下:

参数介绍:
others:要合并的另外一个对象(右侧对象),如果为空,则将左侧对象进行组合。
sep:合并的分隔符,默认为空,可自定义,例如“,”、“;”等。
na_rep:如果遇到NA(缺失值)时如何处理,默认为忽略。
需要注意的是:该方法用于对series做组合,而不能是数据框,适用于一维数据或者字符串。
举例:将左侧对象进行组合
输入输出如下。
在这里插入图片描述

(8) 保存结果到excel

rfm_gb.to_excel('sales_rfm_scorel.xlsx')

总结

在这里插入图片描述
????????终于终于!!! 过程是十分曲折,把这个东西画出去了,看教程没有说怎么操作画出来,然后一直在瞎操作,意思到自己是多么菜,我是怎么经历了这于我的九九八十一难了?我来复盘复原一下下

  1. 透视表我会,插入透视,然后
    在这里插入图片描述

咋眼一看怎么是求和项,为啥rfm_group 不是求和,是离散化呢?
猜想:可能是year这里原来是数字,我试试改为文本说不定就好了
在这里插入图片描述

结果丝毫没有变化,我想怎么会这样,然后一直百度透视表弄分组求和,未果

2 发现了可以弄计数不弄求和
在这里插入图片描述
但是发现还是不是我想要的!
在这里插入图片描述
3 百度怎么画直方图的,我在想是不是想用python处理groupby 求和,然后画出那个图,想到就马上做

import pandas as  pd
data = pd.read_excel('sales_rfm_scorel.xlsx',sheet_name='Sheet1')
new_data = data.groupby(['year','rfm_group'],as_index=False).agg({'会员ID':'count'})
new_data = new_data.rename(columns={'会员ID':'个数'})
new_data.to_excel('year_rfm_group_个数.xlsx')

结果,怎么这次应该可以做了
在这里插入图片描述
但是最后我画出这样的一个家伙
在这里插入图片描述
结果
在这里插入图片描述
4 继续百度走,继续探索,甚至找起了微信关注的excel一些公众号看看怎么做的
结果:还是没有解决
5 最后在透视表继续摸索,加上看了教程后面一些图的画,更熟悉了一下透视表,结果在我的努力下弄好了
第1点 看教程虽然看不到具体步骤是怎么画的,但是知道不用python处理直接在哪里透视就可以了
然后发现了这个数据透视图区域
在这里插入图片描述
把year一拉倒轴这里,马上不是数值计算了,可以是类型,马上感觉是有戏,但是看画出来的图还是不对
6 最终取得西经获得成功了
把year拉到了图例(系列哪里)
在这里插入图片描述

小小结

  1. 真的恍然大悟的,之前也一直觉得excel很强,甚至能做数据挖掘,也关注了一个excel相关的公众号,也在知乎刷过相关的,甚至点赞收藏了教程,但是还是处理佛系学中
  2. 除了工具上的一些些小小收获,还有数据化运营商的一些感悟,以前总觉得python直接pd.read() 进来dataframe就可以随便进行处理了,对excel表格总有种不想逃离舒适圈的感觉,现在再一次领略到excel的强大,也知道python,tableau很强,但是工具都是死,业务是生的,总的下来,python处理清洗数据,构建RFM模型,到excel画图分析得出一些决策,看《python数据分析与数据化运营》中,这一关是辅助决策式运营,也应该是数据分析师中的一些日常

--------------------------未完,继续更新 2021年8月21日 0:04分 先睡觉

3 案例数据结论

(1)基于图形的交互式分析 重点人群分布:先通过Excel柱形图做简单分析,在整个分组中,212群体的用户是相对集中且变化最大的。
通过图XX1可以发现,从2016年到2017年用户群体数量变化不大,但到2018年增长了近一倍。因此,这部分人群将作为重点分析人群。
重点分组分布:除了212人群外,图XX1还显示了312、213、211及112人群都在各个年份占据很大数量,虽然各自规模不大,但组合起来的总量超过212本身。因此,后期也要重点做分析。将阈值设置为2000以上,如图XX2中显示,很多分组非常少的人群减少了很多,说明人群数量比较少的组别非常多。

???????可以看得出这里整个流程是python数据处理+excel透视表得出一些结论,这些如果不算上述随机森林的运用,基本是偏向于人脑子学习得出的理论,这是偏向辅助决策策略运营,虽然如此,还是觉得是偏向技术的数据分析,因为涉及到python了,我看到一些交流群一些大厂的大佬数据分析业务,都基本不涉及python的,而且业务数据分析基本不怎么涉及编程的,这些是我目前一些猜想想法,也许过几个月我就能全梳理弄通了
在这里插入图片描述
筛选大于2000的
在这里插入图片描述
下面是一些excel详细的操作的步骤,全部是引用参考链接的,经实践,全部可以

(2)基于RFM分组结果的分析
通过RFM分组的Excel结果数据,我们将更进一步确定要分析的主要目标群体。
我们打开导出的sales_rfm_score.xlsx文件,然后建立数据透视表。
步骤为:
单击Excel顶部菜单栏的“插入–数据透视表”,在弹窗的窗口中单击“确定”按钮,如图所示

在新建的sheet视图中,进行如下设置:

  • 将rfm_group拖入数据透视表字段区域中的“行”区块
  • 将会员ID拖入数据透视表字段区域中的“值”区块
  • 单击会员ID项
  • 在弹出的窗口中选择“值字段设置”
  • 在弹窗中选择“计算类型”为“计数”
  • 单击“确定”按钮

到此,数据就以RFM分组为主题,以用户数量作为分类汇总了,如图所示

在这里插入图片描述鼠标左键单击“计数项:会员ID”中的任意数值,单击顶部的排序功能,按从大到小排序。如图所示。

在这里插入图片描述

排序后发现,会员在所有分组的分布是不均匀的,我们需要按百分数进行汇总显示,这样可以知道每个分组的占比。在透视表中的“计数项:会员ID”列单击任意数值,然后单击右键,在弹出的菜单中选择“值显示方式”,从右侧菜单中选择“父行汇总的百分比”,如图所示。

在这里插入图片描述

设置完成后,我们对分区用户量进行累计求和,最后发现前9个分组的用户数量占比接近96%,如图所示

在这里插入图片描述

个人认为的重点来了

得出结论,应该是最能体现数据分析产出的地方了

因此,我们需要把分析重点,放在这9组人群上。

(3)RFM用户特征分析 经过上面的分析,我们得到了要分析的重点客户群体。可根据用户的量级分为两类: 第1类是用户群体占比超过10%的群体;
第2类是占比在个位数的群体。 这两类人由于量级不同,因此需要分别有针对性的策略场景。
除此以外,我们还会增加第3类人群,虽然从用户量级上偏小,但是单个人的价值度非常高。

第1类人群:占比超过10%的群体。 由于这类人群基数大,必须采取批量操作和运营的方式落地运营策略,一般需要通过系统或产品实现,而不能主要依赖于人工。
212:可发展的一般性群体。这类群体购买新进度和订单金额一般,且购买频率低,考虑到其最大的群体基础,以及在新进度和订单金额上都还可以,因此可采取常规性的礼品兑换和赠送购物社区活动、签到、免运费等手段,维持并提升其消费状态。
211:可发展的低价值群体。这类群体相对于212群体,在订单金额上表现略差,因此在211群体策略的基础上,可以增加与订单相关的刺激措施,例如组合商品优惠券,发送积分购买商品等。
312:有潜力的一般性群体。这类群体购买新进度高,说明最近一次购买发生在很短时间之前,群体对于公司尚有比较熟悉的接触渠道和认知状态,购物频率低,说明对网站的忠诚度一般,订单金额处于中等层级,说明其还具有可提升的空间,因此可以借助其最近购买的商品,为其定制一些与上次购买相关的商品,通过向上销售等策略提升购买频次和订单金额。
112:可挽回的一般性群体。这类群体购买新进度较低,说明距离上次购买时间较长,很可能用户已经处于沉默或预流失流失阶段;购买频率低,说明对网站的忠诚度一般,订单金额处于中等层级,说明其还可能具有可提升的空间,因此对这部分群体的策略,首先是通过多种方式(例如邮件短信等)触达客户并挽回,然后通过针对流失客户的专享优惠(例如流失用户专享优惠券)措施促进其消费,在此过程中可增加接触频次和刺激力度的方式,增加用户的回访、复购以及订单价值回报。
213:可发展的高价值群体。这类人群发展的重点是提升购物频率,因此可指定不同的活动或事件来触达用户,促进其回访和购买,例如不同的节日活动,每周新品推送,高价值客户专享商品等。

第2类人群:占比为1%~10%的群体,这部分人群数量适中,在落地时无论是产品还是人工都可接入。 311:有潜力的低价值群体。这部分用户与211群体类似,但在购物新进度上更好,因此对其可采取相同的策略。除此以外,在这类群体的最近接触渠道上,可以增加营销或广告资源投入,通过这些渠道再次将客户引入网站完成消费。
111:这是一类在各个维度上都比较差的客户群体,一般情况下会在其他各个群体策略和管理都落地后才考虑他们。主要策略是先通过多种策略挽回客户,然后为客户推送与其类似的其他群体,或者当前热销的商品或折扣非常大的商品。在刺激消费时,可根据其消费水平、品类等情况,有针对性的设置商品暴露条件,先在优惠券及优惠商品的综合刺激下,使其实现消费,再考虑消费频率以及订单金额的提升。
313:有潜力的高价值群体。这类群体的消费新进度高且订单金额高,但购买频率低,因此只要提升其购买频次,用户群体的贡献价值就会倍增。提升购买频率上,除了在其最近一次的接触渠道上增加曝光外,与最近一次渠道相关的其他关联访问渠道也要考虑增加营销资源,另外213中的策略也要组合应用其中。
113:可挽回的高价值群体,这类群体与112群体类似,但订单金额贡献更高,因此除了应用112中的策略外,可增加部分人工的参与来挽回这些高价值客户,例如线下访谈,客户电话沟通等。

第3类群体:占比非常少,但却是非常重要的群体。 333:绝对忠诚的高价值群体。虽然用户绝对数量只有355,但由于其各方面表现非常突出,因此可以倾斜更多的资源,例如设计VIP服务、专享服务、绿色通道等。另外针对这部分人群的高价值附加服务的推荐,也是提升其价值的重点策略。
233、223、133:一般性的高价值群体。这类群体的主要着手点是提升新近购买度,及促进其实现最近一次的购买,可通过电话、客户拜访、线下访谈、微信、电子邮件等方式,直接建立用户挽回通道,以挽回这部分高价值用户。
322、323、332:有潜力的普通群体。这类群体最近刚完成购买,需要提升的是购买频次及购买金额。因此可通过交叉销售、个性化推荐、向上销售、组合优惠券、打包商品销售等策略,提升其单次购买的订单金额,及促进其重复购买。

4 案例应用和部署

针对上述得到的分析结论,会员部门采取了一下措施:
分别针对3类群体,按照公司实际运营需求和当前目标,制定了不同的群体落地的排期。
录入数据库的RFM得分数据已经应用到其他数据模型中,成为建模输入的关键维度特征之一。

5 案例注意点

本案例中有一下几点需要特别关注的:

不同品类、行业对于RFM的依赖度是有差异的,即使是一个公司,在不同的发展阶段和周期下,3个维度的优先级上也有调整。就一般性的经验而言,大家电等消费周期较长的行业,R和M会更重要一些;快消品等消费周期短且快的行业,更看重R和F。具体还是要根据当前运营需求与业务部门沟通。
对R、F、M区间的划分是一个离散化的过程,具体需要划分为几个区间,需要与业务方确认。本案例是划分为3个区间,这样的结果对于业务分析而言,略有点多。这意味着业务方需要制定十几套甚至更多的策略。如果业务方要求简略,也可以划分为2个区间,这样分出来的组别最多有8组,策略制定会更加简单。但是,具体是划分为2个还是3个,取决于当前业务方有多少资源可以投入到这个事情中来。
R、F、M的权重打分,除了案例中提到的建模方法外,结合业务经验的专家打分法也是常用的思路。例如,结合AHP层次分析法进行打分,这样出来的权重结果会更加科学、严谨。
虽然订单数据库中的数据质量相对较高,但可能由于数据采集、数据库同步、ETL、查询、误操作等问题,还是会导致NA值的出现,而NA值的处理非常重要。
R、F、M三个维度的处理(包括计算、离散化、组合、转换)之前都需要注意期数据类型和格式,尤其是有关时间项的转换操作应提前完成。

5 案例延伸思考

利用RFM模型划分用户群体并做价值度分析,是统计分析非常基础且有效的方法。该模型几乎用不到任何专业的统计分析和挖掘只是,只需要具有基本的数据清洗、处理和转换技能即可完成,因此几乎是各个企业都会用到的模型。更重要的是,该模型原理简单,业务方理解和应用起来非常容易入手,可大大提高部署落地的可能性。
结合本节案例,有一下几个值得思考的问题:
(1)按照R、F、M三个维度进行穷尽,应该有333=27中可能性,但是为什么结果只有26种?
(2)不同周期下,R、F、M权重会发生改变,那么运营结果是否有可比性和连续性?
(3)RFM模型可以作为模型分析方法,也可以作为数据预处理方法,基于不同的维度,通过计算组合得分或加权得分的方式获得新的数据,这是一种数据降维的有效方法。使用组合得分方法和加权得分方法得到的两种降维方法,在后续应用中,有什么不同呢

---------------还有这里三个问题 ----留坑 2021年8月21日11:32

参考

Datawhale-team-learning
内容部分参考宋天龙老师的《Python数据分析与数据化运营》

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:19:48  更:2021-08-21 15:20:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 11:09:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计