如果有了类别标签,那么聚类结果也可以像分类那样计算准确率和召回率。scikitlearn上说:“其实不应该将分类标签作为聚类结果的评价指标,除非你有相关的先验知识或某种假设,知道这种分类类内差距更小”。但是它还是给出了几种评价标准
1. Adjusted Rand index
1.1 原理及代码实现
和分类中的acc类似,这是在计算样本预测值和真实值之间的相似度
similarity:同属于这一类或都不属于这一类 python实现的代码如下:
labels_true, labels_pred = check_clusterings(labels_true, labels_pred)
n_samples = labels_true.shape[0]
classes = np.unique(labels_true)
clusters = np.unique(labels_pred)
# Special limit cases: no clustering since the data is not split;
# or trivial clustering where each document is assigned a unique cluster.
# These are perfect matches hence return 1.0.
if (classes.shape[0] == clusters.shape[0] == 1
or classes.shape[0] == clusters.shape[0] == 0
or classes.shape[0] == clusters.shape[0] == len(labels_true)):
return 1.0
contingency = contingency_matrix(labels_true, labels_pred)
# Compute the ARI using the contingency data
sum_comb_c = sum(comb2(n_c) for n_c in contingency.sum(axis=1))
sum_comb_k = sum(comb2(n_k) for n_k in contingency.sum(axis=0))
sum_comb = sum(comb2(n_ij) for n_ij in contingency.flatten())
prod_comb = (sum_comb_c * sum_comb_k) / float(comb(n_samples, 2))
mean_comb = (sum_comb_k + sum_comb_c) / 2.
return ((sum_comb - prod_comb) / (mean_comb - prod_comb))
其中contingency_matrix可以参考wiki中的
contingency table,就是把预期和真实一样的同时表示在一个表里,sum_comb_c,sum_comb_k则对应实际这一类有多少样本,预测这一类有多少样本。 计算的其实是
RI = (a + b) / C(n,2) ,
分子:属性一致的样本数,即同属于这一类或都不属于这一类。a是真实在同一类、预测也在同一类的样本数;b是真实在不同类、预测也在不同类的样本数;
分母:任意两个样本为一类有多少种组合
为了保证随机聚类的值能接近于0,才有了如下计算方式:
ARI = (RI - Expected_RI) / (max(RI) - Expected_RI),
1.2 优缺点
优点: 1. 对任意数量的聚类中心和样本数,随机聚类的ARI都非常接近于0; 2. 取值在[-1,1]之间,负数代表结果不好,越接近于1越好; 3. 可用于聚类算法之间的比较 缺点: 1. ARI需要真实标签
2.Mutual Information based scores
2.1 原理及代码实现
真实值,预测值,衡量两种分配方式的agreement。MI是衡量对同一样本给出的两种标签之间的相似性。
计算方式同KL散度一样,计算真实标签中属于某一类的概率与预测标签中属于某一类的概率的互信息的熵。
python代码如下
if contingency is None:
labels_true, labels_pred = check_clusterings(labels_true, labels_pred)
contingency = contingency_matrix(labels_true, labels_pred)
contingency = np.array(contingency, dtype='float')
contingency_sum = np.sum(contingency)
pi = np.sum(contingency, axis=1)
pj = np.sum(contingency, axis=0)
outer = np.outer(pi, pj)
nnz = contingency != 0.0
# normalized contingency
contingency_nm = contingency[nnz]
log_contingency_nm = np.log(contingency_nm)
contingency_nm /= contingency_sum
# log(a / b) should be calculated as log(a) - log(b) for
# possible loss of precision
log_outer = -np.log(outer[nnz]) + log(pi.sum()) + log(pj.sum())
mi = (contingency_nm * (log_contingency_nm - log(contingency_sum))
+ contingency_nm * log_outer)
return mi.sum()
2.2 优缺点
优点:除取值范围在[0,1]之间,其他同ARI;可用于聚类模型选择 缺点:需要先验知识 注:也有AMI,这里Adjusted是指结果不依赖于所选聚类中心和样本数 scikitlearn中有
避免随机性的聚类标准的实例,比较了ARI,AMI,V,在不同数量样本下的聚类结果。随机选取了10个聚类中心(聚类中心数量小于样本数)