Kuhn-Munkres算法将聚类后的预测标签映射为真实标签

使用Kuhn-Munkres(KM)算法将聚类后的预测标签映射为真实标签

问题:对一部分样本进行聚类,得到了聚类标签,同时这部分数据有真实标签,为了计算聚类之后的准确率,如何将聚类标签数据映射到真实标签数据呢?


Python包的安装:pip install munkres

munkres:假设n个工人完成n个工作,每个工人完成工作的代价不同,一个工作只能由一个工人来完成,一个工人也只能完成一个工作。如matrix所示,有3个工人,第1个工人完成第1个工作需要5天,完成第2个工作需要9天,完成第3个工作需要1天;第2个工人完成第1个工作需要10天,完成第2个工作需要3天,依次类推。问如何将每个工作分配给每个工人(1个工作分配给1个工人),使得总的代价cost最少。

munkres提供了一个方法,通过调用可以实现这个问题,如下代码所示。

munkres库链接:https://pypi.org/project/munkres/

from munkres import Munkres,print_matrix

matrix=[[5,9,1],
        [10,3,2],
        [8,7,4]]
m=Munkres()
indexes=m.compute(matrix)
print(indexes)
print_matrix(matrix,msg='Lowest cost through this matrix')
total=0
for row,column in indexes:
    value=matrix[row][column]
    total+=value
    print('(%d,%d)->%d'%(row,column,value))
print('total cost:%d'%total)

运行结果:

Kuhn-Munkres算法将聚类后的预测标签映射为真实标签_第1张图片


       以COIL20数据集为例,该数据集是一个object datasets,由1440个samples,20个objects组成,每张图片的维度是32*32。该数据集由训练集[‘fea’]和标签集['gnd']组成。labels的数据形式为:

[ 1  1  1 ... 20 20 20]

假设聚类后的标签为:

[ 3  3  3 ... 14 14 14]

使用一下代码可以将预测标签映射为真实标签:

def best_map(L1,L2):
	#L1 should be the labels and L2 should be the clustering number we got
	Label1 = np.unique(L1)       # 去除重复的元素,由小大大排列
	nClass1 = len(Label1)        # 标签的大小
	Label2 = np.unique(L2)       
	nClass2 = len(Label2)
	nClass = np.maximum(nClass1,nClass2)
	G = np.zeros((nClass,nClass))
	for i in range(nClass1):
		ind_cla1 = L1 == Label1[i]
		ind_cla1 = ind_cla1.astype(float)
		for j in range(nClass2):
			ind_cla2 = L2 == Label2[j]
			ind_cla2 = ind_cla2.astype(float)
			G[i,j] = np.sum(ind_cla2 * ind_cla1)
	m = Munkres()
	index = m.compute(-G.T)
	index = np.array(index)
	c = index[:,1]
	newL2 = np.zeros(L2.shape)
	for i in range(nClass2):
		newL2[L2 == Label2[i]] = Label1[c[i]]
	return newL2
def err_rate(gt_s,s):
    print(gt_s)
    print(s)
    c_x=best_map(gt_s,s)
    err_x=np.sum(gt_s[:]!=c_x[:])
    missrate=err_x.astype(float)/(gt_s.shape[0])
    return missrate

       在err_rate(gt_s,s)方法中,gt_s表示真实标签数组,s表示预测标签数组。通过调用best_map(gt_s,s)方法可以得到映射后的标签,然后使用np.sum(gt_s[:]!=c_x[:])可以得到预测错误的标签个数err_x,err_x除以总的标签个数即可以得到错误率,进而可以计算聚类之后的准确率

你可能感兴趣的:(Kuhn-Munkres算法将聚类后的预测标签映射为真实标签)