kmeans
Realization of clustering algorithm "kmeans" on Java
Лабораторная работа №2
Ниже представлен отчёт по проделанной второй лабораторной работе (всего их в дисциплине у преподавателя А.С. Лебедева было 3) по предмету "Информационные хранилища и информационно-аналитические системы" 4-го курса 1-го семестра (осень) (2021/2022 учебный год).
Содержание
Цель работы
Реализовать кластеризацию методами k-means и fuzzy c-means. Набор данных выбирается самостоятельно. Возможен выбор популярного датасета “Ирисы Фишера”.
Теоретическое введение
[4] С развитием сети Интернет получили развитие вопросы построения распределенных баз данных, создания распределенных глобальных информационных систем. Многократно возросла интенсивность формирования и архивирования различных данных, за которыми следовало развитие масштабируемых программно-аппаратных комплексов, дорогостоящих мощных и недорогих пользовательских компьютеров и накопителей данных.
Все это способствовало всплеску развития индустрии ИКТ и сделало огромное количество баз данных доступными для хранения разнородной информации в значительных объемах и управления транзакциями в них. При этом все больше возникала потребность анализа имеющихся данных в разновременном аспекте, с возможностью построения произвольных запросов, при условии обработки сверхбольших объемов данных, полученных, в том числе, из различных регистрирующих БД. Использование для этих задач традиционных регистрирующих систем и БД крайне затруднительно. Например, в регистрирующей системе информация актуальна исключительно на момент обращения к БД, а в следующий момент времени по тому же запросу можно ожидать другой результат. Интерфейс таких систем рассчитан на проведение определенных стандартизованных операций и возможности получения результатов на нерегламентированный произвольный запрос ограничены. Возможности обработки больших массивов данных также могут быть ограничены вследствие ориентации СУБД на нормализованные данные, характерные для стандартных реляционных регистрирующих БД.
Ответом на возникшую потребность стало появление новой технологии организации баз данных — технологии Хранилищ Данных (англ. «Data Warehouse»), предполагающей некоторую предварительную обработку данных и их интеграцию, а также онлайновую аналитическую обработку (англ. «On-Line Analytical Processing», OLAP).
Несмотря на очевидную пользу такого инструмента анализа данных, он ориентирован на хорошо нормализованные табличные данные и не предполагает использование целого ряда дополнительного аналитического инструментария типа классификации, кластеризации, регрессионного анализа, моделирования, прогнозирования и интерпретации многомерных данных и т.п.
Таким образом, сегодня наблюдается высокий уровень развития масштабируемой аппаратно-программной ИКТ инфраструктуры, позволяющей увеличивать и без того значительные архивы данных. Имеется достаточно существенный задел в области компьютерных наук и информационных технологий, разработаны теория и прикладные аспекты теории вероятности и математической статистики. Однако при этом следует признать, что присутствует заметный избыток данных при дефиците информации и знаний. Быстро растущие объемы накопленных и пополняемых (автоматически, а не людьми — как это было когда-то) архивов данных пока существенно превышают способности человека в их практически полезной обработке. Для обострения этого тезиса иногда говорят, что «большие базы данных стали могилами, которые редко посещаются». Как следствие, важные решения порой принимаются не на основе аналитических выводов из информативных БД, а на основе интуиции человека, не имеющего подходящих инструментов для извлечения полезных знаний из имеющихся огромных объемов данных.
Поэтому в последние годы стремительное развитие получила область Data Mining (в отечественной литературе наиболее используемая аналогия — интеллектуальный анализ Данных, ИАД), направленная на поиск и разработку методов извлечения из имеющихся данных знаний, позволяющих принимать на их основе конкретные, в высокой степени обоснованные, практически полезные управленческие решения [4].
Ход работы
Для написания кода была использована IDE IntelliJ IDEA. Язык программирования был выбран Java. Помимо стандартных Java-библиотек, использовалась также библиотека для построения графиков и диаграмм «JFreeChart» автора Дэвида Гилберта (David Gilbert; он же jfree) [3].
Как указано, в презентации, которую сделали мои одногруппницы, есть строго определённые шаги при выполнении алгоритмов «k-means» и «fuzzy c-means» [1,2]. Их вы, дорогой читатель, должны придерживаться.
Структура кода как реализации первого из этих алгоритмов кластеризации содержит в себе три класса: Main
, KMeans
и Universe
(от англ. «Вселенная»).
Группируются в этой работе звёзды в шесть заранее выбранных кластеров (т.е. групп) (см. рисунок 1).
Рисунок 1 — Исследуемая предметная область
Чем выше температура, тем у звезды цвет холоднее. И чем выше масса звезды, тем короче её жизненный цикл. Совсем массивные звёзды превращаются в нейтронные звёзды или чёрные дыры в конце своего существования.
Единицы обсуждаемых величин, хоть и показаны в килограммах и кельвинах (см. рисунок выше), но всё равно являются по большей части выдуманными и несоответствующими реальным значениям температуры и массы подобных светил. Но в целом, для этой работы сойдут и такие, очень-очень приближённые значения. Это сделано для удобства реализации кода.
Класс Universe
описывает звёзды и используется в классе KMeans
в процессе группировки (кластеризации). Класс Main
по умолчанию начальная точка запуска всей программы. В Main
рисуется также график при помощи модуля JFreeChart
.
Начальная выборка звёзд задаётся в том же классе Main
в самом начале (см. код 1 ниже).
Код 1 — Выборка кластеризуемых объектов (звёзд) |
В классе Universe
есть массив строк stars
, который и содержит в подобном формате описание всех звёзд (объектов). Массив выше (см. код 1) передаётся в качестве аргумента в конструктор класса Universe
при его создании, и тем самым инициализируются все объекты Universe
, над которыми и будет проводиться работа.
Этот Universe
, как было сказано чуть раньше, передаётся следом в конструктор уже KMeans
— класс, который содержит в себе методы алгоритма кластеризации «k-means» [2,1]:
KMeans kmeans = new KMeans(new Universe(stars));
Далее идёт вывод результатов в консоль и в окно модуля JFreeChart
:
Код 2 — Остальная часть метода |
Метод run()
, как видно из кода 2 выше, принадлежит классу KMeans
и выполняет основную часть алгоритма k-means. Переменная sample
у объекта kmeans
в том же коде выше и есть объект Вселенной, хранящий массив всех звёзд. А благодаря методам getTemp()
и getMass()
вытаскиваются из строк (см. код 1) соответственно температура и масса каждой звезды и возвращаются в виде массивов.
Чтобы вам было понятнее, дорогой читатель, нужно пояснить значение этих строк:
stars[0] = "1000:1000.0;-1"; stars[1] = "2050:1400.0;-1"; stars[2] = "3000:2500.0;-1";
Число до двоеточия в них — это температура. Число с плавающей точкой после двоеточия обозначает значение массы соответствующей звезды; а цифра в конце означает принадлежность звезды к какому-либо кластеру. Кластеры нумеруются от 0-ля до 5-ти, а -1 означает, что звезда пока что не принадлежит ни к какому кластеру.
Таким образом, заданная выборка объектов во Вселенной будет графически выглядеть так — см. рисунок 2.
Глазом из этого рисунка уже можно примерно выделить группы, небольшие скопления звёзд.
Класс Universe
вбирает в себя весь код, необходимый для редактирования и чтения данных о его объектах. К примеру, публичный метод changeCluster()
изменяет номер кластера какого-либо объекта, а метод getStars()
выступает в роли геттера для переменной-массива класса stars
.
Полный код этого класса представлен в этом каталоге ГитХаба!
Рисунок 2 — Начальный некластеризованный набор звёзд
Как и код класса Universe
, KMeans
с основной частью этой лабораторной работы тоже представлен в этом репозитории ГитХаба.
Тестирование
В итоге, из-за случайной компоненты при выборе начальных центров всех кластеров программа выдаёт несколько возможных вариантов группировки звёзд по шести кластерам.
Первый вариант представлен в блоке Код 3 ниже.
0. Temperature: 1000 Mass: 1000.0 Cluster: 0 Код 3 — Вывод программы в консоль |
Как видно из этого вывода, алгоритм решил обойтись вообще без двух кластеров (с номерами 2 и 4) и смог кластеризовать объекты и таким способом.
Способ группировки тут зависит от начального выбора центров кластеров, который, как уже упоминалось, имеет случайную компоненту — то есть алгоритм характеризуется чётко прослеживаемой стохастичностью.
Метод init()
класса KMeans
инициализирует алгоритм и определяет начальные центры всех групп. В нём используется класс Random
, генерирующий псевдослучайные числа. См. код 4.
Расстояния (а равно различия) между объектами представлены Евклидовой метрикой:
Чем больше расстояние d, тем больше различие между двумя объектами (см. код 4, выделенное жирным).
// Поэтапно определить все необходимые центроиды:
Код 4 — Метод |
Буква v в выводе (см. код 3) обозначает суммарное квадратичное отклонение точек кластеров от центроидов этих кластеров [5]. Смысл алгоритма заключается в том, чтобы минимизировать это значение v:
Это значит максимально компактно сгруппировать все объекты к центрам кластеров (то есть к центроидам), чтобы получилось несколько вполне различных групп объектов.
В формуле (1) μ_i — это центроид для кластера S_i; а k — это количество кластеров в исследовании (в этой работе их, напомним, шесть).
В коде это значение, представленное формулой (1), выражается отдельным методом:
|
И используется в главном цикле while
метода run()
.
Как можно заметить в выводе (см. код 3 выделенное жирным — значение v), это суммарное квадратичное отклонение v по ходу алгоритма уменьшается. А когда оно перестанет изменяться, алгоритм завершает свою работу. Это означает, что группы (кластеры) упакованы как можно компактнее в этой ситуации. Дальше уплотнять уже кластеры некуда.
На рисунке 3 изображено графическое представление вывода (код 3).
Рисунок 3 — Первый результат работы программы k-means
0. Temperature: 1000 Mass: 1000.0 Cluster: 0 |
Это идеальный для поставленной в этой работе задачи результат! Выделены все шесть кластеров, и объекты сгруппированы в них, как того хотелось изначально.
Графически результат выглядит так, как показано на рисунке ниже.
Вывод
Благодаря проделанной работе вы должны понять суть алгоритма кластеризации k-means. Его характерные особенности, в том числе стохастичность (случайность) и условие остановки.
Необходимо также понимать, зачем нужна кластеризация и в каких областях её реализуют. Она нужна для того, чтобы лучше понять представленные в какой-либо области деятельности данные и группировать их по их отличительным свойствам. Это может быть биология, география, понятия из математических и компьютерных наук, история и многое-многое другое.
Список использованной литературы
- k-means++ // Википедия. Свободная энциклопедия URL: https://ru.wikipedia.org/wiki/K-means%2B%2B (дата обращения: 18.01.2022).
- Метод k-средних // Википедия. Свободная энциклопедия URL: https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_k-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85 (дата обращения: 18.01.2022).
- JFreeChart // GitHub URL: https://github.com/jfree/jfreechart (дата обращения: 18.01.2022).
- Лебедев А.С. Лекция 1 - Технологии анализа данных. Методы и средства извлечения знаний // Лекции по дисциплине "Информационные хранилища и информационно-аналитические системы". - М.: 2021
- Кластеризация: метод k-средних // Портал Знаний. Глобальный интеллектуальный ресурс. StatSoft URL: http://statistica.ru/theory/klasterizatsiya-metod-k-srednikh/#:~:text=%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%20k%2D%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85%20%E2%80%93%20%D1%8D%D1%82%D0%BE%20%D0%BC%D0%B5%D1%82%D0%BE%D0%B4,(%D1%86%D0%B5%D0%BD%D1%82%D1%80%D0%BE%D0%B8%D0%B4%D1%83)%20%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D0%BE%D0%B3%D0%BE%20%D0%BE%D0%BD%D0%BE%20%D0%B1%D0%BB%D0%B8%D0%B6%D0%B5%20%D0%B2%D1%81%D0%B5%D0%B3%D0%BE (дата обращения: 18.01.2022)
- Плетнёва Мария, Конюшко Анастасия КЛАСТЕРИЗАЦИЯ. МЕТОДЫ K-MEANS, FUZZY C-MEANS // Презентация. – 2021
Примечания
- Недавно отыскал реализацию того же алгоритма kmeans на языке Go у пользователя Christian Muehlhaeuser: https://github.com/muesli/kmeans.
- Теорию про сами алгоритмы kmeans и fuzzy c means смотрите в папке "docx" этого репозитория.
Как видно из этой работы, алгоритм fuzzy c means в ней не реализован. "Fuzzy c means" — это модифицированный алгоритм kmeans, включающий вдобавок ещё и элементы нечёткой логики, а именно — матрицу принадлежностей. Реализуется он в основной своей части аналогично алгоритму kmeans, но объекты кластеризации в fuzzy c means принадлежат не только чётко одному кластеру, а сразу всем с разной степенью принадлежности (в зависимости от расстояния до центров этих кластеров).
Подробнее про этот алгоритм см. тут:
- https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%BD%D0%B5%D1%87%D1%91%D1%82%D0%BA%D0%BE%D0%B9_%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8_C-%D1%81%D1%80%D0%B5%D0%B4%D0%BD%D0%B8%D1%85;
- https://habr.com/ru/post/208496/ (статья пользователя andrewnester 2014-го года);
- https://github.com/omadson/fuzzy-c-means (реализация этого нечёткого алгоритма на Python пользователя ГитХаба Madson Dias).
- JFreeChart в виде jar-файла для импорта его в ваш проект тоже лежит в папке "docx"! [3]