🔍 一、题目背景与核心概念

1.1 题目概述

本系列题目基于某店铺的会员消费数据 sales.csv,通过 RFM 模型 对用户进行价值评分,并筛选出最有价值的高消费用户。

  • DA46:实现对每个用户的 R、F、M 三个维度分别打分(1-4分)。
  • DA47:在评分基础上构建 RFM 综合标签,识别“444”类顶级优质客户并排序输出前5名。

🧩 二、RFM 模型详解

字母 含义 特性
R (Recency) 最近一次消费距今天数 越小越好(越近越好)
F (Frequency) 一段时间内消费次数 越大越好(越频繁越好)
M (Monetary) 一段时间内消费总额 越大越好(花钱越多越好)

🎯 目标:将用户按这三个维度划分等级,综合判断其商业价值。


📊 三、评分规则解析

✅ 四分位数划分法(Quantile-based Scoring)

使用 四等分(quartiles) 将数据分为四个区间:

对于 Recency(越小越好):
分数 条件
4分 ≤ Q1(下四分位数)→ 最近消费过,最好
3分 Q1 < x ≤ Q2(中位数)
2分 Q2 < x ≤ Q3(上四分位数)
1分 > Q3 → 最久没来,最差
对于 Frequency 和 Monetary(越大越好):
分数 条件
1分 ≤ Q1 → 消费少/金额低
2分 Q1 < x ≤ Q2
3分 Q2 < x ≤ Q3
4分 > Q3 → 消费最多/金额最高,最优

💡 注意方向相反!这是关键点!


💻 四、完整代码实现(Python + Pandas)

import pandas as pd

# 读取数据
df = pd.read_csv("sales.csv")

# Step 1: 对 R/F/M 分别评分(使用 qcut 自动按分布切分)
df["R_Quartile"] = pd.qcut(df["recency"], q=4, labels=[4, 3, 2, 1]).astype(str)   # 反向打分
df["F_Quartile"] = pd.qcut(df["frequency"], q=4, labels=[1, 2, 3, 4]).astype(str) # 正向打分
df["M_Quartile"] = pd.qcut(df["monetary"], q=4, labels=[1, 2, 3, 4]).astype(str)  # 正向打分

# Step 2: 拼接成 RFMClass 字符串标签
df["RFMClass"] = df["R_Quartile"] + df["F_Quartile"] + df["M_Quartile"]

# 输出第一部分:评分后前5行记录
print(df[["user_id", "recency", "frequency", "monetary", "RFMClass"]].head(5))

# 输出空行
print()

# Step 3: 筛选“444”用户(最佳客户),按 monetary 降序取前5
top_users = (
    df[df["RFMClass"] == "444"]
    .sort_values("monetary", ascending=False)
    [["user_id", "recency", "frequency", "monetary", "RFMClass"]]
    .head(5)
    .reset_index(drop=True)
)

print(top_users)

🧪 五、代码关键点解析

技术点 解析
pd.qcut(..., q=4) 按值的分布均匀分成4个区间(非等距),确保每组样本量大致相等
labels=[4,3,2,1] for recency 实现“数值越小得分越高”的反向映射
astype(str) 将分类变量转为字符串以便拼接
"R" + "F" + "M" → "444" 构建组合标签用于客户分类
sort_values(..., ascending=False) 按消费金额从高到低排序
.reset_index(drop=True) 清除原始索引,使结果从0开始编号

📈 六、扩展知识:RFM 客户细分策略

RFM 类型 用户特征 运营建议
444 刚买过、常买、花得多 VIP客户,重点维护,专属优惠
111 很久没买、不常买、花得少 流失用户,尝试唤醒或放弃
4xx 最近活跃但频次/金额低 新客转化机会,引导复购
x4x 高频但最近未消费 可能流失,推送召回活动
xx4 高消费但不频繁 推荐套餐提升购买频率

📌 应用领域:精准营销、客户生命周期管理、促销活动定向投放


🛠️ 七、常见错误与调试技巧

错误 原因 解决方案
ValueError: Bin edges must be unique 数据存在大量重复值导致无法划分四分位 使用 duplicates='drop' 参数:<br>pd.qcut(..., duplicates='drop')
数值型 vs 字符型混淆 忘记 .astype(str) 导致无法拼接 显式转换类型
排序后索引混乱 未重置索引影响输出格式 加 .reset_index(drop=True)
方向搞反 F/M用了 [4,3,2,1] 记住:只有 R 是反向,F/M是正向

调试建议

# 查看各字段分位数边界(辅助理解 qcut 切分)
print(df["recency"].quantile([0.25, 0.5, 0.75]))

📝 八、学习总结

要点 内容
✅ 核心技能 使用 pandas.qcut 实现基于分布的自动评分
✅ 关键思维 “越优指标得分越高” 的逆向/正向打分设计
✅ 工程实践 多维度评分 → 标签拼接 → 筛选排序输出
✅ 商业洞察 RFM 是用户分层的经典方法,广泛应用于电商、零售、金融等领域
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐