商场客户聚类实战:从RFM特征到K-Means分群全流程解析

发布时间:2026/10/24 7:15:33
商场客户聚类实战:从RFM特征到K-Means分群全流程解析 有的朋友可能遇到过这种情况市场部的同事拿着一堆会员数据找过来说“咱们商场有几十万会员能不能帮我分分类看看哪些是高价值客户哪些快流失了营销预算好往重点人群上投”。这活儿听起来不复杂但真做起来最合适的工具反而不是那些需要标注标签的分类模型而是无监督学习里的聚类。今天我就用“商场客户聚类”这个项目把从数据清洗、特征构造、算法选型到业务解读的完整链路捋一遍顺便把实操中那些文档里不会写的坑也抖出来。这套思路适合刚接触机器学习的数据分析师、想用数据驱动精细化运营的运营同学也适合自己练手完整项目的初学者。1. 为什么商场要搞客户聚类1.1 业务问题从“一刀切”到“千人千面”传统商场的会员运营方式坦白说非常粗放。节假日发优惠券全员一个折扣新品上市做推广又是一条短信群发。这种“一刀切”模式的问题在于高价值客户可能根本不在乎这点折扣而价格敏感型客户看到满减就想跑偏偏你又把活动规则设得太复杂。结果两头不讨好。我当时接到的需求很简单某连锁商场想在会员里划分出几个清晰的人群每个群体要有明确的行为特征比如谁在贡献毛利、谁在凑单买低价、谁已经很久没来了。只有把人群拆开营销活动才能“千人千面”——给忠诚客户做积分权益给沉睡客户做召回给价格敏感客户做爆款促销。聚类就是干这个的在没有任何标签的情况下让数据自己把相似的人归到同一堆里。1.2 为什么偏偏选聚类不选分类很多新手会问既然要给客户分类为什么不用逻辑回归或者决策树做分类任务区别很关键分类是有监督学习必须提前准备好“类别标签”比如把客户标成“高价值”“中价值”“低价值”。但实际业务里这些标签的划分标准是拍脑袋定的什么叫高价值消费满一万还是满五万不同业态都不一样。强行定标签等于把业务偏见塞进模型。聚类是无监督学习核心思路是“让数据自己说话”。我不需要提前告诉模型谁是高价值客户只需要给它一组特征比如最近一次消费时间、消费频次、消费金额K-Means这类算法就会自动找出数据的自然结构。用聚类还有一个隐性好处它让我发现了三个此前业务经验完全没想到的人群比如有一类“高频低客单”客户团队一直以为是羊毛党实际聚类后发现他们是周边写字楼的上班族中午来买简餐复购率极高。这种洞察不是靠拍脑袋能拍出来的。1.3 这个项目的边界与预期产出做项目前一定要先划清楚边界不然会被业务无限追问。我当时的预期产出是三样东西第一一个可解释的客户群体划分表每个群体有特征均值第二每个群体的业务标签命名和营销建议第三一个可以定期重跑的数据脚本。边界是不做预测、不做实时打分只做“当前会员存量结构”的分析。项目周期大概三周其中数据清洗占了一半时间这部分常被新手低估。2. 数据准备决定聚类上限的环节2.1 数据从哪来、拿什么字段商场会员数据一般存在CRM系统或数据仓库里取数口径要想清楚。我当时拿到的是某区域门店的会员交易明细数据量大约25万会员、300多万条消费记录时间跨度12个月。字段包括会员ID、性别、年龄、入会时间、每笔消费的时间戳、金额、商品品类、优惠券使用情况、支付方式等。原始字段不能直接丢进聚类模型。我的做法是汇总成客户维度特征这里最经典的框架是RFMRRecency最近一次消费距离今天多久、FFrequency统计周期内的消费频次、MMonetary统计周期内的消费总金额。这三个特征组合起来恰好能覆盖“活跃度、忠诚度、贡献度”三个维度。除此之外我还加了两个衍生特征平均客单价总金额除以总次数和连带率总购买件数除以总次数用来反映客户在购物篮深度上的差异。这里有个经验特征不是越多越好而是越“正交”越好。RFM三个维度之间相关性不能太高否则模型会重复加权导致聚类结果偏向某一个维度。我当时把商家补贴金额也放进去了结果发现它和消费金额相关系数接近0.8果断删掉。2.2 特征清洗与异常值处理商场的脏数据比想象中多。我列几个典型的坑年龄字段有0值和负数有人录入了800岁直接按缺失处理或做截断。消费金额有负数通常是退款单没对冲干净这类记录要单独处理不能直接求和。同一会员出现多个ID是因为线下办卡和线上注册没有打通需要按手机号去重。统计周期内只有一笔消费的会员占比很高他们和真正的低频忠诚用户是两回事需要在解读时特别标注。清洗逻辑上我保留了交易金额大于0且小于某个业务阈值的记录比如单笔超过5万元的极值客户先拉出来人工核查防止是批发走账把年龄限制在16到90岁区间。对缺失值没有一律删行而是看缺失比例性别缺失小于3%用众数填充消费特征缺失超过10%的会员直接剔除因为聚类对这类样本的归属非常不稳定。2.3 标准化聚类前的关键一步聚类算法里最常用的是距离度量比如欧氏距离。但消费金额的量级和消费频次完全不一样金额动辄几千频次可能只有个位数。如果不做标准化计算距离时金额会彻底主导簇的划分频次和最近消费时间就变成了摆设。我见过有人在这个环节偷懒聚类出来全是“钱多钱少”两个极端簇业务完全没法用。我用的是Z-score标准化让每个特征均值变成0、标准差变成1。另外提一句有些场景也可以用Min-Max缩放但Z-score对异常值的容忍度更低所以在前面清洗环节已经把极端值处理掉的情况下Z-score是更稳的选择。标准化的另一个好处是后面做轮廓系数评估时数值之间不会因为尺度原因产生误导。from sklearn.preprocessing import StandardScaler features [Recency, Frequency, Monetary, Avg_Order_Value, Cross_Sell_Ratio] X df[features] scaler StandardScaler() X_scaled scaler.fit_transform(X)标准化之后我还做了相关性检查确保五个特征之间相关系数绝对值都低于0.6。这个动作不是形式主义是为了让聚类出的每个簇都有多维度的业务解释权否则解释的时候会发现高价值和高频是完全绑定的人群拆不出来。3. 算法选型K-Means到底香在哪3.1 几种聚类算法的适用场景对比商场客户聚类可以选的算法不少我拿当时对比的几种来说K-Means速度快、可解释性强适合数据量大、维度适中、簇形状近似球形的场景。客户聚类恰好是典型应用因为RFM特征空间里簇形状通常还算规则。层次聚类Agglomerative不需要预先指定K值可以输出树状图。但样本量一大距离矩阵就爆炸25万会员根本跑不动更适合几千条数据的探索。DBSCAN能识别任意形状的簇还能自动发现离群点。但它的密度参数eps很难调会员数据密度分布不均匀时容易出现“一个大簇吞掉所有点”或者“全变成噪声点”的极端情况。高斯混合模型GMM可以输出属于每个簇的概率比硬分配更柔性。可它假设每个簇服从高斯分布而实际消费数据通常是长尾的拟合效果不稳定。说实话这些算法我在练手项目里都试过一遍最后在“业务可解释性”和“落地成本”之间反复权衡还是选了K-Means。不是说其他算法不好而是这个场景下K-Means的简单性反而是优点。3.2 为什么最终选了K-Means选K-Means有三个非常现实的原因。第一业务方要的是能马上执行的客户分组K-Means给出的硬分类结果可以直接打标签写进营销系统不用处理概率阈值。第二K-Means的时间复杂度接近线性25万会员、5个特征几秒钟就能跑完一轮后面调参和重训的成本极低。第三也是最重要的它的簇中心可以直接解读。每个簇中心就是一组特征均值业务团队一眼就能看出“哦这个群体最近一次消费是30天前平均消费1200元”不需要懂算法也能听明白。但我也得承认它的短板K-Means对初始质心敏感对异常值敏感而且只擅长找球形簇。这就需要在实操里配合正确的初始化方法比如K-Means和多轮随机重启来规避而不是换一个复杂算法。商业分析场景里能让人看懂的模型往往比精度高但解释不清的模型更有价值。3.3 K-Means的原理和迭代过程用大白话讲K-Means就是干这么一件事把数据分成K堆让每堆内部的点尽量紧凑堆与堆之间尽量疏远。具体迭代就四步随机选K个点当初始质心。每个样本计算到K个质心的距离归到最近的质心那一簇。重新计算每个簇的质心该簇所有样本的均值。重复第2、3步直到质心变化很小。目标函数是簇内误差平方和SSE也叫惯性inertia。算法在反复寻找能让这个值最小的分组方式。由于这个优化不是全局收敛的所以一般要设置n_init10即随机跑10次取最优这能大幅减少撞上局部最优的概率。我习惯把所有随机数种子固定方便复现也方便和同事对结果。4. 实操全过程从K值选择到结果可视化4.1 用肘部法则初选K值聚类和分类最大的差别是没有正确答案告诉你K该取几。我常用的第一招是肘部法则。思路很简单随着K增大SSE一定下降因为簇越多组内越紧凑。但下降的幅度会越来越小在某个临界点出现“拐弯”像人的手肘一样这个拐点对应的K就是结构上比较自然的簇数量。from sklearn.cluster import KMeans import matplotlib.pyplot as plt sse [] k_range range(2, 11) for k in k_range: model KMeans(n_clustersk, random_state42, n_init10) model.fit(X_scaled) sse.append(model.inertia_) plt.plot(k_range, sse, markero) plt.xlabel(K) plt.ylabel(SSE) plt.show()跑出来的肘部图里K从2到5时SSE下降非常陡峭到6之后曲线明显变平。这个拐点指向K5左右但不是特别锐利。于是我没有急着定死又跑了第二重验证轮廓系数。4.2 结合轮廓系数做最终确认轮廓系数是目前最常用的聚类内部评估指标之一。对于每个样本它计算两个距离样本与自己簇内其他样本的平均距离a以及样本与最近的那个相邻簇所有样本的平均距离b。轮廓系数 (b - a) / max(a, b)。数值范围在-1到1之间越接近1说明样本离自己簇近、离邻近簇远分组效果越好。把所有样本的轮廓系数取平均就是当前K值的整体轮廓系数。from sklearn.metrics import silhouette_score sil_scores [] for k in k_range: model KMeans(n_clustersk, random_state42, n_init10) labels model.fit_predict(X_scaled) sil_scores.append(silhouette_score(X_scaled, labels)) plt.plot(k_range, sil_scores, markero) plt.show()当时的结果是K5时轮廓系数约0.42K6时掉到0.35K4时是0.38。单看数值都不算特别高但这在真实业务数据里很正常——人的行为本身就有重叠不可能像合成数据那样跑出0.7以上。综合肘部法的拐点和业务上“五个人群包”的运营规模我最终选了K5。关于K值选择我个人的原则是先看肘部法再用轮廓系数验证最后一定要问业务“给你5个人群和6个人群运营上有没有区别”。如果某个K跑出来的结果无法落地命名数值再漂亮也别用。4.3 跑通K-MeansPython代码实操选好K值后就是正式建模。代码本身非常简短但有几处细节值得说清楚。import pandas as pd from sklearn.cluster import KMeans best_k 5 final_model KMeans(n_clustersbest_k, random_state42, n_init10) df[cluster] final_model.fit_predict(X_scaled) # 把标准化前的原始特征拉出来做群体画像 profile df.groupby(cluster)[features].mean().round(2) print(profile)输出结果类似这样具体数值要按数据分析不能凭空写死簇Recency(天)Frequency(次)Monetary(元)平均客单价连带率012948005333.214538602872.1..................这里要注意一个坑fit_predict是在训练数据上直接给出预测标签聚类本身没有过拟合问题但如果你后续要用这些标签做训练特征必须小心“标签泄露”。另外KMeans的随机种子一定要固定不然每次跑出来的簇编号顺序会乱业务人员第一次看可能每次结果都不一样会直接对模型失去信任。4.4 降维可视化PCA和TSNE怎么看聚类结果最好还是要可视化不然业务方没法“眼见为实”。高维空间我一般先用PCA主成分分析把五个特征压缩成两个主成分再画散点图用不同颜色标出不同簇。PCA降维后的两个轴是有解释意义的通常是贡献度最大的两个线性组合方向。from sklearn.decomposition import PCA pca PCA(n_components2) X_pca pca.fit_transform(X_scaled) plt.scatter(X_pca[:, 0], X_pca[:, 1], cdf[cluster], cmapviridis, s1, alpha0.6) plt.xlabel(PC1) plt.ylabel(PC2) plt.show()如果PCA投影后簇之间重叠严重我还会用TSNE再跑一次因为TSNE擅长把局部结构拉开视觉上更“分得开”。但记住TSNE的距离没有全局含义不能拿TSNE图去解释“这两个簇有多远”只能当作辅助确认。实际我发现PCA图里K5的簇重叠确实存在但每个簇的中心区域都很清晰这和轮廓系数0.42的水平是一致的。5. 聚类结果解读每个簇是一个“人群包”5.1 核心特征画像聚类模型跑完真正的重头戏才开始解读。我先把每个簇的特征均值做成表格再算每个簇的人数占比。从业务视角把簇编号换成可理解的名字簇编号人数占比RecencyFrequencyMonetary业务标签018%5天14次9600元高价值忠诚客户124%50天4次1200元沉睡唤醒客户231%15天6次2200元中间潜力人群315%3天11次800元高频低客单412%90天1次350元临近流失客户这个表一出来业务同事基本秒懂。但我想特别提醒给簇命名要克制不要硬编故事。我是先把特征画成雷达图再结合访谈数据给标签的。比如簇3起初团队以为是羊毛党但看连带率3.8和平均客单价72元更像每天下班来买熟食和日用品的上班族。后来调了订单详情验证了这一点。5.2 从统计显著到业务命名命名不是随口取的。我当时做了两个额外的分析第一计算每个簇在各个特征上的分布和全局均值的差异用t检验或直接看置信区间确认这个簇确实在某个维度上显著偏离整体第二按簇交叉分析性别、年龄段、入会年限等画像字段看能不能找到外部可触达的标识。比如“高价值忠诚客户”这个簇统计上显著特征是消费金额高、频次高、最近一次消费距离今天小于7天然后在画像字段里他们集中在35到50岁、入会超过两年、持有商场联名信用卡。所有这些信息汇总后我建议加上一句“定向触达时优先使用会员APP推送”因为这群人的APP活跃度也是最高的。5.3 营销策略的落地映射聚类不是终点营销动作才是。我给每个簇设计了适配的策略高价值忠诚客户维系为主提供专属会员日、双倍积分、新品优先试用。这群人不需要被过度促销刺激反而在意被认可。沉睡唤醒客户重点发召回券但金额不要太大。用数据分析来看这批人唤醒后复购率显著高于新客说明是“知道商场好但最近没来”而不是质量差。中间潜力人群他们有一定频次和金额最值得做交叉销售推荐关联品类。高频低客单给满减券但门槛要低。他们吃的是便利和刚需你高门槛满减等于没发。临近流失客户先用问卷或短信了解流失原因再结合品类偏好做最后一波挽回。各簇的营销策略写清楚后业务团队就能直接抄作业。聚类项目真正交付的不是PPT而是这套“标签动作”的组合拳。6. 踩坑记录与经验技巧6.1 特征选择比调参重要得多这是我最想强调的一点。很多新人在聚类上花大量时间调n_init、max_iter效果却不理想。实际上当聚类结果解释不通时90%的原因是特征没构造好。特征如果只是原始字段堆砌比如只放年龄和性别聚类出来基本是一团浆糊放RFM三个特征马上有业务意义。我的习惯是至少做两轮特征迭代。第一轮跑一个baseline看出来的簇合不合理然后根据解释过程中的困惑加特征或删特征比如我第一轮发现“高价值”和“高频”绑在一起于是拆出平均客单价才把“高价值贡献”和“高频低额消费”区分开。这种迭代是聚类的灵魂不是说算法跑完就结束了。6.2 做聚类前一定要看数据的分布形态有次我拿一版新数据直接标准化后丢进K-Means结果轮廓系数只有0.2效果惨不忍睹。后来画了分布图才发现消费金额的偏态非常严重大部分客户一年只消费几百块少数大客户消费几十万Z-score标准化后依然有长尾影响。解决方法是做log1p变换把金额压缩到近正态分布再做标准化。类似的问题还有频次特征经常是泊松分布也可以考虑做平方根变换。这里教大家一个快速检查方法在跑K-Means前对每个特征画直方图如果看到严重的长尾或双峰先做变换聚类结束后看一眼每个簇在原始尺度上的分布而不是只看标准化后的均值防止解读时被“还原退火”坑了。6.3 聚类不是一锤子买卖上线后要定期重训有些团队把聚类结果做成一个静态名单用半年都不换这是不对的。客户的消费行为会漂移比如某个节假日大促会让高频客户频次骤增活动结束恢复商场的业态调整也会让客户结构变化。我后来把这套聚类脚本封装成月度任务每个月用最近12个月滚动窗口重新训练。同时做一件事记录每个客户簇归属的变化轨迹。如果某个客户从“高价值忠诚”漂移到“临近流失”系统要及时触发预警这个动态视角比静态分组价值大多了。重训时还有个细节不要每次都用完全不同的K值否则簇的历史对比没法做。我的做法是K值固定只在必要时重新验证一次平时的月度重训只看簇的人数占比和特征均值漂移情况。6.4 冷启动和特殊人群要单独处理聚类对所有客户一视同仁但业务上有些特殊情况得单独切出来。比如员工内部采购账号、企业团购客户他们的消费模式和普通个人客户完全不同一旦混进去整个聚类会被带偏。我当时按照“是否绑定企业账户”做了两层处理先排除企业客户再对个人会员聚类。还有处于“生命周期初期”的新会员入会不满一个月RFM天然偏低硬塞进聚类会被分到“流失客户”但这显然不公平。我的处理是给新会员单独建一个“观察期”分组满了三个月再进入聚类模型。6.5 解释模型时别硬造因果最后一条提醒偏方法论。聚类输出的只是相关性结构不自动代表因果关系。比如“高价值忠诚客户”频次高、金额高你不能直接说“因为频次高所以价值高”只能说“在这批数据里这两个特征在同一人群中共同出现”。再比如聚类发现“临近流失客户”平均折扣使用率高可能是他们只在大促销时才回来而不是因为折扣才流失。一定要避免在业务汇报里说出“打折导致流失”这种话数据不支持因果结论真的要说也应该用测试验证。最后再分享一句实在话这个商场客户聚类项目做完我最深的体会是聚类算法的代码半小时就能写完但真正难的是在业务场景里定义“什么是相似的人”。同样的RFM特征在超市、百货、购物中心里跑出来的簇结构天差地别因为消费逻辑不一样。所以一定要和业务方反复对齐你们想区分的到底是什么样的人群哪个维度对营销决策影响最大把这个问题聊透聚类才不是“机器自己玩”而是帮我们把常识变成了可执行的数据策略。如果你也想练这个项目我建议从公开的商场客户数据集开始先跑通流程然后一定找一个真实业务问题对一下你会发现比调参有意思得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询