scikit-learn 中聚类的混淆矩阵
Confusion matrix for Clustering in scikit-learn
我有一组带有已知标签的数据。我想尝试聚类,看看是否可以获得已知标签给出的相同聚类。为了衡量准确性,我需要得到类似混淆矩阵的东西。
我知道我可以很容易地得到一个分类问题测试集的混淆矩阵。我已经试过了 this。
但是,它不能用于聚类,因为它期望列和行都具有相同的标签集,这对于分类问题是有意义的。但是对于聚类问题,我期望的是这样的。
Rows - Actual labels
Columns - New cluster names (i.e. cluster-1, cluster-2 etc.)
有办法吗?
编辑:这里有更多细节。
在 sklearn.metrics.confusion_matrix 中,它期望 y_test
和 y_pred
具有相同的值,并且 labels
是这些值的标签。
这就是为什么它给出了一个矩阵,它的行和列都具有相同的标签,就像这样。
但在我的例子中(KMeans 聚类),实际值是字符串,估计值是数字(即聚类数)
因此,如果我调用 confusion_matrix(y_true, y_pred)
,它会给出以下错误。
ValueError: Mix of label input types (string and number)
这才是真正的问题。对于分类问题,这是有道理的。但是对于聚类问题,这个限制不应该存在,因为真正的标签名称和新的聚类名称不需要相同。
有了这个,我明白我正在尝试使用一个应该用于分类问题的工具来解决聚类问题。所以,我的问题是,有没有办法为可能的聚类数据得到这样的矩阵。
希望问题现在更清楚了。如果不是,请告诉我。
您可以轻松计算成对交集矩阵。
但如果 sklearn 库已针对分类用例进行了优化,则可能需要您自己执行此操作。
我自己写了一个代码
# 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]))
编辑:
(Dayyyuumm) 刚刚发现我可以用 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)
我有一组带有已知标签的数据。我想尝试聚类,看看是否可以获得已知标签给出的相同聚类。为了衡量准确性,我需要得到类似混淆矩阵的东西。
我知道我可以很容易地得到一个分类问题测试集的混淆矩阵。我已经试过了 this。
但是,它不能用于聚类,因为它期望列和行都具有相同的标签集,这对于分类问题是有意义的。但是对于聚类问题,我期望的是这样的。
Rows - Actual labels
Columns - New cluster names (i.e. cluster-1, cluster-2 etc.)
有办法吗?
编辑:这里有更多细节。
在 sklearn.metrics.confusion_matrix 中,它期望 y_test
和 y_pred
具有相同的值,并且 labels
是这些值的标签。
这就是为什么它给出了一个矩阵,它的行和列都具有相同的标签,就像这样。
但在我的例子中(KMeans 聚类),实际值是字符串,估计值是数字(即聚类数)
因此,如果我调用 confusion_matrix(y_true, y_pred)
,它会给出以下错误。
ValueError: Mix of label input types (string and number)
这才是真正的问题。对于分类问题,这是有道理的。但是对于聚类问题,这个限制不应该存在,因为真正的标签名称和新的聚类名称不需要相同。
有了这个,我明白我正在尝试使用一个应该用于分类问题的工具来解决聚类问题。所以,我的问题是,有没有办法为可能的聚类数据得到这样的矩阵。
希望问题现在更清楚了。如果不是,请告诉我。
您可以轻松计算成对交集矩阵。
但如果 sklearn 库已针对分类用例进行了优化,则可能需要您自己执行此操作。
我自己写了一个代码
# 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]))
编辑: (Dayyyuumm) 刚刚发现我可以用 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)