精细化运营-基于销售订单数据的精细化用户管理

一. 项目背景

精细化运营是针对人群、场景、流程做差异化细分运营的运营策略。

一般情况在产品进入稳定增长的阶段后,需要提升用户的覆盖,以更好的服务不同属性的用户,来提升运营效率和效果。

精细化运营中人群精细化尤为重要,精细化的前提是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)
View Code

运行结果(只截取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
View Code

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']
View Code

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]
View Code

 结果如下:

    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)])
View Code

得分规则

  • F和M的值越大,等级越高
  • R的值越小,等级越高

4.4.2 RFM总分

基本思路

  • 方法一:加权总分
  1.  优点:可以对所有汇总从一个维度做衡量,尤其用于价值度排序
  2.  具体操作:首先基于会员等级确定RFM的权重,然后根据各自的权重乘以rfm三列,得到新的加权得分
  • 方法二:RFM组合
  1. 传统的会员分组的方法,其优点是分组更清晰,直接
  2. 将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]
View Code
# 方法二
# 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'])
View Code

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')
View Code

五. 基于RFM分组结果的分析

5.1 基本思路

  • 在Excel中创建数据透视表
  • 以RFM分组为主体,以用户数量作为分类汇总
  • 计算用户量占比和用户量累计占比

5.2 表格

 

 5.3 分析

  • 通过表格可以看出,前9个分组的用户数量占比近96%。因此,需要把分析重点放在这9组人群上
  • 将重点用户群体根据用户量级分为两类:
  1. 用户群体占比超过10%
  2. 用户群体占比低于10%
  • 剩余的分组虽然占比非常小,但是单个人的价值度很高,也需要关注,分为第三类人群

猜你喜欢

转载自www.cnblogs.com/yanmai/p/12725792.html