RI是一种直观的反应归档结果精度的指标,对于原始的数据集中,我们任选两个点p和q,观察他们两个在聚类中的结果,可能会有四种情况:
类似深度学习中的混淆矩阵,我们可以通过计算(TP+TN)/(TP+TN+FP+FN)的方法来计算推理结果的精度,也可以推广到Recall等等。
实际的使用过程中,对于任意的两个点p和q,最大的可能就是原始数据集中p和q不属于同一类,而聚类的结果中p和q中也不属于同一类,也就是说分子和分母中,TN都占了绝大多数的比例,以至于这个数字干扰了我们查看正常的聚类结果,我们可以采用赋权重来调节TN所占的比例。
Adjusted Rand Index亦可以解决上面所说的TN过高的问题,其范围是[-1, 1],越高表示聚类的结果越好,如果聚类的结果倾向于随机分布则会接近0,如果我们的聚类算法总能得到不正确的结果,对于GroundTruth中同一个类的特征向量倾向于将其分入不同的类,对于GroundTruth中不同类的特征向量倾向于将其分为同一个类,那么我们可以得到一个接近-1的Adjusted Rand Index。对于某个数据集上特定一组参数的聚类结果,可以看出Adjusted Rand Index通常比Rand Index更加灵敏,我们更推荐用户使用该指标对聚类结果进行精度评估。
``` from sklearn import metrics def CalcRI(allClusters, groundTruth, thresh = 99999999): ''' Args allClusters: list of list, represent all clusters groundTruth: groundtruth dict thresh: blackhole archive threshold, if one single archive has features more than this value, ignore such archive ''' filteredClusters = [] for arc in allClusters: if len(arc) < thresh: filteredClusters.append(arc) tmpDict = {} for label, cluster in enumerate(filteredClusters): for feat in cluster: tmpDict[feat] = label featLis = list(tmpDict.keys()) featLis.sort() pd = [] gt = [] for feat in featLis: pd.append(tmpDict[feat]) gt.append(int(groundTruth[feat])) print("Start to calculate RI") score = metrics.rand_score(pd, gt) print("Rand Score {}".format(score)) score = metrics.adjusted_rand_score(pd, gt) print("Adjusted Rand Score {}".format(score)) ```