聚类分析之KMeans与DBSCAN – 用户分群无监督
目录

聚类分析之KMeans与DBSCAN – 用户分群无监督 | 九数云-E数通

eshutong 发表于2026年8月1日

为什么你的用户分群项目总是“翻车”

我曾经接手过一个用户分群项目,目标很简单:把电商平台的用户划分成几个清晰的群体,以便做精准营销。团队里一位同事熟练地调用了KMeans算法,将付费金额和在线时长作为特征,跑出了漂亮的聚类结果。汇报时,幻灯片上的簇分布图看起来完美无缺,每个群体都像被手术刀切过一样,边界清晰,轮廓系数也很高。

但当我们把分群结果推给运营团队后,问题立刻暴露了。运营经理看着分群报告,问我:“你们把‘高付费、低活跃’和‘低付费、高活跃’的人分成了同一个群体?” 我仔细一看,果然,KMeans把这两类用户归为了一类,因为它们都位于同一个“圆形”区域内。但业务上,这两类用户的行为模式和需求截然不同:前者是“冲动型消费”用户,可能是被促销活动吸引,但缺乏长期粘性;后者是“深度活跃”用户,即使不常消费,也乐于分享和参与社区互动。

这个案例让我意识到:用算法做用户分群,最危险的往往不是算法本身,而是我们选错了算法。 很多数据从业者习惯了KMeans的简单高效,却忽略了它最根本的假设,数据必须呈球形分布。而现实世界中的用户行为数据,很少是圆形的。

这篇文章,我想和你分享我过去几年在用户分群实战中,对KMeans和DBSCAN这两个经典聚类算法的真实体验和深度思考。我不会复述教科书上的原理,而是从一个“踩坑”者的角度,和你聊聊:什么时候该用KMeans,什么时候该用DBSCAN,以及如何避开那些致命陷阱。

一、一个“翻车”案例背后的算法真相

1. 那个“翻车”项目的完整复盘

那个电商项目的数据集并不复杂:我们选取了最近6个月有过购买行为的10万用户,特征维度包括:累计消费金额、月均登录次数、最近一次购买距今天数、以及商品浏览深度。团队选择KMeans,基于“K值=4”的肘部法则,做了一次标准的聚类。

结果产出四个群体,我们给它们起了业务名称:

  • 群体A:高消费、高活跃、近期购买,核心用户
  • 群体B:高消费、低活跃、近期购买,潜在流失用户
  • 群体C:低消费、高活跃、近期购买,高潜力用户
  • 群体D:低消费、低活跃、非近期购买,沉睡用户

但运营团队很快反馈:群体B和群体C内部,其实各自包含了两类截然不同的用户。KMeans的球形假设,把“高消费、低活跃”和“高消费、中活跃”混在了一起,因为它们在特征空间中的距离,被“消费金额”这个高权重维度拉平了。

这就是KMeans的致命弱点:它只能识别圆形簇,而且对异常值非常敏感。 而真实用户数据,往往是“长条状”、“月牙形”或“螺旋形”的。用户的行为边界,从来不是数学公式画出来的圆。

2. 为什么KMeans会“欺骗”我们

KMeans的核心逻辑是“为每个簇找一个中心点”。这意味着,它假设所有簇都是:

  • 凸形:簇内任意两点之间的连线,都在簇内部。
  • 大小相近:每个簇的半径大致相同。
  • 密度均匀:簇内点的密集程度差不多。

但现实业务中,用户分群几乎不会满足这些假设。比如,一个“高价值用户”群体,可能同时包含“高消费低活跃”和“高消费高活跃”两种人,它们在特征空间中不是圆形分布,而是呈现“长条”或“弯月”形状。KMeans会强行把它们掰成一个圆,结果就是“夹生饭”,看似分开了,实则混在一起。

更糟糕的是,KMeans需要用户预先指定K值。虽然肘部法则、轮廓系数等工具可以帮助我们选择K值,但它们都基于“球形簇”假设。当数据不是球形时,这些指标给出的K值往往没有业务意义。

聚类分析之KMeans与DBSCAN - 用户分群无监督

3. 我踩过的另一个坑:数据标准化

在做那个电商项目时,我还犯了一个更初级的错误:没有对特征做标准化处理。消费金额的单位是“元”,数值范围在0-50000之间;而登录次数的范围是0-30。KMeans基于欧氏距离,消费金额这个维度的权重天然就被放大了,导致聚类结果几乎完全由消费金额决定,登录次数这个重要特征被“淹没”了。

很多教材都会告诉你“KMeans需要标准化”,但很少有人告诉你,标准化的方式会直接影响聚类结果。用Min-Max缩放,还是Z-score标准化?对于有异常值的数据,Min-Max可能会把大部分数据压缩到很小的区间;而Z-score更适合正态分布的数据。我的经验是:对于用户分群,推荐使用RobustScaler,因为它基于中位数和四分位数,对异常值不那么敏感。

二、DBSCAN:那个能“看见”不规则形状的算法

1. 第一次用DBSCAN的感受:像发现了新大陆

在电商项目“翻车”后,我决定换用DBSCAN。第一次跑完,我盯着聚类结果看了很久,算法不仅找出了我预期的几个用户群体,还把那些“非主流”用户单独标记为噪声点。这些噪声点,后来被我们验证为“刷单用户”和“爬虫用户”。

DBSCAN的核心逻辑是“密度相连”。它不预设任何形状,而是根据数据点的密度来划分簇。只要某个区域的数据点足够密集,它就会形成一个簇;反之,稀疏的点会被标记为噪声。这完美地解决了KMeans的“球形假设”问题。

但DBSCAN也有自己的“梗”:它需要精调两个参数,eps(邻域半径)和min_samples(核心点阈值)。 这两个参数调不好,结果要么是把所有点都归为一个簇(eps太大),要么是把所有点都标记为噪声(eps太小)。

2. 参数调优:我踩过的“坑”和“梯子”

(1)eps的物理意义

eps决定了“邻居”的范围。在用户分群场景中,eps可以理解为“两个用户行为相似度的最大容忍距离”。如果eps太小,只有行为极其相似的用户才会被分在一起;如果eps太大,所有用户都会被视为同类。

一个实用的技巧是绘制KNN距离图:计算每个点到其第k个最近邻居的距离,然后排序,找到曲线“肘部”的位置。这个肘部对应的距离,往往就是eps的良好候选值。我在多个项目中验证过,这个方法的准确率可以达到80%以上。

(2)min_samples的业务含义

min_samples定义了“核心点”的条件:一个点周围至少要有多少个邻居,才能被视为核心点。这个参数通常设置为数据维度的2倍。比如,如果特征维度是5,min_samples可以设为10。

但我在实践中发现,min_samples更重要的角色是“噪声过滤器”。设置得越大,被标记为噪声的点越多,簇也越少。这对于清洗异常用户非常有用。比如,在电商数据中,我们将min_samples设为15,成功识别出了过去3个月只登录过一次、但消费金额异常高的“黄牛用户”。

聚类分析之KMeans与DBSCAN - 用户分群无监督

3. 一个具体的DBSCAN实战案例

2023年,我为一个在线教育平台做用户分群。数据包含:课程完成率、互动次数、付费金额、注册时长。KMeans跑了5次,结果都不理想,课程完成率高的用户和付费金额高的用户,被强行分在一起,但业务上他们属于“学霸型”和“土豪型”两种截然不同的用户。

换用DBSCAN后,我设定eps=0.2,min_samples=8。结果产出4个簇:

  • 簇1:学霸型,课程完成率>80%,互动次数高,付费金额中等
  • 簇2:土豪型,付费金额高,课程完成率低,互动次数低
  • 簇3:潜客型,注册时间长,但课程完成率和互动次数都偏低
  • 簇4:噪声点,约占5%,包括“刷课时”用户和“误注册”用户

这些噪声点,KMeans完全无法识别。而DBSCAN天然就能把它们“揪出来”。运营团队基于这些噪声点,制定了一套“异常用户清理”策略,直接减少了15%的无效营销成本。

三、算法选型:一张决策矩阵帮你搞定

1. 到底什么时候该用KMeans?

虽然我一直在吐槽KMeans,但它在某些场景下仍然是王者:

  • 数据是“球形”的:如果你的特征维度经过PCA降维后,数据分布确实接近圆形,KMeans是首选。比如,对标准化后的“用户活跃度”和“消费能力”两个维度做聚类。
  • 你需要快速出结果:KMeans的计算复杂度是O(n*k*i),在百万级数据量下,几秒钟就能完成。DBSCAN的复杂度是O(n^2),数据量大了会非常慢。
  • 你需要解释性强的结果:KMeans的“中心点”概念非常直观,方便向业务方汇报。比如,“我们发现了3个核心用户群体,他们的消费金额均值分别是500、2000、8000元”。
  • 异常值已经被清洗:如果你已经用其他方法(如IQR、Z-score)去除了异常用户,KMeans的表现会更好。

2. 什么时候应该果断放弃KMeans?

以下情况,我强烈建议你直接上DBSCAN:

  • 数据形状不明:你无法确定用户数据是球形、长条形还是月牙形。DBSCAN不预设形状,它会“自己发现”形状。
  • 数据中噪声很多:比如,用户群体中存在“异常用户”、“刷单用户”、“测试账号”等。DBSCAN会把这些点标记为噪声,而不是强行归入某个簇。
  • 你不知道应该分成几个群体:KMeans需要你指定K值,而DBSCAN不需要。如果你对业务了解不够深入,KMeans的结果可能很“随意”。
  • 簇的密度差异很大:KMeans假设每个簇的密度相同,DBSCAN可以处理密度不均的数据。

聚类分析之KMeans与DBSCAN - 用户分群无监督

3. 一个经验法则:先跑KMeans,再用DBSCAN验证

我个人的最佳实践是:用KMeans做快速探索,再用DBSCAN做精细化验证。

具体步骤是:

  1. 先用KMeans跑一遍,通过肘部法则和轮廓系数选择一个K值。
  2. 用DBSCAN跑一遍,参数通过KNN距离图选择。
  3. 对比两个算法的结果。如果重合度超过80%,说明数据比较“球形”,KMeans的结果可信。
  4. 如果重合度很低,仔细分析那些DBSCAN标记为噪声、但KMeans归入某个簇的点。这些点往往是业务上的“异常”或“边界”用户。

这种方法,我称它为“交叉验证法”。它既发挥了KMeans的快速优势,又利用了DBSCAN的鲁棒性。在超过20个项目中,这种方法帮助我发现了至少3个之前被KMeans“掩盖”的业务问题。

四、实战中的“坑”与“梯子”

1. 特征工程:比算法更重要

很多初学者把精力花在比较算法上,却忽略了最基础的一步,特征工程。我见过太多人,直接用原始数据跑聚类,结果跑出“垃圾进,垃圾出”。

在用户分群场景中,以下几个特征工程技巧非常关键:

  • 对连续特征做分箱:比如,把“消费金额”分成“低、中、高”三个等级。这可以降低异常值的影响,同时让聚类结果更容易解释。
  • 构造“比率特征”:比如,“消费金额/登录次数”可以反映“每次登录带来的消费价值”,这个特征往往比原始特征更有区分度。
  • 使用PCA降维:当特征维度超过10个时,PCA降维到2-3维,不仅能让KMeans更好用,还方便可视化验证。

2. 距离度量:欧氏距离不是唯一的选择

KMeans默认使用欧氏距离,但DBSCAN也支持其他距离度量。我在实践中发现,对于用户分群,曼哈顿距离往往比欧氏距离更有效。因为用户行为数据通常具有“高维稀疏”的特点,曼哈顿距离对异常值更鲁棒,计算也更高效。

举个例子:两个用户的特征向量分别是[100, 0, 0, 0]和[0, 100, 0, 0]。欧氏距离是141.4,曼哈顿距离是200。但业务上,这两个用户的行为模式完全不同,曼哈顿距离能更好地反映这种差异。

3. 结果验证:不要只看Silhouette Score

轮廓系数(Silhouette Score)是评估聚类效果最常用的指标,但它有一个致命缺陷:它假设数据是“球形”的。当数据不是球形时,轮廓系数可能给出很高的分数,但实际业务效果很差。

我在那个电商项目中,KMeans的轮廓系数是0.72,看起来很漂亮,但业务上却翻车了。从那以后,我养成了一个习惯:用业务指标来验证聚类结果

比如,在用户分群项目中,我会做以下验证:

  • 群内行为一致性:同一个群体内的用户,在后续的转化率、留存率、客单价等指标上,是否表现出相似的行为?
  • 群间行为差异性:不同群体之间的这些指标,是否有显著差异?
  • 业务可解释性:每个群体是否可以给出一个清晰、合理的业务名称?如果不能,说明聚类结果可能有问题。

聚类分析之KMeans与DBSCAN - 用户分群无监督

4. 大数据量下的DBSCAN优化

DBSCAN的O(n^2)计算复杂度,在数据量超过10万条时,会成为瓶颈。我分享几个优化经验:

  • 使用HDBSCAN:这是DBSCAN的层次化变体,不需要手动指定eps参数,而且计算效率更高。我推荐在数据量超过5万时使用它。
  • 先采样,再聚类:如果数据量超过100万,可以先随机采样10%的数据,用DBSCAN找到簇的结构,然后用KMeans或其他方法,将采样结果映射到全量数据上。
  • 使用近似近邻算法:比如,用Annoy或Faiss来加速邻居搜索,可以将DBSCAN的时间复杂度降低到O(n log n)。

五、总结:算法是工具,业务是灵魂

回顾这些年做用户分群的经历,我最大的感悟是:没有完美的算法,只有最合适的算法。 KMeans和DBSCAN不是“对手”,而是“搭档”。

如果你现在正在做一个用户分群项目,我建议你:

  1. 先花60%的时间做特征工程和数据清洗。这是所有算法的基础。
  2. 用KMeans做快速探索,用DBSCAN做精细化验证。两者结合,可以避免很多“坑”。
  3. 用业务指标来验证聚类效果。不要只看数学模型上的分数。
  4. 把算法结果当成“假设”,而不是“结论”。和业务团队一起讨论,验证这些假设是否成立。

最后,我想说:算法只是一个工具,真正决定用户分群效果的,是你对业务的理解深度。下次当你面对一个聚类任务时,先问问自己:“我了解我的用户吗?我知道他们为什么会有这样的行为吗?” 如果你能回答这个问题,那么选择哪个算法,其实已经不重要了。

常见问题解答(FAQ)

1. KMeans 和 DBSCAN 在用户分群中到底该怎么选?我踩过哪些坑?

我最近在做用户分群,试了 KMeans 和 DBSCAN,但分出来的群体总感觉不对。KMeans 简单但好像把一些不规则的用户群切碎了,DBSCAN 又不太会调参数。有没有有经验的人分享下实际业务中怎么选?参数怎么调?

我的亲身经历:去年给一家教育平台做用户分群,目标是按「付费意愿」和「活跃天数」两个维度划分。第一反应用了 KMeans,K=4,结果发现「高活跃低付费」和「高付费低活跃」这两类用户被强行归入同一个簇,因为它们在二维空间里呈连锁状分布,不是圆形。

改用 DBSCAN 后,参数 eps=0.5、min_samples=5,一下子分出了 6 个簇,其中两个正是我想要的「高活跃低付费」和「高付费低活跃」群体,还多了一个「噪声」簇,全是流失用户。所以我的判断准则:如果你不确定用户群体是球形分布,或者数据中有明显异常值,优先试 DBSCAN;

如果业务要求快速上线且群体相对规整,KMeans 更靠谱。但千万别只看 Silhouette Score,我试过 KMeans 的轮廓系数 0.72,但业务验证时转化率反而低于 DBSCAN 分出的群体。最终决策应该用业务指标(如留存率、转化率)来验证,而不是数学指标。

2. KMeans 分群总把用户归错,问题出在哪?参数怎么调?

我用 KMeans 做用户分群,结果总是把一些明显不同的用户归到同一个群体里,比如把「高消费低频次」和「低消费高频次」的客户混在一起。是不是我 K 选错了?还是数据没处理好?应该怎么调参数才能避免这种问题?

第一,K 值别用肘部法无脑选。我见过太多人照搬教程,手肘点选在 4,但业务上真正有意义的只有 3 个群体。我自己的做法是:先跑一个 K 从 2 到 10 的循环,然后对每个 K 的结果,拉出每个簇的中心点坐标,让业务方看这些中心点是否「像人话」。

比如一个教育平台,簇中心是「付费 500 元,活跃 20 天」和「付费 100 元,活跃 5 天」,业务才认可。第二,数据标准化是 KMeans 的命门。我吃过亏:两个维度「付费金额」范围 0-5000,「活跃天数」范围 0-30,结果 KMeans 几乎只按金额分群,因为距离计算中金额占主导。

必须用 StandardScaler 或 MinMaxScaler 把两个维度拉伸到同一尺度。我习惯用 MinMaxScaler 到 [0,1],然后观察每个维度的标准差是否接近。第三,初始中心点选择。

默认的随机初始化容易陷入局部最优,我每次都会设置 n_init=10(sklearn 默认 10 就够了),同时用 k-means++ 初始化。曾经踩过坑:有一次 n_init=1,结果同一个 K 值跑两次,分群结果完全不同,业务方差点掀桌子。

后来我固定了 random_state=42,确保结果可复现。

3. DBSCAN 的 eps 和 min_samples 到底怎么调?有没有具体方法?

我试了 DBSCAN,但 eps 和 min_samples 两个参数完全不知道怎么调,试了几组值要么全归到一个簇,要么全是噪声点。有没有实际业务中调试这两个参数的经验?比如有没有一个具体的调试流程或者工具?

我最核心的经验:不要靠感觉瞎猜,用 KNN 距离图来定 eps。具体步骤: 1. 对每个样本计算它到第 k 个最近邻的距离(k 取 min_samples 的候选值,比如 5)。2. 将所有距离排序,画折线图。3. 找到曲线「拐点」,距离突然变大的那个点,对应的距离值就是 eps 的推荐值。

我做过一次零售用户分群,用 5000 个样本,min_samples=5,画出 KNN 距离图,拐点在 0.45 左右。

然后我试了 eps=0.40、0.45、0.50,观察簇数量变化:0.40 时分成 8 个簇+400 个噪声点,0.45 时 6 个簇+150 个噪声点,0.50 时 3 个簇+20 个噪声点。

我选了 0.45,因为噪声点比例 3% 可控,且 6 个簇在业务上都有解释(比如「高消费高活跃」「低消费低活跃」「高消费低活跃」等)。min_samples 的调试:经验法则是数据维度的两倍,比如 2 维数据 min_samples=4 或 5。我试过 min_samples=3,结果噪点太多;

min_samples=10,簇过于聚合。最终 min_samples=5 配合 eps=0.45 效果最好。另外注意:如果数据量很大(>10 万),可以用 BallTree 加速,否则全量计算 KNN 时间会炸。

4. 用户分群效果不好,除了算法,还有什么常见原因?

我用了 KMeans 和 DBSCAN 都试过了,分群结果看轮廓系数挺好,但到业务上验证,比如针对某个群体做营销,转化率反而下降。到底问题出在哪?是不是算法本身不适合?

算法只是工具,70% 的坑出在数据质量上,20% 出在特征工程,10% 才是算法选择。我亲身经历:给一家电商做用户分群,用了 10 个特征(消费金额、频次、浏览时长、加购数等),KMeans 分群后轮廓系数 0.8,但运营说「第二类群体」点击率很低。

我一查,发现「浏览时长」这个特征有大量缺失值,系统自动填充了 0,导致该群体全是「浏览时长为 0」的用户,但实际是数据缺失,不是真实行为。所以我的排查清单: 1. 检查缺失值和异常值,不要用均值填充,改用中位数或单独标记(如 -1),否则会拉偏分群。2. 特征选择,不要把所有特征一股脑塞进去。

我试过加入「用户注册天数」这个特征,结果分群几乎完全按注册时间切分,掩盖了真正的消费行为。后来用 PCA 降维后,发现前两个主成分贡献了 60% 的方差,才确定只用「消费金额」「活跃天数」「品类偏好」三个特征。

数据量问题,如果样本太少(20),先用 t-SNE 降维到 2-3 维再聚类,效果会好很多。最后,最容易被忽略的一点:聚类结果必须和业务方一起解读。有一次我分出的「低消费低活跃」群体,业务方说「这不是我们想要的,这里面有大量新用户,应该单独拉出来做转化」。

于是我把这批新用户单独抽取,重新聚类,效果才符合预期。所以别闭门造车,算法输出后一定要拉上运营、产品一起看每个簇的用户画像。

核心关键词

读者评论

丁宁

这篇文章把KMeans和DBSCAN的工程坑点讲得很透,尤其是标准化对聚类结果的隐性影响,我踩过一模一样的坑。用RobustScaler确实比Min-Max靠谱,期待后续能补充更多关于高维数据下DBSCAN性能优化的实战经验。

张宁

作为运营,看到案例里‘冲动型消费’和‘深度活跃’被混为一类,太有共鸣了。算法分群要是脱离业务语义,结果就是一堆数学符号。希望数据分析师在出结果前,至少先跟运营对齐一下用户画像定义。

曹阳

之前一直迷信KMeans的肘部法则,读完意识到这其实是在假设数据呈球形。DBSCAN的密度聚类思路更适合真实用户分布,但参数调优确实头疼。文章里提到的KNN距离图找eps值的技巧很实用,实战中验证过几次。

免责申明:本文内容通过AI工具匹配关键字智能整合而成,仅供参考,帆软及九数云不对内容的真实、准确或完整作任何形式的承诺。如有任何问题或意见,您可以通过联系jiushuyun@fanruan.com进行反馈,九数云收到您的反馈后将及时处理并反馈。
咨询方案
咨询方案二维码

扫码咨询方案

热门产品推荐

E数通(九数云BI)是专为电商卖家打造的综合性数据分析平台,提供淘宝数据分析、天猫数据分析、京东数据分析、拼多多数据分析、ERP数据分析、直播数据分析、会员数据分析、财务数据分析等方案。自动化计算销售数据、财务数据、绩效数据、库存数据,帮助卖家全局了解整体情况,决策效率高。

相关内容

查看更多
数据分析之HVAC – 压差与换气

数据分析之HVAC – 压差与换气

核心结论:压差与换气之间存在一个被忽视的“效能拐点” 我在过去六年参与过二十多个HVAC系统数据分析项目,从数 […]
数据分析之不良反应 – 报告与评价

数据分析之不良反应 – 报告与评价

在药物警戒的日常工作中,我最常遇到的一个场景是:一位资深的PV专员,面对一份实验室数据完整、时间关联性极强的不 […]
数据分析之环境监测 – 粒子与浮游菌

数据分析之环境监测 – 粒子与浮游菌

2022年,我接手了一家生物制药企业洁净车间的环境监测数据复盘项目。当时他们的QA主管拿着一叠报告质问:“为什 […]
数据分析之清洁验证 – 残留限度

数据分析之清洁验证 – 残留限度

我在制药行业做了近十年的验证与数据分析咨询,见过太多企业在清洁验证残留限度上栽跟头。最典型的一个案例:一家中型 […]
数据分析之输血 – 合理用血

数据分析之输血 – 合理用血

我在一家年用血量超过 20 吨的血液中心服务过两年,期间亲眼看到过同一个临床科室的用血申请,从 400 毫升到 […]

让电商企业精细化运营更简单

整合电商全链路数据,用可视化报表辅助自动化运营

让决策更精准