计算两个聚类结果的聚类精度

Calculate cluster accuracy of two clustering outcomes

假设我有两个如下所示的聚类结果:

clustering = [[8, 9, 10, 11], [14, 13, 4, 7, 6, 12, 5, 15], [1, 2, 0, 3]]
correct_clustering = [[2, 8, 10, 0, 15], [12, 13, 9, 14], [11, 3, 5, 1, 4, 6, 7]]

我将如何比较 clustering 中包含的结果与 correct_clustering 中包含的结果。我想要一个介于 0 和 1 之间的数字。我正在考虑计算在同一簇中正确聚集在一起的对的分数。但是想不出一个程序化的方法来解决这个问题。

您可以在sklearn中使用函数adjusted_rand_score:

from sklearn.metrics import adjusted_rand_score

clustering = sorted((i, num) for num, lst in enumerate(clustering) for i in lst)
clustering = [i for _, i in clustering]
# [2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1]

correct_clustering = sorted((i, num) for num, lst in enumerate(correct_clustering) for i in lst)
correct_clustering = [i for _, i in correct_clustering]
# [0, 2, 0, 2, 2, 2, 2, 2, 0, 1, 0, 2, 1, 1, 1, 0]

ari = adjusted_rand_score(correct_clustering, clustering)
# -0.012738853503184737

函数 returns 的值介于 1 和 -1 之间,因此要获得介于 0 和 1 之间的值,您需要重新缩放:

ari_scaled = (ari + 1) / 2
# 0.49363057324840764

最佳实践措施确实基于配对计数。

特别是调整后的兰特指数 (ARI) 是这里的标准衡量标准。

您实际上并没有计算对数,但是可以使用二项式简单地计算集合中的对数,只需(n*(n-1))>>2.

每个集群和每个集群交集都需要这个。

聚合了所有交集的结果,很容易看出这对于簇的排列(以及因此对于簇标签)是不变的。兰德指数是预测两个对象a,b是在同一个簇中,还是在不同簇中的准确率。 ARI 通过调整机会改进了这一点:在一个非常不平衡的问题中,随机结果可以获得很高的准确性,但在 ARI 中它平均接近于 0。

使用兰德指数:

import numpy as np
from scipy.special import comb

def rand_index_score(clusters, classes):

    tp_plus_fp = comb(np.bincount(clusters), 2).sum()
    tp_plus_fn = comb(np.bincount(classes), 2).sum()
    A = np.c_[(clusters, classes)]
    tp = sum(comb(np.bincount(A[A[:, 0] == i, 1]), 2).sum()
             for i in set(clusters))
    fp = tp_plus_fp - tp
    fn = tp_plus_fn - tp
    tn = comb(len(A), 2) - tp - fp - fn
    return (tp + tn) / (tp + fp + fn + tn)

clusters = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]

classes = [0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 2, 1, 0, 2, 2, 2, 0]

rand_index_score(clusters, classes)
0.6764705882352942