adjusted_rand_score用于评估聚类结果与真实标签的相似度,取值范围为[-0.5, 1.0],1.0表示完全一致,0.0表示与随机标记相当,负值表示比随机更差;它只接受等长整数标签,对簇名顺序不敏感,且要求有真实标签才能使用。

直接用 sklearn.metrics.adjusted_rand_score 就行,但必须注意:它只适用于你有真实标签(labels_true)的场景——比如 Iris、Digits 这类带标注的公开数据集,或者你人工打标过的业务数据。没有真实标签时,这个函数根本没法用,别硬套。
为什么不能直接拿聚类结果和原始特征算 ARI
adjusted_rand_score 的输入只能是两组整数标签:一组是真实类别(如 [0, 0, 1, 1, 2, 2]),另一组是模型输出的簇编号(如 [0, 0, 1, 1, 2, 2] 或 [1, 1, 0, 0, 2, 2])。它不接受原始数据 X、距离矩阵、嵌入向量,也不接受字符串标签(得先用 LabelEncoder 转成 int)。
常见错误现象:
- 传入
y_pred是浮点型簇中心坐标,报ValueError: Unknown label type: 'continuous' - 传入
y_true是字符串(如['cat', 'cat', 'dog']),报TypeError: Expected array-like (array or non-string sequence) - 两个标签长度不一致,直接
ValueError: Found array with dim 3. Expected dim = 2(其实是长度不匹配)
adjusted_rand_score 对标签顺序完全不敏感
它只看“哪些样本被分到了同一组”,不关心组名叫 0 还是 99。这意味着:
立即学习“Python免费学习笔记(深入)”;
-
y_true = [0,0,1,1]和y_pred = [5,5,3,3]→ ARI = 1.0 -
y_true = [0,0,1,1]和y_pred = [1,1,0,0]→ ARI = 1.0(组名翻转不影响) -
y_true = [0,0,1,1]和y_pred = [0,1,0,1]→ ARI ≈ -0.33(完全错位,比随机还差)
所以你不需要对 y_pred 做任何重映射(比如用 hungarian_algorithm 对齐簇名),adjusted_rand_score 内部已经处理好了。
实际跑 KMeans 时怎么嵌入 ARI 计算
典型流程就是:拟合 → 预测 → 对比真实标签。关键点在于确保 y_true 和 y_pred 是等长、同类型、非空的一维数组:
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score
<h1>假设你已有带标签的数据(如 Iris)</h1><p>X, y_true = iris.data, iris.target # y_true 是 0/1/2 整数</p><p>kmeans = KMeans(n_clusters=3, random_state=42)
y_pred = kmeans.fit_predict(X) # 输出也是 0/1/2 整数</p><p>ari = adjusted_rand_score(y_true, y_pred)
print(f"ARI: {ari:.3f}") # 输出类似 0.730
注意:
- 如果
n_clusters设得和真实类别数不一致(比如 Iris 真实是 3 类,你设n_clusters=4),ARI 仍可计算,但值通常会下降; - DBSCAN 返回的
y_pred可能含 -1(噪声点),adjusted_rand_score能正常处理,-1 会被当作一个独立簇; - 不要在训练集上反复调参并用 ARI 选最优
n_clusters——这属于用测试指标污染训练过程,容易过拟合。
真正容易被忽略的是:ARI 高 ≠ 聚类结果业务可用。比如在用户分群中,ARI=0.8 的划分可能把高价值用户全分进同一个簇,但该簇内部行为差异极大——这时得结合轮廓系数、业务规则再判断。ARI 只回答“和已知标签像不像”,不回答“这个簇有没有意义”。


















