Выпуклый корпус / вогнутый корпус для нескольких кластеров данных

Я много читал о рисовании многоугольников вокруг кластеров и понял, что свернуть, возможно, лучший путь вперед. В основном я ищу эластичный многоугольник, чтобы обернуть его вокруг точек кластера.

Мои данные представляют собой матрицу, состоящую из точек x (1-й столбец) и y (2-й столбец), которые сгруппированы в кластеры (3-й столбец). У меня есть 700 таких кластеров, поэтому невозможно построить каждый отдельно.

Есть ли способ выполнить convhull для каждого кластера отдельно, а затем построить каждый из них на одной диаграмме.

введите описание изображения здесь

ИЗМЕНИТЬ

Код, который я написал до сих пор, не может запускать выпуклый корпус для каждого отдельного кластера ...

    [ndata, text, alldata] =  xlsread(fullfile(source_dir));

       [~, y] = sort(ndata(:,end));
       As = ndata(y,:);

       lon = As(:,1); 
       lat = As(:,2);
       cluster = As(:,3);

       %% To find number of points in a cluster (repetitions)
   rep = zeros(size(cluster));

   for j = 1:length(cluster)
       rep(j) = sum(cluster==cluster(j));
   end

   %% Less than 3 points in a cluster are filtered out

   x = lon (rep>3);
   y = lat (rep>3);
   z = cluster (rep>3);

   %% convex hull for each cluster plotted ....hold....then display all.

   figure
   hold on

   clusters = unique(z);

       for i = 1:length(z)

          k=convhull(x(z==clusters(i)), y(z==clusters(i)));

          plot(x, y, 'b.'); %# plot cluster points
          plot(x(k),y(k),'r-'); %# plots only k indices, giving the convex hull


      end

Ниже приведено изображение того, что отображается;

Если этот вопрос уже задавался, прошу прощения за повторение, но, пожалуйста, дайте мне ответ, который вы сочтете нужным.

Пожалуйста, может ли кто-нибудь помочь с этим, как бы тривиально я ни боролся! введите описание изображения здесь


person user3299469    schedule 03.03.2014    source источник
comment
Похоже, это должно быть достаточно просто, если вы разделите данные на 700 наборов точек данных (по одной для каждого кластера). Прогнал алгоритм выпуклой оболочки для каждого кластера, а затем построил получившуюся оболочку.   -  person Nuclearman    schedule 03.03.2014
comment
@Nuclearman да, конечно, но я не очень хорошо разбираюсь в Matlab и не могу его реализовать. Я написал код, но он реализует выпуклую оболочку для всего набора данных, а не для группы. Не знаю, как реализовать это для каждого кластера отдельно. ИЗМЕНИЛ мой вопрос, чтобы добавить код, который у меня есть на данный момент.   -  person user3299469    schedule 04.03.2014
comment
Полагаю, мне следовало ожидать, что проблема будет в незнании. Тогда это проблема, поскольку я тоже не знаком с Matlab (следовательно, комментарий, а не ответ). Однако у вас должна быть возможность сделать это путем сортировки данных по кластерам, чтобы сгруппировать данные по кластерам. Затем используйте цикл for, чтобы просмотреть каждую точку данных и добавить ее в список точек в этом кластере, пока кластер не изменится. Когда это произойдет, постройте и нанесите на график выпуклую оболочку предыдущего списка кластеров и создайте новый список с текущей точкой в ​​нем в качестве начала следующего списка кластеров. Просто убедитесь, что вы построили последний кластер.   -  person Nuclearman    schedule 04.03.2014
comment
Поздравляю. Вы собираетесь написать свою первую нетривиальную программу! Ее можно реализовать с помощью цикла for! Итак, приступим!   -  person Has QUIT--Anony-Mousse    schedule 04.03.2014
comment
Привет, @ Anony-Mousse. Я знаю, что это не сложная проблема, просто я не могу ее реализовать. Если вы можете взглянуть на код и предложить решение, я буду очень признателен. Спасибо   -  person user3299469    schedule 04.03.2014
comment
Я не использую Matlab, потому что считаю его неуклюжим для моих задач. Так что я ничем не могу вам помочь. Есть ли шанс, что x(k) индексируется в неправильный массив (нефильтрованный x вместо x(z==clusters(i))(k))?   -  person Has QUIT--Anony-Mousse    schedule 04.03.2014


Ответы (1)


Я бы перебрал все кластеры и сделал то, что вы уже написали, и использовал бы параметр hold on, чтобы собрать все графики в одном графике. Что-то вроде этого:

% Generate three clouds of points in 2D:
c1 = bsxfun(@plus, 0.5 * randn(50,2), [1 3]);
c2 = bsxfun(@plus, 0.6 * randn(20,2), [0 0]);
c3 = bsxfun(@plus, 0.4 * randn(20,2), [1 1]);

data = [c1, ones(50,1); ...
        c2, 2*ones(20,1); ...
        c3, 3*ones(20,1)];

% Plot the data points with different colors

clf
plot(c1(:,1), c1(:,2),'r+', 'LineWidth', 2);
hold on
plot(c2(:,1), c2(:,2),'k+', 'LineWidth', 2);
plot(c3(:,1), c3(:,2),'b+', 'LineWidth', 2);

x = data(:,1);
y = data(:,2);
cluster = data(:,3);

clusters = unique(cluster);

for i = 1:length(clusters)
    px = x(cluster == clusters(i));
    py = y(cluster == clusters(i));
    if length(px) > 2
        k = convhull(px, py);
        plot(px(k), py(k), '-');
    end
end

Это дает следующий результат: 2D-кластеры и их соответствующая выпуклая оболочка

person Gastón Bengolea    schedule 03.03.2014
comment
Большое спасибо за это, и я понимаю логику этого скрипта, но когда я запускаю его со своими данными, я получаю сообщение об ошибке ??? Ошибка при использовании == ›convhull Ошибка вычисления выпуклой оболочки. Указано недостаточно уникальных точек. Ошибка в == ›cluster_polygon при 21 k = convhull (x (кластер == кластеры (i)), y (кластер == кластеры (i))); - person user3299469; 04.03.2014
comment
Да, похоже, вам нужно как минимум 3 разных точки, но это можно исправить, например, поставив if и проверив, length (cluster == cluster (i)) ›2, а если нет, то сделайте что-то еще (например, не рисование выпуклая оболочка или просто рисование линии, определяемой двумя точками ..) - person Gastón Bengolea; 04.03.2014
comment
Спасибо за правку, так как вы предположили, что я удалил те кластеры с менее чем 3 баллами. Но код по-прежнему не работает так, как я ожидал. Я добавил изображение к вопросу о том, что в данный момент отображается. Не могли бы вы помочь. Большое тебе спасибо. - person user3299469; 04.03.2014
comment
БОЛЬШОЕ СПАСИБО!!! Это сработало, вы действительно очень помогли! Спасибо Вам большое. Хорошего дня!! :) - person user3299469; 04.03.2014