Неясно мне, почему вы хотите переобозначим кластеры на основе упорядочения каждого центроида. Вы можете просто использовать вектор маркировки, который выводится из k-средств для ссылки на кластер/центроид, к которым принадлежит каждая точка.
Тем не менее, первоначальная идея, что вам пришлось сортировать центроиды, является хорошей. Последняя часть вашего кода кажется довольно неэффективной, потому что вы перебираете каждую метку и выполняете переназначение. Одна вещь, которую я мог бы предложить, - это иметь таблицу поиска, в которой ввод является исходной меткой, а вывод - переупорядоченные метки на основе отсортированных центроидов.
Если вы хотите продолжить этот маршрут, вы можете использовать containers.Map
, где ключи являются метками, указанными в порядке сортировки, которые выводятся из sort
, а значения являются переупорядоченными метками ... а именно, вектор, который идет от 1 до нескольких классов, которые у вас есть. Вам нужно сделать это, потому что второй вывод sort
сообщает вам, где каждое значение в исходном массиве будет отображаться в отсортированном результате, поэтому вы должны использовать этот порядок, чтобы правильно выполнять перемаркировку. Кроме того, я бы использовал функцию sortrows
в MATLAB, а не raw sort
. Как вы это делаете, вы сортируете каждый столбец самостоятельно и это даст неправильные центроиды. Это будет работать для изображений в оттенках серого, где у вас будет только одна особенность, а именно оттенки серого, но если вы выходите за рамки серого и, возможно, заходите в RGB или в любое другое цветовое пространство, которое вам нужно, использование raw 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
Так что работает, как мы ожидается ... теперь, если мы покажем исходную карту меток кластера перед сортировкой по центроидам с:
...мы получаем это изображение:
Теперь, если мы запустим через сортировочную логику и отображать центроиды:
imshow(cluster_label, []);
... мы получаем это изображение:
Это работает так, как я ожидал. Потому что центроиды перевернуты, так же как и окраска.
Я не понимаю. Во-первых, что такое «среднее значение» кластера? Поскольку k-средство, как правило, работает в многомерных пространствах, оно кажется мне непонятным. Тогда, каков ваш вопрос? – Ratbert
Среднее значение означает среднее значение этого кластера. В математике оно обозначается mu. Мой вопрос заключается в том, как сделать вывод kmeans, подверженного малой кластерной метке, для кластера с малым средним значением – user3051460
ОК, вы говорите о центроиде кластера, а не о (неопределенном) «среднем значении». Поскольку ваши начальные векторы находятся в 2D, их невозможно сравнивать, как «x больше y», и поэтому вы не можете сравнивать их с «sort». Я думаю, что нет надежды на то, что вы пытаетесь сделать. – Ratbert