我有一个简单的问题,但非常有趣。如您所知,由于随机初始聚类中心,Kmeans在每次运行后可以得到不同的结果。但是,假设我知道群集1的平均值小于群集2,群集2的平均值小于群集3,依此类推。我想制作一个算法来实现该集群具有较小的平均值,然后将其分配给小集群索引。
这是我的Matlab代码。如果你有更多种类或更清晰的方式。请建议我
%% K-mean
num_cluster=2;
nrows = size(Img_original,1);
ncols = size(Img_original,2);
I_1D = reshape(Img_original,nrows*ncols,1);
[cluster_idx mu]=kmeans(double(I_1D),num_cluster,'distance','sqEuclidean','Replicates',3);
cluster_label = reshape(cluster_idx,nrows,ncols);
%% Sort based on mu
[mu_sort id_sort]=sort(mu);
idx=cell(1,num_cluster)
%% Save index of order if mu
for i=1:num_cluster
idx{i}=find(cluster_label==id_sort(i));
end
%% Sort cluster label based on mu
for i=1:num_cluster
cluster_label(idx{i})=i;
end
答案 0 :(得分:1)
我不清楚为什么你想根据每个质心的排序重新标记聚类。您可以简单地使用从k-means输出的标记向量来引用每个点所属的簇/质心。
然而,你必须对质心进行排序的初步想法是一个很好的想法。您的代码的最后一部分看起来效率很低,因为您循环遍历每个标签并进行重新分配。我可以建议的一件事是有一个查找表,其中输入是原始标签,输出是基于排序质心的重新排序标签。
如果您想要使用此路线,可以使用containers.Map
,其中键是从sort
输出的排序顺序给出的标签,值是重新排序的标签。即,一个从1到多个类的向量。您需要执行此操作,因为sort
的第二个输出会告诉您原始数组中的每个值在排序结果中的位置,因此您必须使用此顺序来正确执行重新标记。另外,我会在MATLAB中使用sortrows
函数,而不是原始sort
。根据您的操作方式,您将独立地对每个列/变量进行排序,这将给出错误的质心。这适用于灰度图像,其中您只有一个要考虑的特征,即灰度,但如果您超出灰度并可能进入RGB或您想要的任何颜色空间,使用原始sort
将给您不正确的结果。您需要将每一行视为单个点,然后将这些行联合排序。
鉴于您的代码,您可以执行以下操作:
%% K-mean
num_cluster=2;
nrows = size(Img_original,1);
ncols = size(Img_original,2);
I_1D = reshape(Img_original,nrows*ncols,1);
[cluster_idx mu]=kmeans(double(I_1D),num_cluster,'distance','sqEuclidean','Replicates',3);
%% Sort based on mu
[mu_sort id_sort]=sortrows(mu);
%// New - Create lookup
lookup = containers.Map(id_sort, 1:size(mu_sort,1));
%// Relabel the vector
cluster_idx_sort = lookup.values(num2cell(cluster_idx));
cluster_idx_sort = [cluster_idx_sort{:}];
%// Reshape back to original image dimensions
cluster_label = reshape(cluster_idx_sort,nrows,ncols);
这应该可以为您的代码提供一些加速。
要仔细检查,我在cameraman.tif
图像上尝试了这个,这是图像处理工具箱的一部分。运行代码为我提供了这些集群中心:
>> mu
mu =
153.3484
23.7291
一旦我按升序对集群进行排序,这就是我获得的排序和质心所得:
>> mu_sort
mu_sort =
23.7291
153.3484
>> id_sort
id_sort =
2
1
这样就像我们预期的那样......现在如果我们在对质心进行排序之前显示原始的簇标签图,那么:
cluster_label = reshape(cluster_idx, nrows, ncols);
imshow(cluster_label,[]);
...我们得到这张图片:
现在,如果我们运行排序逻辑并显示质心:
imshow(cluster_label, []);
...我们得到这张图片:
这符合我的预期。因为质心翻转,所以应该着色。