确定 k 均值聚类的准确性

Determining accuracy for k-means clustering

我想使用 sklearns k-means 聚类函数对鸢尾花数据集进行分类(虽然我删除了标签,所以它现在是一个未标记的数据)。我已经制作了预测模型,输出似乎在很大程度上正确地对数据进行了分类,但是它是随机选择标签(0、1 和 2),我无法将它与我自己的标签进行比较以确定准确性(我已将 setosa 标记为 0,versicolor 标记为 1,virginica 标记为 2)。有什么方法可以正确标记花朵?

代码如下:

from sklearn.cluster import KMeans
cluster = KMeans(n_clusters = 3)
cluster.fit(features)
pred = cluster.labels_
score = round(accuracy_score(pred, name_val), 4)
print('Accuracy scored using k-means clustering: ', score)

features,正如预期的那样包含特征,name_val是包含花值的矩阵,0代表setosa,1代表versicolor,2代表virginica

编辑:我想到的一个解决方案是将 random_state 设置为任意数字,以便标签保持不变,还有其他解决方案吗?

首先,您不是在分类,而是在对数据进行聚类。分类是一个不同的过程。

K-Means 算法在选择初始聚类中心时包含随机性。通过设置 random_state 您可以重现相同的聚类,因为初始聚类中心将相同。但是,这不能解决您的问题。你想要的是 id 为 0 的集群是 setosa,1 是 versicolor 等。这是不可能的,因为 K-Means 算法不知道这些类别,它只根据花朵的相似性对花朵进行分组。您可以做的是创建一个规则来确定哪个集群对应于哪个类别。例如,您可以说,如果属于一个簇的超过 50% 的花也属于 setosa 类别,那么该簇的文档应该与 setosa 类别中的文档集进行比较。

这是我能想到的最好的方法。然而,这不是我们评估聚类质量的方式,您可以使用一些指标,例如 Silhouette Coefficient。希望对您有所帮助。

您需要查看 clustering metrics 来评估您的预测,其中包括

  1. Homegenity Score
  2. V measure
  3. Completenss Score 等等

现在以Completeness Score为例,

A clustering result satisfies completeness if all the data points that are members of a given class are elements of the same cluster.

例如

from sklearn.metrics.cluster import completeness_score
print completeness_score([0, 0, 1, 1], [1, 1, 0, 0])
#Output : 1.0

这与您想要的相似。对你来说,代码是 completeness_score(pred, name_val)。这里请注意,分配给数据点的标签并不重要,重要的是它们之间的标签。

另一方面,同质性关注同一集群内数据点的质量。而 V 度量定义为 2 * (homogeneity * completeness) / (homogeneity + completeness)

在这里阅读官方文档:Homogenity, completeness and V-measure

引用自此博客https://smorbieu.gitlab.io/accuracy-from-classification-to-clustering-evaluation/ 您需要使用匈牙利算法从混淆矩阵中获得关系。 代码如下:

from scipy.optimize import linear_sum_assignment as linear_assignment
def cluster_acc(y_true, y_pred):
    cm = metrics.confusion_matrix(y_true, y_pred)
    _make_cost_m = lambda x:-x + np.max(x)
    indexes = linear_assignment(_make_cost_m(cm))
    indexes = np.concatenate([indexes[0][:,np.newaxis],indexes[1][:,np.newaxis]], axis=-1)
    js = [e[1] for e in sorted(indexes, key=lambda x: x[0])]
    cm2 = cm[:, js]
    acc = np.trace(cm2) / np.sum(cm2)
    return acc

或者只导入库 coclust

from coclust.evaluation.external import accuracy
accuracy(labels, predicted_labels)