订阅更新

用户分群怎么做?NTILE打分 vs K-Means聚类,面试怎么答?

用户画像手册 第 9 题 约 10 分钟读完

本文目录
  1. 先说结论
  2. 方案一:规则分群——最简单但最常用
  3. 方案二:RFM + NTILE打分——经典的黄金方案
  4. 方案三:K-Means聚类——数据驱动的分群
  5. 三种方案对比
  6. 面试高频追问
  7. 实战踩坑
  8. 总结

先说结论

用户分群有三种方法,复杂度递增:规则分群(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+NTILEK-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年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器