图谱连接

草稿

纯度(Purity)

让每个预测簇只按其中最多的参考标签得分,快速评价聚类是否“干净”。

concept beginner machine-learningmetricsclustering

问题入口:簇名本身没有含义

聚类算法把 8 张学习卡片分成若干簇。老师手里还有参考答案:每张卡片真实属于 graphtreehash

算法输出的簇名 ABCD 是任意的。不能因为名字叫 A,就把它当成某个真实类别。

参考标签与聚类结果簇名是任意的,真正要比较的是样本归属。
Ada

参考标签:图(graph)

簇:A

Ben

参考标签:图(graph)

簇:A

Cy

参考标签:图(graph)

簇:B

Di

参考标签:树(tree)

簇:B

Eli

参考标签:树(tree)

簇:C

Fay

参考标签:树(tree)

簇:C

Gus

参考标签:哈希(hash)

簇:D

Han

参考标签:哈希(hash)

簇:D

第一个朴素想法:直接比较簇名

如果把 ABCD 当作类别标签,分数会依赖算法随便取的名字。

这不合理。把簇 A 改名成 Z,聚类质量不应该改变。

核心发明:每个簇找自己的多数标签

纯度(Purity)对每个预测簇问一个局部问题:

这个簇里最多的是哪一种参考标签?

然后把这些多数计数加起来,再除以样本总数。

簇内多数标签账本每个簇只贡献其中数量最多的参考标签计数。
簇 A2/2

多数标签:图(graph)

簇 B1/2

多数标签:图(graph)

簇 C2/2

多数标签:树(tree)

簇 D2/2

多数标签:哈希(hash)

Purity7/8 = 0.875

列联表:4 个簇 × 3 个参考标签。

形式化版本

C_k 是第 k 个预测簇,L_j 是第 j 个参考标签,n 是样本数。

Purity=1nkmaxjCkLj\text{Purity}=\frac{1}{n}\sum_k \max_j |C_k \cap L_j|

直观读法:每个簇只保留其中最大的那堆参考标签。

在固定样本中:

2+1+2+28=78=0.875\frac{2 + 1 + 2 + 2}{8}=\frac{7}{8}=0.875

交互实验台

切换预设,比较纯度、Rand 指数、调整 Rand 指数和 Fowlkes-Mallows 指数的反应。

聚类指标预设实验台

说明: 一个混合簇和两个被拆开的真实类别会让纯度看起来高,但成对指标会暴露损失。

纯度0.875

7/8

Rand 指数0.821

23/28

调整 Rand 指数0.444

S=3, E=1

Fowlkes-Mallows 指数0.567

pair P=0.75, pair R=0.429

TP3
FP1
FN4
TN20

无脚本静态表:

纯度的簇贡献
多数标签贡献
Agraph2/2
Bgraph1/2
Ctree2/2
Dhash2/2

纯度的问题:过度拆分也会很高

纯度奖励“干净”的簇,但它对拆得太碎的情况惩罚不够。

如果每个样本都单独成簇,那么每个簇都是纯的,纯度会变成 1.0。这并不代表算法找回了有用的组。

预设对比过度拆分和过度合并会让四个指标产生不同反应。
固定样本

Purity: 0.875

RI: 0.821

ARI: 0.444

FMI: 0.567

完全匹配

Purity: 1

RI: 1

ARI: 1

FMI: 1

单点过度拆分

Purity: 1

RI: 0.75

ARI: 0

FMI: 不可用

全部合并

Purity: 0.375

RI: 0.25

ARI: 0

FMI: 0.5

实现草图

function purity(items: { cluster: string; label: string }[]) {
  const counts = new Map<string, Map<string, number>>();

  for (const item of items) {
    const row = counts.get(item.cluster) ?? new Map<string, number>();
    row.set(item.label, (row.get(item.label) ?? 0) + 1);
    counts.set(item.cluster, row);
  }

  let kept = 0;
  for (const row of counts.values()) {
    kept += Math.max(...row.values());
  }

  return items.length === 0 ? null : kept / items.length;
}

复杂度

构建“簇 × 标签”的计数表需要 O(n) 时间。额外空间是 O(rc),其中 r 是实际出现的预测簇数,c 是实际出现的参考标签数。

常见误区

  • 纯度是外部聚类指标,因为它需要参考标签。
  • 纯度不是准确率:簇名是任意的,每个簇要先找自己的多数标签。
  • 高纯度不一定代表好聚类,尤其是过度拆分时。
聚类指标路径先看簇内多数,再转向样本对计数与成对正例平衡。
1. 纯度

purity

2. Rand 指数

rand-index

3. 调整 Rand 指数

adjusted-rand-index

4. Fowlkes-Mallows 指数

fowlkes-mallows-index

练习

  1. 固定样本中,哪个簇只贡献了 1/2
  2. 为什么单点过度拆分能得到纯度 1.0
  3. 如果把簇 CD 合并,纯度会怎样变化?

图谱连接 : 纯度