聚类性能评估中随机标记的影响

在聚类分析中,评估指标的选择对于衡量聚类算法的性能至关重要。本文通过实验探讨了随机标记对一些聚类评估指标的影响。实验分为两部分:第一部分固定了真实的标签(即固定的类别数量),而预测标签是随机生成的;第二部分则变化真实的标签,同时预测标签也是随机生成的,且预测标签的类别数量和聚类数量与真实标签相同。

评估指标的定义

聚类算法本质上是无监督学习方法。然而,由于在本例中为合成的聚类分配了类别标签,因此可以使用利用这些“监督”真实信息的评估指标来量化所产生聚类的质量。以下是一些这样的指标:

  • V-measure:完整性和同质性的调和平均值;
  • Rand指数:衡量数据点对根据聚类算法的结果和真实类别分配一致分组的频率;
  • 调整后的Rand指数(ARI):对随机聚类分配的期望值为0.0的机会调整后的Rand指数;
  • 互信息(MI):一个信息论度量,量化两个标记的依赖程度。对于完美的标记,MI的最大值取决于聚类的数量和样本数;
  • 归一化互信息(NMI):在大量数据点的极限下,互信息定义在0(无互信息)和1(标签分配完全匹配,标签的排列除外)之间。它没有调整机会,因此如果聚类数据点的数量不够大,随机标记的MI或NMI的期望值可以显著非零;
  • 调整后的互信息(AMI):类似于ARI,随机聚类分配的期望值为0.0的机会调整后的互信息。

更多信息,请参见聚类性能评估模块。

第一次实验:固定真实标签和不断增长的聚类数量

首先定义了一个函数,用于创建均匀分布的随机标记。然后,使用这个函数创建一组固定的真实标签(labels_a),并在n_clusters的值变化时,对多组随机“预测”标签(labels_b)进行评分,以评估给定指标在给定n_clusters下的变异性。

from sklearn import metrics score_funcs = [ ("V-measure", metrics.v_measure_score), ("Rand index", metrics.rand_score), ("ARI", metrics.adjusted_rand_score), ("MI", metrics.mutual_info_score), ("NMI", metrics.normalized_mutual_info_score), ("AMI", metrics.adjusted_mutual_info_score), ]

在第一个示例中,将类别数量(真实的聚类数量)设置为n_classes=10。聚类数量在n_clusters_range提供的值范围内变化。

import numpy as np rng = np.random.RandomState(0) def random_labels(n_samples, n_classes): return rng.randint(low=0, high=n_classes, size=n_samples) def fixed_classes_uniform_labelings_scores(score_func, n_samples, n_clusters_range, n_classes, n_runs=5): scores = np.zeros((len(n_clusters_range), n_runs)) labels_a = random_labels(n_samples=n_samples, n_classes=n_classes) for i, n_clusters in enumerate(n_clusters_range): for j in range(n_runs): labels_b = random_labels(n_samples=n_samples, n_classes=n_clusters) scores[i, j] = score_func(labels_a, labels_b) return scores

在这次实验中,观察到,当n_clusters大于n_classes时,Rand指数趋于饱和。其他未调整的指标,如V-Measure,显示出聚类数量和样本数量之间的线性依赖关系。而调整后的机会指标,如ARI和AMI,显示出围绕0.0的均值分数的一些随机变化,与样本和聚类的数量无关。

第二次实验:变化的类别和聚类数量

在本节中,定义了一个类似的函数,使用多个指标对两个均匀分布的随机标记进行评分。在这种情况下,类别数量和分配的聚类数量对于n_clusters_range中的每个可能值都是匹配的。

def uniform_labelings_scores(score_func, n_samples, n_clusters_range, n_runs=5): scores = np.zeros((len(n_clusters_range), n_runs)) for i, n_clusters in enumerate(n_clusters_range): for j in range(n_runs): labels_a = random_labels(n_samples=n_samples, n_classes=n_clusters) labels_b = random_labels(n_samples=n_samples, n_classes=n_clusters) scores[i, j] = score_func(labels_a, labels_b) return scores

在这种情况下,使用n_samples=100来展示拥有与样本数量相似或相等的聚类数量的效果。

n_samples = 100 n_clusters_range = np.linspace(2, n_samples, 10).astype(int)

观察到与第一次实验相似的结果:调整后的机会指标保持在接近零的水平,而其他指标随着更细粒度的标记而趋于增大。随机标记的平均V-measure随着聚类数量接近用于计算该度量的总样本数而显著增加。此外,原始的互信息没有上限,其尺度取决于聚类问题的维度和真实类别的基数。这就是为什么曲线会超出图表的原因。

因此,只有调整后的机会指标可以安全地用作共识指数,以评估给定k值的聚类算法在数据集的各种重叠子样本上的平均稳定性。未调整的聚类评估指标可能会产生误导,因为它们对于细粒度的标记输出大值,人们可能会认为标记捕获了有意义的组,而它们可能完全是随机的。特别是,这样的未调整指标不应用来比较输出不同聚类数量的不同聚类算法的结果。

脚本的总运行时间

(0分钟1.055秒)

下载Jupyter笔记本:

下载Python源代码:

  • DBSCAN聚类算法演示
  • 使用k-means聚类文本文档
  • 亲和力传播聚类算法演示
  • 使用不同指标的聚合聚类
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485