agglomerativeclustering核心三步:指定n_clusters(必填)、选择linkage与affinity合法组合(如ward仅配euclidean)、用fit_predict获取标签;它不生成树状图,可视化需借助scipy的pdist+linkage+dendrogram。

scikit-learn里用AgglomerativeClustering做层次聚类,核心就三步
直接上手:用 AgglomerativeClustering 类就能完成凝聚式层次聚类,不需要手动维护树结构或计算距离矩阵——它内部自动处理合并逻辑。关键在于你得提前指定簇数量(n_clusters),因为 scikit-learn 的实现是“截断式”的:只返回最终的扁平划分,不提供完整树状图(dendrogram)。
- 必须传
n_clusters,否则会报错ValueError: n_clusters must be specified - 默认度量是欧氏距离(
affinity='euclidean'),但若改用'precomputed',就得自己传入成对距离矩阵,且矩阵必须是对称的、形状为(n_samples, n_samples) -
linkage选'ward'时,affinity只能是'euclidean',其他 linkage(如'complete'、'average')才支持自定义 affinity
怎么可视化聚类结果并验证合理性?
scikit-learn 不内置 dendrogram 绘制,得靠 scipy.cluster.hierarchy 配合。如果你需要看合并过程或选 n_clusters,就得额外走一遍 scipy 流程:
- 先用
scipy.spatial.distance.pdist(X, metric='euclidean')计算压缩距离向量 - 再用
scipy.cluster.hierarchy.linkage(distances, method='ward')构建连接矩阵 - 最后用
scipy.cluster.hierarchy.dendrogram(Z)画图;注意Z是 linkage 输出,不是AgglomerativeClustering的输出 - 如果用
AgglomerativeClustering得到标签后直接画散点图,只能看到最终分组,看不出“为什么是这个数”
常见报错和参数踩坑点
实际跑的时候容易卡在几个地方:
-
ValueError: Negative values in data passed to 'ward' linkage:说明数据含负值,而ward要求输入必须是非负且满足欧氏距离平方可加性,建议标准化或换用linkage='average' -
MemoryError:当样本量 > 10⁴ 且用affinity='precomputed'时,距离矩阵占内存 O(n²),别硬刚,改用近似方法或降维预处理 -
AgglomerativeClustering的fit_predict()返回的是整数标签数组,不是概率或置信度,没法直接评估每个点的归属强度 - 类别不平衡时,
linkage='single'容易产生链式效应(chaining),导致细长簇,实践中慎用
和KMeans比,什么时候该选AgglomerativeClustering?
它不假设球形簇,适合发现嵌套结构或非凸形状,但代价明显:
- 时间复杂度至少 O(n³),样本超 2000 就明显变慢;KMeans 是 O(n·iter·k),快得多
- 不能增量更新:新样本来了得全量重算,KMeans 至少还能 warm start
- 对异常值更敏感——尤其
ward和single,建议先做离群点过滤(比如用IsolationForest或 IQR) - 如果业务明确要固定簇数(比如“分成5个客户群”),KMeans 更稳;如果想探索数据内在粒度(比如“哪些样本天然成组?”),才值得上层次方法
AgglomerativeClustering(n_clusters=5, linkage='average'),别纠结树形细节;真需要 dendrogram,就切到 scipy 去算,别指望 sklearn 替你画。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











