scikit-learn中聚类的混淆矩阵

7
我有一组带已知标签的数据。我想尝试聚类并查看是否可以得到与已知标签相同的聚类。为了衡量准确性,我需要获得类似混淆矩阵的东西。
我知道可以很容易地针对分类问题的测试集获取混淆矩阵。我已经尝试过像这样的方法 this
然而,它不能用于聚类,因为它期望列和行都具有相同的标签集,这对于分类问题是有意义的。但对于聚类问题,我期望的是像这样的东西。
行-实际标签 列-新的聚类名称(即cluster-1、cluster-2等)
有没有办法做到这一点?
编辑:这里有更多细节。
sklearn.metrics.confusion_matrix中,它期望y_testy_pred具有相同的值,并且labels是这些值的标签。因此,它会给出一个矩阵,其行和列都具有相同的标签,如下所示。

enter image description here

但在我的情况下(KMeans聚类),真实值是字符串,估计值是数字(即簇编号)。
因此,如果我调用confusion_matrix(y_true, y_pred)会出现以下错误。
ValueError: Mix of label input types (string and number)

这是一个实际问题。对于分类问题来说,这是有意义的。但对于聚类问题,这个限制不应该存在,因为真实标签名和新聚类名不需要相同。
通过这个,我理解我正在尝试使用一个本应用于分类问题的工具来解决聚类问题。那么,我的问题是,是否有一种方法可以为我的聚类数据获取这样的矩阵。
希望问题现在更清晰了。如果还不清楚,请告诉我。

请用一个示例样本来澄清这个问题。 - Vivek Kumar
添加了更多细节。谢谢。 - Bee
所以,除非你知道如何将群集编号映射到实际结果,否则你该如何继续? - Vivek Kumar
那个映射部分正是我想学习的。我只想知道真实标签和自然聚类数是否可以映射。如果我可以在列中获得真实标签和在行中获得聚类名称(或反之亦然),我就可以自己做到这一点。以Iris数据集为例,我想知道每个新聚类中有多少setosas、多少virginica等。你明白我在寻找什么吗? - Bee
1
请查看scikit-learn文档中关于聚类性能评估的章节(例如,调整兰德指数,归一化/调整互信息,V-measure)。 - σηγ
谢谢,我已经在做了。我只是想看看我的原始标签在新聚类中是如何分布的。 - Bee
2个回答

2
我自己写了一段代码。
# Compute confusion matrix
def confusion_matrix(act_labels, pred_labels):
    uniqueLabels = list(set(act_labels))
    clusters = list(set(pred_labels))
    cm = [[0 for i in range(len(clusters))] for i in range(len(uniqueLabels))]
    for i, act_label in enumerate(uniqueLabels):
        for j, pred_label in enumerate(pred_labels):
            if act_labels[j] == act_label:
                cm[i][pred_label] = cm[i][pred_label] + 1
    return cm

# Example
labels=['a','b','c',
        'a','b','c',
        'a','b','c',
        'a','b','c']
pred=[  1,1,2,
        0,1,2,
        1,1,1,
        0,1,2]
cnf_matrix = confusion_matrix(labels, pred)
print('\n'.join([''.join(['{:4}'.format(item) for item in row])
      for row in cnf_matrix]))

编辑: (哇塞) 刚刚发现可以使用 Pandas Crosstab 轻松实现 :-/。

labels=['a','b','c',
        'a','b','c',
        'a','b','c',
        'a','b','c']
pred=[  1,1,2,
        0,1,2,
        1,1,1,
        0,1,2]   

# Create a DataFrame with labels and varieties as columns: df
df = pd.DataFrame({'Labels': labels, 'Clusters': pred})

# Create crosstab: ct
ct = pd.crosstab(df['Labels'], df['Clusters'])

# Display ct
print(ct)

1
使用 NumPy 对代码进行向量化,使其快 10 倍。 - Has QUIT--Anony-Mousse

1
你可以轻松地计算出一对交集矩阵。
但是如果sklearn库已经针对分类用例进行了优化,可能需要自己操作。

谢谢,我只是在看是否有现成的方法可以做到这一点,而不是自己编写。 - Bee
1
肯定存在这样的实现。例如在图形上,通常有相似性而不是距离。但是在某些时候,编写这些内容自己变得更容易,而不是过多地混合不同的库,然后一次性受到它们所有的错误的影响。 - Has QUIT--Anony-Mousse
我自己写了这个并作为一个独立的答案发布。 - Bee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接