Участник:ЕкатеринаКозырева/Алгоритм динамической иерархической кластеризации CHAMELEON
| Алгоритм динамической иерархической кластеризации CHAMELEON | |
| Последовательный алгоритм | |
| Последовательная сложность | [math]\displaystyle{ O(nm + n log n + m^2 log m) }[/math] |
| Объём входных данных | [math]\displaystyle{ \frac{n (n - 1)}{2} }[/math] |
| Объём выходных данных | [math]\displaystyle{ n }[/math] |
| Параллельный алгоритм | |
| Высота ярусно-параллельной формы | [math]\displaystyle{ O(n+ n log(n) + m^2 log (m) + m log(m)) }[/math] |
| Ширина ярусно-параллельной формы | [math]\displaystyle{ O(n) }[/math] |
Автор описания Е.А.Козырева
Свойства и структура алгоритмов
Общее описание алгоритма
Алгоритм CHAMELEON был предложен в 1999 году тремя учеными из университета Миннесоты – George Karypis, Eui-Hong (Sam) Han и Vipin Kumar[1].
Предназначен для решения задач кластеризации. Кластеризация (или кластерный анализ) — это задача разбиения множества объектов на группы, называемые кластерами. Внутри каждой группы должны оказаться «похожие» объекты, а объекты разных группы должны быть как можно более отличны.
CHAMELEON - это агломеративный иерархический алгоритм кластеризации, ключевой особенностью которого является то, что он учитывает и взаимную связность, и сходство при определении наиболее похожей пары подкластеров, основываясь на динамической модели. Это означает, что в процессе кластеризации два кластера объединяются, только если их относительная взаимная связность и относительное взаимное сходство являются высокими по отношению к внутренней взаимосвязанности кластеров и близости элементов внутри кластеров. Кроме того, CHAMELEON использует подход для моделирования степени взаимосвязанности и близости между каждой парой кластеров, который учитывает внутренние характеристики самих кластеров. Таким образом, он может автоматически адаптироваться к внутренним характеристикам объединяемых кластеров.
CHAMELEON находит кластеры в наборе данных с помощью трехфазного алгоритма. На первой фазе происходит построение графа, путём добавления рёбер по принципу k ближайших соседей. На второй фазе CHAMELEON группирует полученные элементы в множество относительно небольших подграфов. Во время третьей фазы применяется агломеративный иерархический алгоритм кластеризации, с помощью которого находятся естесственные кластеры путем многократного объединения подграфов, полученных на прошлом этапе.

Математическое описание алгоритма
Исходные данные:
- Множество из n точек [math]\displaystyle{ V= {v_{ij}} }[/math] в метрическом пространстве, которое задано симметрической матрицей расстояний [math]\displaystyle{ A }[/math] размера [math]\displaystyle{ n\times n }[/math].
- [math]\displaystyle{ k }[/math] - количество ближайших соседей для вершин, [math]\displaystyle{ k \in N, k \leq n }[/math].
- [math]\displaystyle{ l }[/math] - наименьшее число вершин, которое может содержать наибольший подграф на 2-м этапе, [math]\displaystyle{ l \in N, l \leq n }[/math].
Обозначения:
- [math]\displaystyle{ G = (V, E) }[/math] - граф, полученный путём соединения каждой точки с её [math]\displaystyle{ k }[/math] ближайшими соседями.
- [math]\displaystyle{ K= \{K_{i}\} }[/math] - разбиение множества [math]\displaystyle{ V }[/math] на набор попарно непересекающихся связных подмножеств, полученное в результате выполнения второй фазы алгоритма.
- [math]\displaystyle{ G_{2} = (K, E_{2}) }[/math] - взвешенный граф, вершинами которого являются получившиеся подграфы, а ребрами - количество ребер исходного графа, соединяющих соответствующие подграфы.
- [math]\displaystyle{ C = \{C_{i}\} }[/math] - итоговое разбиение множества вершин графа [math]\displaystyle{ G_{2} }[/math] на набор кластеров.
Вспомогательные понятия
- [math]\displaystyle{ EC_{(C_{i},C_{j})} }[/math] - абсолютная взаимная связность пары кластеров [math]\displaystyle{ C_{i}, C{j} }[/math]. Определяется как сумма весов ребер, соединяющих вершины, принадлежащие [math]\displaystyle{ C{i} }[/math] c вершинами из [math]\displaystyle{ C{j} }[/math]. Внутренняя связность [math]\displaystyle{ EC_{(C_{i},C_{i})} }[/math] вычисляется как сумма ребер, входящих в разделитель, разбивающий [math]\displaystyle{ C{i} }[/math] на два равных подграфа.
- [math]\displaystyle{ RI_{(C_{i},C_{j})} = \frac{|EC_{(C_{i},C_{j})}|}{(|EC_{C_{i}}|+|EC_{C_{j}}|)/2} }[/math] - относительная взаимная связность пары кластеров [math]\displaystyle{ C_{i}, C{j} }[/math]
- [math]\displaystyle{ S_{EC_{(C_{i},C_{j})}} }[/math] - абсолютное взаимное сходство пары кластеров [math]\displaystyle{ C_{i}, C{j} }[/math]. Подсчитывается как среднее сходство между соединенными вершинами, принадлежащими [math]\displaystyle{ C{i} }[/math] и [math]\displaystyle{ C{j} }[/math] соответственно. Соединения обусловлены разбиением общего графа, полученного на первом этапе алгоритма.
- [math]\displaystyle{ RC_{(C_{i},C_{j})}= \frac{S_{EC_{(C_{i},C_{j})}}}{\frac{|C_{i}|}{|C_{i}+C_{j}|}*S_{EC_{(C_{i})}}+\frac{|C_{i}|}{|C_{i}+C_{j}|}*S_{EC_{(C_{j})}}} }[/math] - относительное взаимное сходство пары кластеров [math]\displaystyle{ C_{i}, C{j} }[/math]. Определяется как абсолютное сходство между этой парой кластеров, нормализованное с учетом их внутреннего сходства[2].
Первый этап
На первом этапе, согласно графо-ориентированному подходу, происходит построение графа [math]\displaystyle{ G = (V, E) }[/math] на матрице сходства объектов по принципу k ближайших соседей. Две вершины такого графа соединяет ребро, если объект, соответствующий любой из этих вершин попадает в число k наиболее близких объектов для объекта, соответствующего другой вершине из данной пары.

Второй этап
Алгоритм разделяет полученный граф на множество сравнительно малых подграфов [math]\displaystyle{ K= \{K_{i}\} }[/math]. Разделение происходит последовательно. На каждом шаге выбирается подграф, содержащий наибольшее число вершин. Этот граф разделяется на два подграфа так, что разделитель ребер графа минимален и каждый из получаемых подграфов содержит не менее 25 % вершин исходного графа. Процесс разделения останавливается, когда наибольший подграф содержит меньше некоторого заданного числа вершин. Обычно величина этого параметра задается равной значению от 1 до 5 % от числа объектов. Полученное множество связных графов считается множеством начальных кластеров, на котором требуется провести последовательное иерархическое объединение.
Третий этап
Третий этап заключается в итеративном преобразовании множества подграфов [math]\displaystyle{ K= \{K_{i}\} }[/math] в множество кластеров [math]\displaystyle{ C = \{C_{i}\} }[/math]. Алгоритм осуществляет агломеративную иерархическую кластеризацию на основании показателей [math]\displaystyle{ EC_{(C_{i},C_{j})} }[/math], [math]\displaystyle{ S_{EC_{(C_{i},C_{j})}} }[/math], [math]\displaystyle{ RI_{(C_{i},C_{j})} }[/math], [math]\displaystyle{ RC_{(C_{i},C_{j})} }[/math]. Существует две стратегии анализа показателей сходства. Первая подразумевает наличие некоторых пороговых значений [math]\displaystyle{ T_{RI} }[/math] и [math]\displaystyle{ T_{RC} }[/math]. В соответствии с этой стратегией, алгоритм для каждого кластера [math]\displaystyle{ C_{i} }[/math] проверяет, отвечают ли смежные (наиболее близкие) ему кластеры условиям:
- [math]\displaystyle{ RI_{(C_{i},C_{j})} \geqslant T_{RI} }[/math]
- [math]\displaystyle{ RC_{(C_{i},C_{j})} \geqslant T_{RC} }[/math]
Если более одного смежного кластера отвечает этим условиям, то алгоритм выбирает для объединения наиболее связный кластер (граф), то есть такой кластер [math]\displaystyle{ C_{j} }[/math], с которым у кластера [math]\displaystyle{ C_{i} }[/math] получается наибольшая абсолютная взаимная связность. По завершению прохода по всем кластерам, созданные таким образом пары объединяются. Параметры [math]\displaystyle{ T_{RI} }[/math] и [math]\displaystyle{ T_{RC} }[/math] могут использоваться для изменения характеристик получаемых кластеров.
Вторая стратегия заключается в использовании специальной функции, объединяющей понятия относительной взаимной связности и относительного взаимного сходства. На каждом шаге выбираются те кластеры для объединения, которые максимизируют эту функцию:
[math]\displaystyle{ RI_{(C_{i},C_{j})}*RC_{(C_{i},C_{j})}^\alpha }[/math],
где [math]\displaystyle{ \alpha }[/math] выбирается пользователем. Если [math]\displaystyle{ \alpha \gt 1 }[/math], то алгоритм придает большее значение относительному взаимному сходству, а если [math]\displaystyle{ \alpha \lt 1 }[/math], то большее значение имеет относительная взаимная связность.
Вычисляемые данные:
[math]\displaystyle{ U = (u_1, u_2, ..., u_n) }[/math] - n-мерный вектор, где [math]\displaystyle{ u_i \in N_{[C]} }[/math] - порядковый номер кластера, к которому принадлежит вершина i исходного множества V.
Вычислительное ядро алгоритма
Алгоритм имеет три вычислительных ядра, по одному на каждый этап.
На первом этапе вычислительным ядром является процесс нахождения [math]\displaystyle{ k }[/math] ближайших соседей для каждой вершины, который заключается в анализе матрицы расстояний.
На втором этапе вычислительным ядром является процесс поиска подходящего разбиения очередного подграфа на два графа с минимизацией разделителя ребер графа.
На третьем этапе вычислительным ядром является расчет величин [math]\displaystyle{ EC_{(C_{i},C_{j})} }[/math], [math]\displaystyle{ S_{EC_{(C_{i},C_{j})}} }[/math], [math]\displaystyle{ RI_{(C_{i},C_{j})} }[/math], [math]\displaystyle{ RC_{(C_{i},C_{j})} }[/math] для каждой пары смежных кластеров.
Макроструктура алгоритма
Как уже рассказывалось ранее, алгоритм включает в себя три основных этапа, каждый из которых, по сути, является отдельным алгоритмом. Этапы выполняются последовательно относительно друг друга.
Макрооперация на первом этапе - процедура нахождения [math]\displaystyle{ k }[/math] ближайших соседей, на втором - процедура разбиения наибольшего подграфа на два графа, на третьем - процедура вычисления показателей сходства, на основе которых принимается решение о слиянии подграфов в кластер.
Схема реализации последовательного алгоритма
Первый этап
int n; //количество вершин
int k; //количество соседей
int A[n][n] //матрица расстояний
int D[k] //массив вершин-соседей
int E[n][n] //матрица ребер графа <math>G_{2} = (K, E_{2})</math>
for i=1 to n-1 do
{
for j=i+1 to n do
{
//заполняем массив вершин-соседей вставляя новые вершины, если они ближе, чем самая далекая из массива.
}
for j=0 to k do
{
//для каждой вершины соседа заполняем соответствующую ячейку из матрицы E[n][n] единицей
}
}
Второй этап
1. Все связные подграфы в отсортированном порядке помещаются в список;
2. Берем наибольший элемент списка, вычисляем количество его вершин. Если число вершин > l, то идем в пункт 3. Иначе в пункт 5;
3. Разбиваем подграф на два подграфа таким образом, чтобы разделитель ребер графа был минимален и каждый из получаемых подграфов содержал не менее 25 % вершин исходного графа;
4. Добавляем полученные элементы в список подграфов таким образом, чтобы список оставался отсортированным. Идем в пункт 2;
5. Нашли искомое множество подграфов math>K = \{K_{i}\}</math>;
6. Создаем и заполняем матрицу матрицу расстояний для графа [math]\displaystyle{ G_{2} = (K, E_{2}) }[/math]. Получаем искомый набор рёбер [math]\displaystyle{ E_{2} }[/math].
Третий этап
1. Заводим два массива: а) массив кластеров C, полученных на предыдущем этапе, б) массив объединений кластеров F, которые мы будем получать на этом этапе; 2. Берем следующий кластер [math]\displaystyle{ C_{i} }[/math] (на первом шаге - первый). Если все кластеры просмотрены, идем в пункт 6; 3. Берем следующий кластер [math]\displaystyle{ C_{j}, i\lt \gt j }[/math]. Если все кластеры просмотрены, то идем в пункт 2; 4. Проверяем смежность [math]\displaystyle{ C_{i} }[/math] и [math]\displaystyle{ C_{j} }[/math]. Если не смежны, то возвращаемся в пункт 3. Если смежны, идем в пункт 5; 5. Рассчитываем показатели [math]\displaystyle{ RI_{(C_{i},C_{j})} }[/math] и [math]\displaystyle{ RC_{(C_{i},C_{j})} }[/math]. Проверяем, удовлетворяют ли найденные значения условиям: *[math]\displaystyle{ RI_{(C_{i},C_{j})} \geqslant T_{RI} }[/math] *[math]\displaystyle{ RC_{(C_{i},C_{j})} \geqslant T_{RC} }[/math] Если нет, то идем в пункт 3. Иначе если смежность пары кластеров выше, чем у предыдущих найденных, то [math]\displaystyle{ F_{i}=j }[/math]. Идем в пункт 3; 6. Если в списке F есть хотя бы одна пара кластеров для слияния, то выполняем слияние, обновляем массив кластеров и массив объединений кластеров. Идем в пункт 2.
Последовательная сложность алгоритма
1) Для построения графа на основе метода k ближайших соседей для n вершин требуется [math]\displaystyle{ O(n log(n)) }[/math] операций [3]; для наборов данных большой размерности эта величина составляет [math]\displaystyle{ O(n^2) }[/math] операций [4];
2) Для выделения множества сравнительно малых связных подграфов требуется [math]\displaystyle{ nm }[/math] операций, где [math]\displaystyle{ m }[/math] - количество подграфов, полученных на втором этапе алгоритма;
3) Формирование набора кластеров, на основе множества подграфов, полученных на предыдущем этапе, требует [math]\displaystyle{ m^2log(m) }[/math] операций.
Итого, для n вершин получаем последовательную сложность [math]\displaystyle{ O(n log(n)+nm+m^2log(m)) }[/math].
Информационный граф
Ресурс параллелизма алгоритма
Первый этап работы алгоритма можно распределить между [math]\displaystyle{ n }[/math] процессами. На вход каждому процессу подается своя вершина, далее происходит процедура поиска [math]\displaystyle{ k }[/math] ближайших соседей. Параллельная сложность составляет [math]\displaystyle{ O(n) }[/math].
Второй и третий этапы можно распараллелить частично.
Второй этап распараллеливается путем подачи на вход свободному процессу очередного подграфа для разделения. Число итераций оценивается в [math]\displaystyle{ O(n log(n)) }[/math].
Третий этап делится на расчет показателей схожести и соединение подграфов в кластеры. Процесс расчета показателей можно распараллелить, подавая каждому процессу на вход пару подграфов. Сложность этого процесса оценивается как [math]\displaystyle{ m log(m) }[/math]. Соединение подграфов в кластеры выполняется последовательно, сложность процесса составляет [math]\displaystyle{ m^2 log(m) }[/math]
Таким образом получаем общую параллельную сложность алгоритма: [math]\displaystyle{ O(n+ n log(n) + m^2 log (m) + m log(m)) }[/math]
Входные и выходные данные алгоритма
Входные данные
1. Симметрическая матрица [math]\displaystyle{ A }[/math] расстояний между элементами данных размера [math]\displaystyle{ n\times n }[/math] с нулями на главной диагонали ([math]\displaystyle{ a_{ii}= 0, i = 1, \ldots, N }[/math]).
2. [math]\displaystyle{ k }[/math] - количество ближайших соседей для вершин (рекомендуемое значение [math]\displaystyle{ k }[/math] от 5 до 20 в зависимости от количества анализируемых объектов).
3. [math]\displaystyle{ l }[/math] - наименьшее число вершин, которое может содержать наибольший подкластер на 2-м этапе . Величина этого параметра варьируется от 1 до 5 % от общего числа объектов.
Объём входных данных
[math]\displaystyle{ \frac{n (n - 1)}{2} }[/math] (в силу симметричности и нулевой главной диагонали достаточно хранить только над/поддиагональные элементы).
Выходные данные
Вектор из [math]\displaystyle{ n }[/math] чисел [math]\displaystyle{ u_{1}, u_{2}, \ldots, u_{N} }[/math], где [math]\displaystyle{ u_{i} }[/math] - целое число, соответствующее кластеру [math]\displaystyle{ i }[/math]-го объекта.
Объём выходных данных
[math]\displaystyle{ n }[/math]
Свойства алгоритма
Соотношение последовательной и параллельной сложности на первом этапе является линейным для больших наборов данных и логарифмическим для n вершин. На втором этапе сложно оценить это соотношение - оно сильно зависит от параметров [math]\displaystyle{ k }[/math] и [math]\displaystyle{ l }[/math]. На третьем этапе соотношение равно [math]\displaystyle{ O(1) }[/math];
Оценка вычислительной мощности выглядит следующим образом:
[math]\displaystyle{ O(1) }[/math] для 1-го этапа;
[math]\displaystyle{ O(\frac{nm}{n^2+m^2}) }[/math] для 2-го этапа;
[math]\displaystyle{ O(\frac{m^2log(m)}{m^2+n}) }[/math] для 3-го этапа;
Алгоритм является недетерминированным. Хотя 1-й этап детерминирован, на 2-ом этапе могут быть найдены различные разбиения на подграфы, что повлияет и на итоговый результат работы алгоритма.
Программная реализация алгоритма
Особенности реализации последовательного алгоритма
Локальность данных и вычислений
Возможные способы и особенности параллельной реализации алгоритма
Масштабируемость алгоритма и его реализации

Динамические характеристики и эффективность реализации алгоритма
Выводы для классов архитектур
Существующие реализации алгоритма
Последовательная реализация алгоритма доступна по ссылке [5].
CHAMELEON можно реализовать с использованием графовых библиотек METIS [6], hMETIS [7] и RANN [8].
Существует исследование, связанное с реализацией CHAMELEON посредством технологии OpenMP, с которым можно ознакомиться здесь [9].
Параллельных реализаций алгоритма CHAMELEON не найдено.
Литература
- ↑ George Karypis, Eui-Hong (Sam) Han и Vipin Kumar, «Chameleon: Hierarchical Clustering Using Dynamic Modeling», 1999.
- ↑ http://studopedia.ru/7_41934_algoritm-dinamicheskoy-ierarhicheskoy-klasterizatsii-CHAMELEON.html
- ↑ J.H. Friedman, J.L. Bentley, and R.A. Finkel. An algorithm for finding best matches in logarithmic expected time. ACM Transactions on Mathematical Software, 3:209–226, 1977.
- ↑ S. Berchtold, C. Bohm, D. Keim, and H.-P. Kriegel. Cost model for nearest neighbor search in high dimensional data space. In Proc. of Symposium on Principles of Database Systems, Tucson, Arizona, 1997.
- ↑ http://read.pudn.com/downloads36/sourcecode/math/115779/chameleon/chameleon.c__.htm
- ↑ http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
- ↑ http://glaros.dtc.umn.edu/gkhome/metis/hmetis/overview
- ↑ https://cran.r-project.org/web/packages/RANN/index.html
- ↑ http://research.ijcaonline.org/volume79/number8/pxc3891600.pdf
