Участник:LKruglov/Алгоритм устойчивой кластеризации с использованием связей: различия между версиями

Материал из Алговики
Перейти к навигации Перейти к поиску
Строка 95: Строка 95:


  1. Множество <math>n</math> точек, которые необходимо кластеризовать
  1. Множество <math>n</math> точек, которые необходимо кластеризовать
  2. Порогрвое значение <math>\theta</math>
  2. Порогрвое значение <math>\theta</math> из интервала <math>(0, 1)</math>
  3. Требуемое число кластеров <math>k</math>
  3. Требуемое число кластеров <math>k</math>



Версия от 19:52, 15 октября 2016

Общее описание алгоритма

Свойства и структура алгоритма

В связи с наличием огромного количества накопленной информации задача добычи данных становится все более важной. Кластеризация позволяет распределять данные по группам (кластрерам) так, что в каждой группе данные обладают схожими характеристиками, а в разных группах характеристики различаются.

Алгоритм устойчивой кластеризации с использованием связей (robust clustering using links, ROCK) построен на основе понятия связей между кластеризуемыми точками и их соседства. Две точки считаются соседями, если являются достаточно близким (схожими): [math]\displaystyle{ sim({p_i}, {p_j}) \gt = \theta }[/math], где [math]\displaystyle{ \theta }[/math] - заданное пороговое значение в интервале [math]\displaystyle{ (0, 1) }[/math]. Связь [math]\displaystyle{ link({p_i}, {p_j}) }[/math] между двумя точками определяется как число общих соседей между точками [math]\displaystyle{ {p_i} }[/math] и [math]\displaystyle{ {p_j} }[/math]. Таким образом, чем большее значение функции связи для двух точек, тем более вероятно они принадлежат одному кластеру.

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

ROCK принадлежит к классу иерархических алгоритмов кластеризации. На первом этапе работы алгоритма происходит определение соседей для каждой точки и подсчет количества связей для каждой пары точек. Изначально каждая точка рассматривается в качестве отдельного кластера и для каждого такого кластера рассчитываются значения функции качества,которые используются при последующем слиянии кластеров. Далее в ходе итерационного процесса на каждом шаге выбираются и объединяются два кластера и пересчитываются количество связей и функции качества для нового кластера. По достижении требуемого числа кластеров алгоритм завершается.

Математическое описание алгоритма

Задача кластеризации сводится к выделению такого разбиения точек на кластеры, которое максимизирует сумму связей точек принадлежащих одному кластеру, и минимизирует эту функцию для точек из разных кластеров. Таким образом, для разбияния на [math]\displaystyle{ k }[/math] кластеров необходима максимизация следующей функции.

[math]\displaystyle{ E_l = \sum_{i=1}^k n_i * \sum_{p_q, p_r \in C_i} \frac{link(p_q, p_r)}{n_i^{1+2f(\theta)}} }[/math] (1)

Данная функция отличается от простой суммы связей для каждого кластера, так как не обеспечивает распределение точек, имеющих мало связей между собой, по разным кластерам. Поэтому действительную сумму связей в кластере следует разделить на ожидаемую сумму связей. Функция [math]\displaystyle{ f(\theta) }[/math] задается пользователем исходя из свойств обрабатываемых данных и ожидаемого характера кластеризации. Она должна обладать следующим свойством: каждая точка, принадлежащая кластеру [math]\displaystyle{ C_i }[/math], имеет приблизительно [math]\displaystyle{ n_i^{f(\theta)} }[/math] соседей в этом кластере.

Связь между двумя кластерами определяется как

[math]\displaystyle{ link({C_i}, {C_j}) = \sum^{}_{{p_q}\in{C_i}, {p_r}\in{C_j}}{link[{C_i}, {C_j}]} }[/math]

Тогда для выбора кластеров для объединения определяется целевая функция качества:

[math]\displaystyle{ g(C_i, C_j) = \frac{link[C_i, C_j]}{(n_i+n_j)^{1+2f(\theta)} - f_i^{1+2f(\theta)} - f_j^{1+2f(\theta)}} }[/math]

Аналогично целевой функции (1) значение связи между двумя кластерами делится на ожидаемое число связей между кластерами.

Вычислительное ядро алгоритма

Вычислительное ядро алгоритма состоит из двух частей: подсчет количества связей между точками и итеративное объединение кластеров.

Один из возможных подходов к подсчету количества связей основывается на матрице смежности точек: достаточно умножить матрицу смежности на себя, и тогда каждая клетка полученной матрицы будет содержать число связей соответствующей точки.

Итеративная часть алгоритма может быть реализована с помощью структуры данных куча. На каждой итерации с каждым кластером [math]\displaystyle{ i }[/math] связана своя куча [math]\displaystyle{ q[i] }[/math], содержащая все связанный с ним кластеры, упорядоченная по убыванию функции качества. Также поддерживается глобальная куча [math]\displaystyle{ Q }[/math], содержащая все кластеры [math]\displaystyle{ j }[/math], упорядоченные по мере убывания функции качества [math]\displaystyle{ g(j, max(q[j])) }[/math], где [math]\displaystyle{ max(q[j]) }[/math] - это вершина кучи [math]\displaystyle{ q[j] }[/math]. Тогда на каждой итерации объединяются кластер [math]\displaystyle{ j }[/math] с вершины глобальной кучи и кластер [math]\displaystyle{ q[j] }[/math]. После объединения необходимо обновить все кучи, содержащие объединенные кластеры, обновить глобальную кучу [math]\displaystyle{ Q }[/math] и создать кучу для нового кластера. Итеративный процесс продолжается до тех пор, пока в глобальной куче [math]\displaystyle{ Q }[/math] не останется требуемое число кластеров.

Макроструктура алгоритма

Как было описано выше, основную часть каждой итерации алгоритма составляет обновление куч, содержащих сливаемые кластеры.

Схема реализации последовательного алгоритма

Следующая схема последовательного алгоритма представлена в работе [1]:

procedure cluster(S, k)
begin
    link := compute_links(S)
    for s in S do
    begin
        q[s] := build_local_heap(link, s)
    end
    Q := build_global_heap(S, q)
    while size(Q) > k do
    begin
        u := extract_max(Q)
        v := max(q[u])
        delete(Q, v)
        w := merge(u, v)
        for each x in q[u] or q[v] do
        begin
            link[x, w] := link[x, u] + link[x, v]
            delete(q[x], u)
            delete(q[x], v)
            insert(q[x], w, g(x, w))
            insert(q[w], x, g(x, w))
            update(Q, x, q[x])
        end
        insert(Q, w, q[w])
        deallocate(q[u])
        deallocate(q[v])
    end
end

Последовательная сложность алгоритма

Для вычисления количества связей с помощью возведения матрицы в квадрат можно воспользоваться алгоритмом Копперсмита—Винограда, вычислительная сложность которого равна [math]\displaystyle{ O(n^{2,37}) }[/math] [3] ([math]\displaystyle{ n }[/math] - количество точек). Для случаев разреженной матрицы смежности в работе [1] описывается алгоритм, имеющий сложность [math]\displaystyle{ O(n^2 + n{m_m}{m_a}) }[/math], где [math]\displaystyle{ {m_a} }[/math] и [math]\displaystyle{ {m_m} }[/math] - это среднее и максимальное количество соседей точки соответственно.

Каждая куча может быть построена за время [math]\displaystyle{ O(n) }[/math] [4]. Внешний цикл итерационной части алгоритма исполняется [math]\displaystyle{ O(n) }[/math] раз. Так как на очередной итерации размер каждой локальной кучи в худшем случае может равняться [math]\displaystyle{ n }[/math], то новый кластер должен быть помещен в [math]\displaystyle{ n }[/math] локальных куч, что дает временную сложность вложенного цикла [math]\displaystyle{ O(n\log{n}) }[/math]. Таким образом, сложность внешнего цикла в худшем случае будет [math]\displaystyle{ O(n^2\log{n}) }[/math].

Итак, сложность описанного алгоритма будет

[math]\displaystyle{ L + O(n^2\log{n}) }[/math],

где [math]\displaystyle{ L }[/math] - сложность алгоритма вычисления количества связей.

Информационный граф

На рисунке представлен информационный граф алгоритма. Блок L соответствует предварительному подсчету числа связей точек, блок QLs и QG - созданию локальных и глобальной куч соответственно, блок M - слиянию кластеров, блок U - обновлению куч.

TODO

Ресурс параллелизма алгоритма

В описанном последовательном алгоритме основной ресурс параллелизма заключается в возможности параллельного вычисления количества связей (например, используя алгоритм параллельного вычисления произведения матриц), создании очередей, и параллельная обработка локальных очередей во внутреннем цикле итерационного этапа алгоритма.

TODO?

Входные и выходные данные алгоритма

Входные данные:

1. Множество [math]\displaystyle{ n }[/math] точек, которые необходимо кластеризовать
2. Порогрвое значение [math]\displaystyle{ \theta }[/math] из интервала [math]\displaystyle{ (0, 1) }[/math]
3. Требуемое число кластеров [math]\displaystyle{ k }[/math]

Выходные данные:

1. [math]\displaystyle{ k }[/math] полученных кластеров

Свойства алгоритма

Одним из важных вопросов, влияющих на эффективность алгоритма, является выбор исходных точек. Подход к выбору размера исходного набора точек, достаточного для качественной кластеризации, описывается в работе [5]. Использование случайной стратегии выбора исходных точек помогает алгоритму кластеризации отбрасыванием выпадающих точек (то есть точек, слабо связанных с другими точками). Различные алгоритмы случайного выбора исходных точек рассматриваются в работе [6].

Обработка выпадающих точек в рассматриваемом алгоритме обеспечивается выбором порогового значения [math]\displaystyle{ \theta }[/math]. Также такие точки могут быть принудительно отброшены на последних итерациях алгоритма.

После завершения кластеризации выбранных исходных точек, оставшиеся точки распределяются по кластерам следующим образом. Из каждого кластера выбирается набор точек [math]\displaystyle{ {L_i} }[/math], и очередная точка [math]\displaystyle{ p }[/math] помещается в кластер [math]\displaystyle{ i }[/math], если [math]\displaystyle{ p }[/math] имеет наибольшее число соседей множеством [math]\displaystyle{ {L_i} }[/math].

Рассматриваемый алгоритм является детерминированным. Его вычислительная мощность равна

[math]\displaystyle{ \frac{L + O(n^2\log n)}{2n+2} }[/math],

отношение последовательной и параллельной сложности:

[math]\displaystyle{ \frac{L + O(n^2\log n)}{{L_p} + O(\frac{n^2\log n}{p})} }[/math],

где [math]\displaystyle{ L }[/math] и [math]\displaystyle{ {L_p} }[/math] - соответственно последовательная и параллельная сложность алгоритма подсчета числа связей.

Программная реализация алгоритма

Существующие реализации алгоритма

  1. Библиотека annoviko/pyclustering включает реализации для Python и C++ под GPL 3.
  2. Пакет CBA из репозитория CRAN содержит реализацию на R под GPL 2: [1]
  3. Библиотеки Weka и feed4weka содержат реализацию для Java под GPL 2.