用户分群怎么做?NTILE打分 vs K-Means聚类,面试怎么答?
先说结论
用户分群有三种方法,复杂度递增:规则分群(CASE WHEN)→ RFM+NTILE打分 → K-Means聚类。大多数业务场景,RFM+NTILE就够用了,不用上K-Means。
方法选择的核心标准是业务可解释性。运营不懂什么是聚类中心,他们需要的是「高价值用户」「沉睡用户」这种能理解的分群。如果你的分群结果无法用业务语言解释,运营不会用。
分群不是目的,差异化运营才是。每个分群都要对应具体的运营动作,否则分群就是自嗨。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
用户分群是画像系统最直接的应用场景。运营最常说的话就是「帮我把用户分个层,我要做差异化运营」。但分群的方法很多——最简单的CASE WHEN硬编码、经典的RFM+NTILE打分、高级的K-Means聚类——面试官想听的是你怎么选方案,而不只是会哪个技术。
方案一:规则分群——最简单但最常用
适用于业务方已经有明确分群标准的场景。比如运营说「消费>200块的是高价值用户」——那就直接写CASE WHEN。
-- 规则分群:业务方定义的硬编码规则
SELECT user_id,
total_amount_usd,
login_cnt_30d,
CASE
WHEN total_amount_usd >= 200 AND login_cnt_30d >= 15
THEN 'core_user' -- 核心用户:高消费+高活跃
WHEN total_amount_usd >= 200 AND login_cnt_30d < 15
THEN 'high_value_sleep' -- 高价值沉睡:花了钱但不活跃了
WHEN total_amount_usd < 50 AND login_cnt_30d >= 20
THEN 'active_freeloader'-- 活跃白嫖:天天来但不花钱
WHEN total_amount_usd < 50 AND login_cnt_30d < 5
THEN 'churn_risk' -- 流失风险:不花钱也不活跃
ELSE 'general' -- 一般用户
END AS user_segment
FROM ads_user_profile
WHERE dt = '${bizdate}';
优点:简单、可解释、业务方能理解;规则可以随时调整;SQL即可实现。
缺点:阈值是人工拍的,不一定准确;维度多了规则就写不完(3个维度有27种组合)。
方案二:RFM + NTILE打分——经典的黄金方案
RFM是用户价值分析的经典框架:Recency(最近购买时间)、Frequency(购买频率)、Monetary(消费金额)。用NTILE(5)把每个维度分成5档,然后组合出125种用户类型,再归并成8类核心用户。
-- RFM + NTILE(5)打分
WITH rfm_raw AS (
SELECT user_id,
DATEDIFF(CURRENT_DATE, MAX(order_date)) AS recency, -- R:越小越好
COUNT(DISTINCT order_id) AS frequency, -- F:越大越好
SUM(amount_usd) AS monetary -- M:越大越好
FROM dwd_order_detail
WHERE order_date >= DATE_SUB(CURRENT_DATE, 365)
GROUP BY user_id
),
rfm_scored AS (
SELECT user_id, recency, frequency, monetary,
NTILE(5) OVER (ORDER BY recency ASC) AS r_score, -- R反向排序!越近越高分
NTILE(5) OVER (ORDER BY frequency DESC) AS f_score,
NTILE(5) OVER (ORDER BY monetary DESC) AS m_score
FROM rfm_raw
)
SELECT user_id, r_score, f_score, m_score,
CASE
WHEN r_score >= 4 AND f_score >= 4 AND m_score >= 4 THEN 'champion' -- 冠军用户
WHEN r_score >= 4 AND f_score >= 4 AND m_score < 4 THEN 'loyal' -- 忠诚用户
WHEN r_score >= 4 AND f_score < 3 AND m_score >= 4 THEN 'big_spender' -- 大额偶买
WHEN r_score < 3 AND f_score >= 4 AND m_score >= 4 THEN 'at_risk' -- 高价值流失风险
WHEN r_score < 2 AND f_score < 2 AND m_score < 2 THEN 'lost' -- 已流失
WHEN r_score >= 3 AND f_score < 2 AND m_score < 2 THEN 'new_user' -- 新用户
ELSE 'general' -- 一般用户
END AS rfm_segment
FROM rfm_scored;
NTILE打分的关键细节:R的排序方向和F、M相反!R(最近购买距今天数)越小越好,所以ORDER BY recency ASC,让最近购买的用户得高分。很多人在面试时把R的排序搞反了,面试官一听就知道没实操过。
方案三:K-Means聚类——数据驱动的分群
当业务方说不清楚怎么分群、没有明确的规则时,可以用K-Means让数据自己说话。
# K-Means用户聚类
from pyspark.ml.feature import VectorAssembler, StandardScaler
from pyspark.ml.clustering import KMeans
from pyspark.ml import Pipeline
# 特征准备:R, F, M + 近30天登录次数 + 使用时长
assembler = VectorAssembler(
inputCols=['recency', 'frequency', 'monetary', 'login_30d', 'usage_min'],
outputCol='features_raw')
# 标准化(K-Means对量纲敏感,必须归一化)
scaler = StandardScaler(inputCol='features_raw', outputCol='features')
# K-Means聚类,先试K=5
kmeans = KMeans(k=5, seed=42, featuresCol='features', predictionCol='cluster')
pipeline = Pipeline(stages=[assembler, scaler, kmeans])
model = pipeline.fit(user_df)
result = model.transform(user_df)
# 查看每个聚类中心的特征
centers = model.stages[-1].clusterCenters()
for i, c in enumerate(centers):
print(f'Cluster {i}: R={c[0]:.1f} F={c[1]:.1f} M={c[2]:.1f}')
K怎么选?常用方法是Elbow法(手肘法):从K=2到K=10分别跑一遍,画出K和WSSS(簇内平方和)的曲线,拐点处的K值就是合适的。实际业务中K一般在4-8之间,太少区分不出差异,太多运营管不过来。
三种方案对比
| 维度 | 规则分群 | RFM+NTILE | K-Means |
|---|---|---|---|
| 实现难度 | 低(SQL) | 中(SQL) | 高(Python/Spark ML) |
| 可解释性 | 高(业务定义的) | 高(RFM框架通用) | 低(需要人工解读聚类中心) |
| 灵活性 | 低(硬编码规则) | 中(NTILE自动分档) | 高(数据驱动) |
| 适用场景 | 规则明确的业务场景 | 电商/消费类业务 | 探索性分析、无先验知识 |
| 维护成本 | 低 | 低 | 中高(需要定期重训模型) |
| 我的选择 | 快速验证时用 | 生产环境主力方案 | 做过POC但没上线生产 |
面试高频追问
追问一:NTILE分档会不会导致分群不稳定?今天是高价值,明天就变成中价值?
会的。NTILE是相对排序,用户的绝对消费金额没变,但如果有一批大客户新增,他的排名就会下降。解决方案有两个:①用绝对阈值替代相对排序——比如消费>200就是高价值,不受其他用户影响;②用滑动窗口+平滑处理——连续3天都在top20%才标记为高价值,避免单日波动。我们生产环境用的是「绝对阈值+相对排序」结合:先用绝对阈值划出核心用户和流失用户,中间地带再用NTILE细分。
追问二:K-Means聚类完了,怎么给每个簇取名字?
这是K-Means落地最难的环节。我的做法是:看每个聚类中心的特征均值,找到最显著的特征来命名。比如某个簇的R很小(最近刚买)、F很高(经常买)、M很高(花钱多),就命名为「活跃高价值」。命名一定要和运营一起做,用他们能理解的业务语言。如果聚类结果无法用业务语言解释,说明特征选取或K值有问题,需要调整。
追问三:分群之后怎么落地运营?
每个分群必须对应具体的运营策略。比如:冠军用户→VIP专属优惠+新品优先体验;流失风险用户→召回推送+大额优惠券;新用户→引导完善资料+首购优惠。分群结果写入画像标签表后,推送系统按标签圈选人群做差异化推送。我在出海硬件品牌做过RFM分群后的差异化推送,复购率提升了20%。
实战踩坑
我在某出海硬件品牌做RFM分群时踩过一个坑:一开始只看消费数据(R、F、M),没考虑设备激活数据。结果有一批用户消费金额很高(买了贵的设备),但其实只买过一次就不活跃了——按RFM被分到了「冠军用户」,实际上他们是「高价值沉睡用户」。
后来我在RFM的基础上加了两个维度:近30天设备使用时长和近30天App登录次数。5维度打分后,分群结果准确多了——那批买了贵设备但不活跃的用户被正确标记为「高价值沉睡」,运营针对性地做了召回活动。
教训:RFM是经典框架,但不能照搬。要根据业务特点增减维度。电商类业务RFM够用了,但硬件类业务还需要加设备使用数据。分群的本质是业务理解,不是套公式。
总结
用户分群三种方案:规则分群快速验证、RFM+NTILE生产主力、K-Means探索性分析。面试时重点讲RFM(注意R的排序方向!),能说清楚分群后的运营策略和效果数字,比只讲技术实现有说服力得多。记住:分群不是目的,差异化运营才是。
下一篇聊一个架构设计问题:画像表越来越宽,500列了——宽表和标签表到底怎么选?
你们做用户分群用的什么方法?RFM还是聚类?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长