聚类结果相似性评估方法有哪些?大列联表场景Python实现咨询
嘿,针对你遇到的聚类结果相似性评估问题,我整理了几个适合大列联表(比如10x10、8x6这类)的成熟方法,附上Python实现,应该能完美解决你的需求:
常用聚类结果相似性评估方法及Python实现
1. 调整兰德指数(Adjusted Rand Index, ARI)
这是评估聚类一致性最常用的指标之一,它修正了随机聚类带来的偏差,取值范围是[-1, 1]:
- 1表示两个聚类结果完全一致
- 0表示聚类结果和随机分配无差异
- -1表示聚类结果完全相反
Python实现(用scikit-learn直接计算,无需手动构建列联表):
from sklearn.metrics import adjusted_rand_score # 示例:两个聚类标签数组(长度需一致) cluster_labels_a = [0, 0, 1, 1, 2, 2, 3] cluster_labels_b = [1, 1, 0, 0, 2, 2, 3] ari_score = adjusted_rand_score(cluster_labels_a, cluster_labels_b) print(f"Adjusted Rand Index: {ari_score:.4f}")
2. 归一化互信息(Normalized Mutual Information, NMI)
基于信息论的指标,衡量两个聚类结果之间的互信息,并做了归一化处理,取值范围是[0, 1]:
- 1表示两个聚类完全一致
- 0表示两个聚类无任何关联
它支持聚类数量不同的场景(比如你的8x6列联表情况),非常灵活。
Python实现:
from sklearn.metrics import normalized_mutual_info_score nmi_score = normalized_mutual_info_score(cluster_labels_a, cluster_labels_b) print(f"Normalized Mutual Information: {nmi_score:.4f}")
3. Fowlkes-Mallows指数(FMI)
计算两个聚类结果的精确率和召回率的几何平均值,取值范围[0, 1],同样适合聚类数量不同的场景,对不平衡聚类的鲁棒性较好。
Python实现:
from sklearn.metrics import fowlkes_mallows_score fmi_score = fowlkes_mallows_score(cluster_labels_a, cluster_labels_b) print(f"Fowlkes-Mallows Index: {fmi_score:.4f}")
4. Cramér's V系数(卡方检验的替代方案)
如果你还是想基于列联表分析,Cramér's V是卡方统计量的归一化版本,解决了卡方值随列联表维度增大而膨胀的问题,同时也能在单元格数值较小时衡量分类变量的关联强度,取值范围[0, 1]:
- 1表示两个聚类标签完全相关
- 0表示无关联
Python实现:
from scipy.stats import chi2_contingency import numpy as np # 先构建列联表(示例为3x3表,替换成你的实际数据) contingency_table = np.array([ [5, 0, 0], [0, 6, 1], [0, 2, 7] ]) chi2, p_val, dof, expected = chi2_contingency(contingency_table) total_samples = contingency_table.sum() min_dimension = min(contingency_table.shape) - 1 # 取行/列数较小的那个减1 cramers_v = np.sqrt(chi2 / (total_samples * min_dimension)) print(f"Cramér's V Coefficient: {cramers_v:.4f}")
方法选择建议
- 如果你的两个聚类结果的簇数量相同,ARI和NMI都是首选,解释性强且计算简单;
- 如果簇数量不同(比如8x6的情况),NMI或FMI更合适;
- 如果需要基于列联表做分析,Cramér's V是卡方检验的理想替代,无需担心单元格过小的限制(它是衡量关联强度而非做显著性检验)。
内容的提问来源于stack exchange,提问作者Ryszard Tuora




