概述

模型概念

RFM 模型是衡量客户价值和客户创造利益能力的重要工具和手段。根据美国数据库营销研究所 Arthur Hughes 的研究,客户数据库中有 3 个神奇的要素:

  • 最近一次消费时间(Recency):客户距离最近的一次消费时间的间隔。
  • 最近一段时间内消费频次(Frequency):指客户在限定的期间内所消费购买的次数。
  • 最近一段时间内消费金额(Monetary):客户的消费能力,通常以客户单次的平均消费金额作为衡量指标。

这 3 个要素构成了数据分析最好的指标。

得到客户的特征向量值后,在 R、F、M 任意一项中的价值可被分为高(1)、低(0)两类,综合 R、F、M 三项的表现,用户可被划分为 8 种类型,详细类型及分类规则如下表所示:

客户类型 客户价值 分类说明
重要价值客户 (1 1 1) 最近消费时间近、消费频次和消费金额都很高(VIP)
重要发展客户 (1 0 1) 最近消费时间较近、消费金额高,但频次不高,忠诚度不高,
很有潜力的用户,必须重点发展。
重要保持客户 (0 1 1) 最近消费时间较远,消费金额和频次都很高。
重要挽留客户 (0 0 1) 最近消费时间较远、消费频次不高,但消费金额高的用户,
可能是将要流失或者已经要流失的用户。
一般价值客户 (1 1 0) 最近消费时间近,频率高但消费金额低,需要提高其客单价。
一般发展客户 (1 0 0) 最近消费时间较近、消费金额,频次都不高。
一般保持客户 (0 1 0) 最近消费时间较远、消费频次高,但金额不高。
一般挽留客户 (0 0 0) 三个关键指标都不高。

应用意义

RFM 分析就是通过三个关键指标对客户进行观察和分类,判断每类细分用户的价值。针对不同的特征的客户进行相应的营销策略。

RFM 非常适用于生产多种商品的企业,而且这些商品单价相对不高,如消费品、化妆品、小家电、录像带店、超市等;它也适合在一个企业内只有少数耐久商品,但是该商品中有一部分属于消耗品,如复印机、打印机、汽车维修等消耗品;RFM 对于加油站、旅行保险、运输、快递、快餐店、KTV、行动电话信用卡、证券公司等也很适合。

实战

基础数据

这里只选择最基本的三个字段进行分析,数据字段为:

  • CardID:客户
  • TrxDate:消费时间
  • Amount:消费金额

部分数据如下:

CardID TrxDate Amount
1000101 2019-01-09 77035
1000101 2019-11-06 98946
1000102 2020-03-05 178002
1000102 2020-06-03 381420
1000102 2019-01-05 152999
1000102 2020-01-02 256770
1000103 2019-01-02 31538
1000103 2019-06-07 215572
1000103 2019-01-07 27906
1000103 2019-01-05 65549

数据下载地址:rfm uas

数据处理

  1. 计算 RFM 三个字段:

    1
    2
    3
    4
    5
    6
    SELECT RIGHT("card_id", 3) AS "card_id",
    CURRENT_DATE - MAX("trx_date") AS "r", -- 距离最近的一次消费时间的间隔
    COUNT("card_id") AS "f", -- 消费频率
    ROUND(AVG("amount"), 4) AS "m" -- 单次的平均消费金额
    FROM "rfm"
    GROUP BY "card_id"

  2. 构造客户 RFM 特征向量值,这里通过判断是否大于均值去构造特征向量值,也可以使用标准化后的数据作为特征向量值,再使用 KMeans 等聚类方法将客户分为 8 个类别,再自行区分客户价值类型。

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT *,
    CASE WHEN ("r" - AVG("r") OVER()) < 0 THEN 1 ELSE 0 END AS "vr", -- 时间间隔小于平均值则 1
    CASE WHEN ("f" - AVG("f") OVER()) > 0 THEN 1 ELSE 0 END AS "vf", -- 消费频率大于平均值则 1
    CASE WHEN ("m" - AVG("m") OVER()) > 0 THEN 1 ELSE 0 END AS "vm", -- 平均消费金额大于平均值则 1
    ROUND(("r" - AVG("r") OVER()) / STDDEV("r") OVER(), 4) AS "zr", -- 标准化
    ROUND(("f" - AVG("f") OVER()) / STDDEV("f") OVER(), 4) AS "zf", -- 标准化
    ROUND(("m" - AVG("m") OVER()) / STDDEV("m") OVER(), 4) AS "zm" -- 标准化
    FROM ( ... ) t1

  3. 如果是用均值构造特征向量值,则可继续使用 SQL 进行客户价值分类,如果使用分类模型,则可导出数据到 Python 等处理。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT *,
    CASE
    WHEN "vr" = 1 AND "vf" = 1 AND "vm" = 1 THEN '重要价值客户'
    WHEN "vr" = 1 AND "vf" = 0 AND "vm" = 1 THEN '重要发展客户'
    WHEN "vr" = 0 AND "vf" = 1 AND "vm" = 1 THEN '重要保持客户'
    WHEN "vr" = 0 AND "vf" = 0 AND "vm" = 1 THEN '重要挽留客户'
    WHEN "vr" = 1 AND "vf" = 1 AND "vm" = 0 THEN '一般价值客户'
    WHEN "vr" = 1 AND "vf" = 0 AND "vm" = 0 THEN '一般发展客户'
    WHEN "vr" = 0 AND "vf" = 1 AND "vm" = 0 THEN '一般保持客户'
    WHEN "vr" = 0 AND "vf" = 0 AND "vm" = 0 THEN '一般挽留客户'
    ELSE NULL
    END AS cls
    FROM (...) t2

完整 SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
SELECT *,
CASE
WHEN "vr" = 1 AND "vf" = 1 AND "vm" = 1 THEN '重要价值客户'
WHEN "vr" = 1 AND "vf" = 0 AND "vm" = 1 THEN '重要发展客户'
WHEN "vr" = 0 AND "vf" = 1 AND "vm" = 1 THEN '重要保持客户'
WHEN "vr" = 0 AND "vf" = 0 AND "vm" = 1 THEN '重要挽留客户'
WHEN "vr" = 1 AND "vf" = 1 AND "vm" = 0 THEN '一般价值客户'
WHEN "vr" = 1 AND "vf" = 0 AND "vm" = 0 THEN '一般发展客户'
WHEN "vr" = 0 AND "vf" = 1 AND "vm" = 0 THEN '一般保持客户'
WHEN "vr" = 0 AND "vf" = 0 AND "vm" = 0 THEN '一般挽留客户'
ELSE NULL
END AS cls
FROM (
SELECT *,
CASE WHEN ("r" - AVG("r") OVER()) < 0 THEN 1 ELSE 0 END AS "vr", -- 时间间隔小于平均值则 1
CASE WHEN ("f" - AVG("f") OVER()) > 0 THEN 1 ELSE 0 END AS "vf", -- 消费频率大于平均值则 1
CASE WHEN ("m" - AVG("m") OVER()) > 0 THEN 1 ELSE 0 END AS "vm", -- 平均消费金额大于平均值则 1
ROUND(("r" - AVG("r") OVER()) / STDDEV("r") OVER(), 4) AS "zr", -- 标准化
ROUND(("f" - AVG("f") OVER()) / STDDEV("f") OVER(), 4) AS "zf", -- 标准化
ROUND(("m" - AVG("m") OVER()) / STDDEV("m") OVER(), 4) AS "zm" -- 标准化
FROM (
SELECT RIGHT("card_id", 3) AS "card_id",
CURRENT_DATE - MAX("trx_date") AS "r", -- 距离最近的一次消费时间的间隔
COUNT("card_id") AS "f", -- 消费频率
ROUND(AVG("amount"), 4) AS "m" -- 单次的平均消费金额
FROM "rfm"
GROUP BY "card_id") t1
) t2
ORDER BY "card_id"

输出数据

card_id r f m vr vf vm zr zf zm cls
101 891 2 87990.5000 0 0 0 0.3689 -0.5642 -1.3177 一般挽留客户
102 681 4 242297.7500 1 1 1 -0.6917 0.6538 0.5175 重要价值客户
103 1043 4 85141.2500 0 0 1 1.1365 0.6538 -1.3516 重要挽留客户
104 1200 1 231207.0000 0 1 0 1.9294 -1.1733 0.3856 一般保持客户
105 801 7 188911.8571 1 0 1 -0.0856 2.4809 -0.1175 重要发展客户
106 832 5 275764.2000 0 1 1 0.0709 1.2628 0.9155 重要保持客户
107 618 1 348289.0000 1 1 0 -1.0098 -1.1733 1.7780 一般价值客户

数据可视化

  1. 绘制 R-客户 的散点图,其中 X 轴为客户,Y 轴为距离最后一次消费的时间间隔 R,其中 R 特征值为 1(R < 平均值)的为价值用户(1 1 ?)和发展用户(1 0 ?)。

    R-客户

  2. 绘制 F-客户 的散点图,其中 X 轴为客户,Y 轴为客户消费频次,其中 F 特征值为 1(F > 平均值)的为价值用户(1 1 ?)和发展用户(0 1 ?)保持用户。

    F-客户

  3. 绘制 M-客户 的散点图,其中 X 轴为客户,Y 轴为客户单次平均消费金额,其中 M 特征值为 1(M > 平均值)的为重要用户(1 ? ?)。

    M-客户

  4. 绘制 RFM 模型气泡图,其中 X 轴为消费频率 F,Y 轴为消费金额 M,气泡大小为距离最后一次消费的时间间隔 R(气泡越大说明时间间隔越长,客户价值越低),气泡颜色各个客户分类。

    RFM模型气泡图