scikit-learn层次聚类算法中如何获取所有中间聚类结果?
关于凝聚式层次聚类的中间结果问题
你的理解是对的
凝聚式层次聚类(也就是你用的AgglomerativeClustering)是自底向上的合并过程:一开始每个样本单独成一个簇,之后每一步把最相似的两个簇合并,直到达到指定的簇数。所以当你聚类到8个簇时,整个合并过程已经包含了所有簇数大于8的中间划分结果(比如9、10…直到每个样本单独成簇的状态)。
不需要多次运行代码,一次训练就能获取所有中间结果
sklearn的AgglomerativeClustering提供了直接获取任意簇数划分的方法,不用重复训练模型,能大幅节省计算时间:
优化思路
- 先训练一个完整的层次聚类模型:不指定
n_clusters(或者设为1,会完成所有合并步骤直到只剩1个簇),让模型生成完整的合并树。 - 用
cut_tree方法,传入不同的k值,直接生成对应簇数的标签。
优化后的代码示例
%%time # 先训练完整的层次聚类模型 np.random.seed(123456) full_model = AgglomerativeClustering(linkage='ward', connectivity=w.sparse, n_clusters=None) full_model.fit(cont_std) # 遍历所有需要的k值,直接生成标签 for k in K: start_time = time.time() s[k] = [] db[k] = [] # 用cut_tree获取k个簇的标签 y_labels = full_model.cut_tree(n_clusters=k).flatten() cont_std_[f'AHC_k{k}'] = y_labels # 计算评估指标 silhouette_score = metrics.silhouette_score(cont_std, y_labels, metric='euclidean') print(f'silhouette at k={k}: {silhouette_score}') s[k].append(silhouette_score) davies_bouldin_score = metrics.davies_bouldin_score(cont_std, y_labels) print(f'davies bouldin at k={k}: {davies_bouldin_score}') db[k].append(davies_bouldin_score) end_time = time.time() print(f"Time for k={k}: {end_time - start_time} seconds")
额外说明
- 模型的
children_属性可以查看每一步合并的簇对(每一行是两个被合并的簇的索引),能帮你直观理解整个合并过程。 n_leaves_属性对应初始簇数(也就是样本总数),n_components_是最终簇数(当n_clusters=None时为1)。
内容的提问来源于stack exchange,提问作者Reuben
相关产品推荐
相关产品推荐

