Сгруппируйте n точек в k кластеров равного размера [дубликат]

Возможный дубликат:
Вариант алгоритма K-средних с одинаковым размером кластера

РЕДАКТИРОВАТЬ: как и casperOne, указывают мне, что этот вопрос является дубликатом. В любом случае, вот более общий вопрос, который охватывает этот: https://stats.stackexchange.com/questions/8744/clustering-procedure-where-each-cluster-has-an-equal-number-of-points

Мои требования

В проекте мне нужно сгруппировать n точек (x, y) в k кластеров одинакового размера (n / k). Где x и y - двойные числа с плавающей запятой, n может находиться в диапазоне от 100 до 10000, а k может находиться в диапазоне от 2 до 100. Также k известно до запуска алгоритма.

Мои эксперименты

Я начал решать проблему, используя алгоритм http://en.wikipedia.org/wiki/K-means_clustering , который отлично и быстро дает ровно k кластеров. примерно такого же размера.

Но моя проблема в том, что K-средства создают кластеры примерно одинакового размера, где мне нужно, чтобы кластеры были точно такого же размера (или, если быть более точным: мне нужно, чтобы они имели размер между этажами (n / k) и ceil (n / k)).

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

Основная идея состоит в том, чтобы постобработать массив созданных кластеров с помощью K-средних. От самого большого кластера до самого маленького.Мы уменьшаем размер кластеров, которые имеют более n / k членов, перемещая дополнительные точки в другой ближайший кластер. Оставив в покое кластеры, которые уже уменьшились.

Вот реализованный мной псевдокод:

n is the number of point
k is the number of cluster
m = n / k (the ideal cluster size)
c is the array of cluster after K-means
c' = c sorted by size in descending order
for each cluster i in c' where i = 1 to k - 1
    n = size of cluster i - m (the number of point to move)
    loop n times
        find a point p in cluster i with minimal distance to a cluster j in c' where j > i
        move point p from cluster i to cluster j
    end loop
    recalculate centroids
end for each

Проблема с этим алгоритмом заключается в том, что ближе к концу процесса (когда я приближаюсь к k) мы должны выбрать кластер j в c '(где j> i, потому что нам нужно оставить в покое уже обработанные кластеры), но этот кластер j, который мы нашли, может быть далеко от кластера i, тем самым нарушая концепцию кластера.

Мой вопрос

Существует ли пост-алгоритм K-средних или вариант K-средних, который может удовлетворить мои требования, или я ошибся с самого начала и мне нужно найти другой алгоритм кластеризации?

PS: Я не против реализовать решение самостоятельно, но было бы здорово, если бы я мог использовать библиотеку, а в идеале - на JAVA.

22
задан Community 23 May 2017 в 12:02
поделиться