2. ARI的定义与数学原理
调整兰德指数,简称 ARI,是聚类评估里出场率最高的指标之一。我个人觉得,想用好 ARI,得先搞明白它的前身——兰德指数。这一节我们把公式拆开揉碎,看看它到底在算什么,以及那个“调整”到底调了什么。
2.1 从兰德指数说起
兰德指数(Rand Index, RI)的逻辑很直白:把所有样本对拎出来,数一数在真实划分和预测划分下,哪些样本对“意见一致”。
对于 N 个样本,一共有 C(N, 2) 个样本对。每个样本对会出现四种情况:
- a:两种划分下都属于同一类
- b:真实划分下属于同一类,预测划分下不属于
- c:真实划分下不属于同一类,预测划分下属于
- d:两种划分下都不属于同一类
兰德指数的公式就出来了:
RI = (a + d) / (a + b + c + d) = (a + d) / C(N, 2)
说白了,RI 就是“一致的样本对”占总样本对的比例。值越高,说明聚类结果和真实标签越吻合。
但 RI 有个明显的 bug——它对随机聚类基本没有惩罚。你想想看,哪怕聚类结果是瞎蒙的,RI 也不会归零,而是会趋近一个正数。这就导致我们很难判断“0.8 的 RI 到底算好还是不好”。
我记得第一次用 RI 评估聚类时,算出来 0.75,还挺开心。后来试了试随机标签,发现也能跑到 0.6 以上……嗯,从那以后我就老老实实用 ARI 了。
2.2 为什么要加“调整”
ARI 的核心思路就一句话:减去随机期望,再除以最大可能调整幅度。
公式长这样:
ARI = (RI - E[RI]) / (max(RI) - E[RI])
因为 max(RI) = 1,所以可以简化为:
ARI = (RI - E[RI]) / (1 - E[RI])
这么一调,随机划分的 ARI 就归零了。值为正说明聚类效果优于随机,为负说明比随机还差。我个人习惯把 ARI 理解成“扣除了运气成分之后的一致性分数”——和机器学习里 R² 的调整思路其实异曲同工。
2.3 ARI 的公式推导
要推导 ARI,得先引入列联表。假设真实划分有 R 个类别,预测划分有 C 个类别,构建一个 R × C 的列联表:
| V₁ | V₂ | … | V_C | 行和 | |
|---|---|---|---|---|---|
| U₁ | n₁₁ | n₁₂ | … | n₁_C | a₁ |
| U₂ | n₂₁ | n₂₂ | … | n₂_C | a₂ |
| … | … | … | … | … | … |
| U_R | n_R₁ | n_R₂ | … | n_RC | a_R |
| 列和 | b₁ | b₂ | … | b_C | N |
n_ij 表示真实类别 i 中被预测为类别 j 的样本数。a_i 是第 i 行的和,b_j 是第 j 列的和。接下来用组合数表示 a、b、c、d:
- a = Σ_ij C(n_ij, 2) —— 两种划分下都属同类的样本对数
- b = Σ_i C(a_i, 2) – a —— 真实划分下同类但预测划分下不同类的样本对数
- c = Σ_j C(b_j, 2) – a —— 真实划分下不同类但预测划分下同类的样本对数
- d = C(N, 2) – a – b – c —— 两种划分下都不同类的样本对数
通过代数变换,兰德指数的组合数形式为:
RI = [Σ_ij C(n_ij, 2) + (C(N,2) – Σ_i C(a_i,2) – Σ_j C(b_j,2) + Σ_ij C(n_ij,2))] / C(N,2)
= [2·Σ_ij C(n_ij,2) – Σ_i C(a_i,2) – Σ_j C(b_j,2) + C(N,2)] / C(N,2)
下一步是算期望。在随机划分假设下,列联表服从超几何分布,因此:
E[Σ_ij C(n_ij,2)] = [Σ_i C(a_i,2) · Σ_j C(b_j,2)] / C(N,2)
把上面几块拼起来,就得到 ARI 的完整公式:
ARI = (Σ_ij C(n_ij,2) – [Σ_i C(a_i,2)·Σ_j C(b_j,2)] / C(N,2)) /
(0.5·(Σ_i C(a_i,2) + Σ_j C(b_j,2)) – [Σ_i C(a_i,2)·Σ_j C(b_j,2)] / C(N,2))
公式看着确实有点吓人。但我建议你抓核心:分子是“实际一致性减去随机期望”,分母是“最大可能一致性减去随机期望”。
adjusted_rand_score 一行就搞定。但理解推导过程能帮你判断什么时候该用它,什么时候该换其他指标。
2.4 公式含义解读
把 ARI 的公式拆成三块来看:
- Σ_ij C(n_ij, 2):真实值和预测值都认为属于同一类的样本对数量。这是“一致”的部分。
- Σ_i C(a_i, 2) · Σ_j C(b_j, 2) / C(N, 2):随机划分下“一致”样本对的期望数量。这是“运气”的部分。
- 0.5 · (Σ_i C(a_i, 2) + Σ_j C(b_j, 2)):理想情况下“一致”样本对的最大可能数量。
ARI 的取值有几个关键点位:
- ARI = 1:完美匹配,两个划分完全相同。
- ARI = 0:相当于随机划分,没有信息量。
- ARI < 0:比随机还差,通常是个警示信号。
- ARI 的最大值不超过 1,最小值可能小于 –1(极端情况下)。
我曾经在一个项目里遇到过 ARI 为负的情况。排查后发现聚类数设得太多,把本就稀疏的数据切得更碎了。所以看到负值时,别急着怀疑算法,先检查参数设置。
2.5 一个手动计算案例
看个简单的例子。6 个样本,真实标签和聚类结果如下:
样本: 1 2 3 4 5 6
真实: A A A B B B
聚类: X X Y Y Y Y
列联表:
X Y
A 2 1
B 0 3
手算各项:
- C(6, 2) = 15
- ΣC(n_ij, 2) = C(2,2) + C(1,2) + C(0,2) + C(3,2) = 1 + 0 + 0 + 3 = 4
- ΣC(a_i, 2) = C(3,2) + C(3,2) = 3 + 3 = 6
- ΣC(b_j, 2) = C(2,2) + C(4,2) = 1 + 6 = 7
RI = 4 / 15 ≈ 0.267
E[RI] = (6 × 7) / 15² = 42 / 225 ≈ 0.187
ARI = (4 – 42/15) / (0.5 × (6 + 7) – 42/15)
= (4 – 2.8) / (6.5 – 2.8)
= 1.2 / 3.7
≈ 0.324
这个例子中 ARI 只有 0.324,说明聚类效果很一般。你想想看,6 个样本里只正确分出了部分,确实不怎么样。
2.6 使用 ARI 的几点建议
- 样本量不要太少:N 很小时,ARI 的方差会很大,结果不可靠。我一般建议 N > 50 再使用 ARI。
- 类别数不要太多:当类别数接近样本数时,ARI 会趋近于 0,区分度明显下降。
- 不平衡类别要小心:如果某个类别只有 1–2 个样本,组合数会变成 0,影响计算结果。
- 配合其他指标使用:ARI 只衡量“一致性”,不衡量“质量”。我习惯同时看 NMI 和轮廓系数。
核心回顾:
- ARI = (RI – E[RI]) / (1 – E[RI]),扣除了随机运气成分。
- 取值范围 [–1, 1],0 代表随机,正值优于随机,负值需警惕。
- 基于列联表和组合数计算,对类别数和不平衡数据比较敏感。