如何在散点图中查找各聚类的相邻聚类?层次聚类Voronoi法失效求解
层次聚类相邻聚类识别方案
为什么基于聚类中心的Voronoi图不好用?
层次聚类的聚类边界由样本的相似度/距离关系决定,并非简单的"以中心为原点的划分"。用聚类中心绘制Voronoi图,仅能反映中心的空间位置关系,和实际聚类的样本分布边界完全不匹配,自然找不到真正共享边界的相邻聚类。
三种可行的实现方法
1. 全样本邻域检测(最直接靠谱)
遍历每个聚类的所有样本,找每个样本的k个近邻,统计近邻所属的其他聚类——只要有交叉样本,就标记为相邻聚类:
from sklearn.neighbors import NearestNeighbors import numpy as np # 假设你有这些变量: # all_samples: 所有样本的numpy数组,形状(n_samples, n_features) # labels: 每个样本对应的聚类标签数组,形状(n_samples,) # cluster_ids: 所有聚类的编号列表,比如[0,1,2,3,4,5,6] # 初始化近邻检测器 nbrs = NearestNeighbors(n_neighbors=5).fit(all_samples) _, neighbor_indices = nbrs.kneighbors(all_samples) # 初始化相邻聚类字典 adjacent_clusters = {cid: set() for cid in cluster_ids} # 遍历每个样本,统计相邻聚类 for sample_idx, current_label in enumerate(labels): # 获取当前样本近邻的标签 neighbor_labels = labels[neighbor_indices[sample_idx]] # 排除自身,添加到相邻集合 for lbl in neighbor_labels: if lbl != current_label: adjacent_clusters[current_label].add(lbl) # 把集合转成列表,方便后续处理 for cid in adjacent_clusters: adjacent_clusters[cid] = list(adjacent_clusters[cid])
这个方法能精准捕获到像聚类0和1、3、4、5、6这种实际共享样本邻域的相邻聚类,完全匹配你的需求。
2. 边界样本匹配(更高效)
先提取每个聚类的边界样本(比如取距离聚类中心最远的20%样本,或者用DBSCAN标记非核心点),然后只计算不同聚类边界样本之间的距离:
- 设定一个距离阈值(比如所有样本平均距离的1/2)
- 如果两个不同聚类的边界点距离小于阈值,就标记这两个聚类相邻
这种方法减少了计算量,适合样本量很大的场景。
3. 聚类树结构推导(仅适用于特定场景)
层次聚类生成的聚类树(树状图)记录了聚类的合并顺序。如果你的聚类是从树的某个高度切割得到的,可以查看每个聚类在合并时的"兄弟"聚类,以及兄弟聚类后续合并的聚类。但这个方法只能找层级上的相邻,不一定是空间上的相邻,通用性不如前两种。
内容的提问来源于stack exchange,提问作者Ayesh
相关产品推荐
相关产品推荐

