如何实现约束聚类:强制同一Label样本归为同一簇?
如何在聚类时强制同一Label的样本归为同一簇?
针对你的需求(10k+样本、100+Label,需将同一Label样本强制归为同一簇,最终划分3-8个簇),以下是两种直接可行的解决方案:
方法一:Label级聚合后聚类(推荐,高效且完全满足约束)
核心思路是先将同一Label的所有样本合并为一个特征代表,再对Label层面的数据进行聚类,最后将簇ID映射回原样本。这种方式天然保证同一Label的样本必在同一簇,且计算量远低于样本级聚类。
具体步骤:
- 对每个Label,计算其所有样本的特征聚合值(如均值、中位数,或取该Label的聚类中心),得到Label与聚合特征的映射表
- 对Label级数据集运行常规聚类算法(如K-Means),指定簇数3-8
- 将每个Label对应的簇ID,批量映射到原数据集中的所有该Label样本
代码示例(Python):
import pandas as pd from sklearn.cluster import KMeans # 假设原始数据存储在df中,包含Label列和Feature开头的特征列 feature_cols = [col for col in df.columns if col.startswith('Feature')] # 1. 按Label聚合特征(这里使用特征均值作为代表) label_feature_agg = df.groupby('Label')[feature_cols].mean().reset_index() # 2. 对Label级数据执行K-Means聚类,指定簇数为5(可在3-8之间调整) kmeans = KMeans(n_clusters=5, random_state=42) label_feature_agg['Cluster'] = kmeans.fit_predict(label_feature_agg[feature_cols]) # 3. 将簇ID映射回原数据集 df = df.merge(label_feature_agg[['Label', 'Cluster']], on='Label', how='left')
方法二:带Must-Link约束的聚类(样本级强制约束)
如果需要在样本层面直接施加约束,可使用支持Must-Link约束的聚类算法——Must-Link约束指定"这些样本必须归为同一簇",这里即为同一Label下的所有样本两两建立约束。
具体步骤:
- 生成Must-Link约束对:遍历每个Label,将该Label下的所有样本两两配对
- 使用支持约束的聚类算法(如
scikit-learn-extra的KMeansConstrained)执行聚类
代码示例(Python):
import pandas as pd from sklearn_extra.cluster import KMeansConstrained # 假设原始数据df的索引为样本Id feature_cols = [col for col in df.columns if col.startswith('Feature')] X = df[feature_cols].values # 生成Must-Link约束对:同一Label的所有样本两两绑定 must_link = [] for label in df['Label'].unique(): label_sample_indices = df[df['Label'] == label].index.tolist() # 生成该Label下所有样本的两两组合 for i in range(len(label_sample_indices)): for j in range(i + 1, len(label_sample_indices)): must_link.append((label_sample_indices[i], label_sample_indices[j])) # 运行带约束的K-Means,指定簇数为5 constrained_kmeans = KMeansConstrained(n_clusters=5, random_state=42, must_link=must_link) df['Cluster'] = constrained_kmeans.fit_predict(X)
注意事项:
此方法会生成大量约束对(若某Label有N个样本,会产生N*(N-1)/2个约束),当样本量较大时,计算开销会显著增加,因此更适合Label下样本数较少的场景。
内容的提问来源于stack exchange,提问作者Krzysztof C
相关产品推荐
相关产品推荐

