一. 项目背景
精细化运营是针对人群、场景、流程做差异化细分运营的运营策略。
一般情况在产品进入稳定增长的阶段后,需要提升用户的覆盖,以更好的服务不同属性的用户,来提升运营效率和效果。
精细化运营中人群精细化尤为重要,精细化的前提是CRM(用户关系管理),而用户关系管理的核心即用户分类。
用户价值细分是了解用户分类的重要途径,针对不同价值度的用户进行差异化运营策略,以提升用户留存与活跃,实现精细化管理用户。
二. 项目模型
RFM模型:根据客户活跃度和交易金额,进行客户价值细分的一种方法。通过以下三个指标衡量客户价值和客户创利能力:
R - Recency 最近一次消费
F - Frequency 消费频率
M - Monetary 消费金额
三. 项目数据
某零售平台从2015年到2018年的用户订单抽样数据,数据在excel中包含5个sheet,前4个sheet是每年的交易订单数据,最后一个是用户的会员等级表
以下是数据集的5个特征变量,包括:
- 会员ID:用户ID
- 提交日期:订单日期,格式为YYYY-MM-DD
- 订单号:订单ID
- 订单金额:订单金额
- 会员等级:用来确认R、F、M三个特征的权重
四. 项目建模
4.1 导入所需的库
- pandas:用于数据读取,数据格式化处理和RFM计算
- numpy:用于基本的数据处理
- sklearn:利用其中的随机森林库
代码如下
扫描二维码关注公众号,回复:
10923329 查看本文章
import pandas as pd import numpy as np from sklearn.ensemble import RandomForestClassifier
4.2 数据预处理
4.2.1. 数据审查
- 展示前5条数据:主要查看不同数据列的数据格式,便于之后转换操作的参照
- 描述性统计:主要分析数据的分布规律,包括计数,极值,标准差,分位数等,作为后续计算的辅助判断依据
- 缺失值信息:主要查看缺失值数量,为后续应对策略做参考
- 数据类型:主要查看目标类型的当前状态,为后续是否需要特殊处理提供依据
代码如下
# 读取数据 sheet_names = ['2015', '2016', '2017', '2018', '会员等级'] sheet_datas = [pd.read_excel('C:\\Users\HUAWEI\Desktop\python_book\chapter5\sales.xlsx', sheet_name=i) for i in sheet_names] # 数据审查: for each_name, each_data in zip(sheet_names, sheet_datas): print('data summary for {:=^50}'.format(each_name)) print('Overview:', '\n', each_data.head()) print('DESC:', '\n', each_data.describe()) print('NA records:', each_data.isnull().any(axis=1).sum()) print('Dtypes:', '\n', each_data.dtypes)
运行结果(只截取2015年和会员等级的结果)
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 data summary for =======================会员等级======================= Overview: 会员ID 会员等级 0 100090 3 1 10012905801 1 2 10012935109 1 3 10013498043 1 DESC: 会员ID 会员等级 count 1.543850e+05 154385.000000 mean 2.980055e+10 2.259701 std 1.365654e+10 1.346408 min 8.100000e+01 1.000000 25% 2.213894e+10 1.000000 50% 3.833022e+10 2.000000 75% 3.927932e+10 3.000000 max 3.954614e+10 5.000000 NA records: 0 Dtypes: 会员ID int64 会员等级 int64 dtype: object
4.2.2 初步分析
- 订单金额中最小值有0或0.1这种金额,明显是不正常的订单。通过查看对应的用户消费记录,发现这类订单是使用优惠券支付的,没有实际意义。除此之外,所有低于1元的订单均有此类问题,因此将订单金额小于1的记录全部删除
- 订单金额中最大值也过于明显,但经过查看发现这些订单是一次性购买多个大型用品产生的,是有效数据,因此保留原数据
- 有的表中数据存在缺失值,但数量不多,这里选择丢弃(也可以填充)
4.2.3 数据预处理
- 去除缺失值和异常值
- 汇总所有数据,合并成完整的数据框
- 基于会员ID和年份,分别做RFM原始值的聚合计算(先分组再聚合)
- 将RFM原始值重新命名为r、f、m
代码如下
# 去除缺失值和异常值 for ind, each_data in enumerate(sheet_datas[:-1]): each_data = each_data.dropna() # 去除缺失值的记录 each_data = each_data[each_data['订单金额'] > 1] # 去除订单金额<=1的记录 each_data['max_year_data'] = each_data['提交日期'].max() # 增加一列最大日期值 sheet_datas[ind] = each_data # 合并数据 data_merge = pd.concat(sheet_datas[:-1], axis=0) # 获取各自年份数据 data_merge['year'] = data_merge['提交日期'].dt.year # 新增一列每条记录发生的年份 data_merge['date_interval'] = data_merge['max_year_data'] - data_merge['提交日期'] # 日期间隔 data_merge['date_interval'] = data_merge['date_interval'].apply(lambda x: x.days) # 时间间隔转换为数值型 # 按会员ID做汇总(分组,聚合) rfm_gb = data_merge.groupby(['year', '会员ID'], as_index=False).agg({'date_interval': 'min', '提交日期': 'count', '订单金额': 'sum'}) # 重命名列名 rfm_gb.columns = ['year', '会员ID', 'r', 'f', 'm']
4.3 确定RFM划分区间
4.3.1 基本思路
- 查看数据的分布状态
- 选取区间划分的边界值
- 定义区间边界
代码如下
# 首先查看数据分布 desc_pd = rfm_gb.iloc[:, 2:].describe().T # 定义区间边界 r_bins = [-1, 79, 255, 365] f_bins = [0, 2, 5, 130] m_bins = [0, 69, 1199, 206252]
结果如下:
count mean std min 25% 50% 75% max r 148591.0 165.524043 101.988472 0.0 79.0 156.0 255.0 365.0 f 148591.0 1.365002 2.626953 1.0 1.0 1.0 1.0 130.0 m 148591.0 1323.741329 3753.906883 1.5 69.0 189.0 1199.0 206251.8
4.3.2 结果分析
- 在对RFM划分时,基本逻辑是分别对R、F、M做分箱或离散化处理,然后才能得到离散化后的得分。在选取数据的离散化方法,首先查看数据的基本分布状态
- 通过上述结果,可以看出R和M的数据分布相对较离散,而从F(购买频率)可以看出,大部分用户分布都是趋于1。这就导致R和M能够较好的区分用户特征,而F则无法区分
- 经过企业查询和销售订单的查看,发现该公司属于大型家用电器行业,用户复购行为较少。根据大家电的行业情况,一般认为购买2次及2次以上的用户可以定义为复购用户,购买5次及5次以上为价值较高用户(可依照实际运营情况做相应的调整,本项目划分数据仅供参考)
- 区间边界定义:就本项目而言,选择25%和75%作为区间划分的中间2个边界值,最小值边界是小于各维度的最小值,最大值边界是大于等于各维度的最大值
4.4 RFM计算
4.4.1 R、F、M分箱得分
基本思路
- 基于自定义的边界区间进行划分,离散化后的具体值分为1,2,3
代码如下:
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)])
得分规则
- F和M的值越大,等级越高
- R的值越小,等级越高
4.4.2 RFM总分
基本思路
- 方法一:加权总分
- 优点:可以对所有汇总从一个维度做衡量,尤其用于价值度排序
- 具体操作:首先基于会员等级确定RFM的权重,然后根据各自的权重乘以rfm三列,得到新的加权得分
- 方法二:RFM组合
- 传统的会员分组的方法,其优点是分组更清晰,直接
- 将rfm三列转换为字符串并组合为新的分组
代码如下
# 方法一 # 匹配会员等级和rfm得分 rfm_merge = pd.merge(rfm_gb, sheet_datas[-1], on='会员ID', how='inner') # 使用merge方法合并两个数据框 # 通过RF(随机森林)获得rfm因子得分 clf = RandomForestClassifier() # 建立rf模型对象 clf = clf.fit(rfm_merge[['r', 'f', 'm']], rfm_merge['会员等级']) # 将rfm三列作为特征,会员等级作为目标,输入模型并进行训练 weights = clf.feature_importances_ # 返回值是列表形式 print('feature importance: ', weights) # 加权得分 rfm_gb = rfm_gb.apply(np.int32) # 类别型转换成数值 rfm_gb['rfm_score'] = rfm_gb['r_score'] * weights[0] + rfm_gb['f_score'] * weights[1] + rfm_gb['m_score'] * weights[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'])
4.4.3 RFM因子权重
基本思路
- 在加权求和得到新的指标时,需要确定一个权重值
- 权重依据:会员等级(涉及会员数据时,公司一般都会有自己的一套会员体系,而会员体系中衡量用户价值度的高低的则是会员等级,根据会员等级公司会设置各种的会员权益)
- 权重的计算方法:建立一个rfm三个维度与会员等级的分类模型,然后通过模型输出维度的权重
- 分类模型:随机森林
- 训练特征:R、F、M三个变量;预测目标:会员等级
结果分析
- 特征权重分别为:[0.41493317 0.00584649 0.57922034]
- 用户的等级首先侧重于用户的价值贡献度(即实际订单的贡献),其次是最近消费程度,最后是频次
4.5 保存结果到Excel
- 用于做后续分析和二次加工使用
代码如下:
rfm_gb.to_excel('sales_rfm_score.xlsx')
五. 基于RFM分组结果的分析
5.1 基本思路
- 在Excel中创建数据透视表
- 以RFM分组为主体,以用户数量作为分类汇总
- 计算用户量占比和用户量累计占比
5.2 表格
5.3 分析
- 通过表格可以看出,前9个分组的用户数量占比近96%。因此,需要把分析重点放在这9组人群上
- 将重点用户群体根据用户量级分为两类:
- 用户群体占比超过10%
- 用户群体占比低于10%
- 剩余的分组虽然占比非常小,但是单个人的价值度很高,也需要关注,分为第三类人群