17 Кластеризация
Кластеризация — это не метод, а задача, для решение которой придумано множество алгоритмов. Не существует “правильных”методов кластеризации, так как “clustering is in the eye of the beholder”[Estivill-Castro 2002]. Мы рассмотрим два семейства алгоритмов:
- метод k-средних (k-means)
- иерархическая кластеризация (hierarchical clustering)
17.1 Метод k-средних (k-means)
Алгоритм k-means был разработан в статье [Lloyd 1982]:
- на вход алгоритму подаются данные и k — количество кластеров, на которые эти данные надо поделить;
- произвольно выбираются k точек (центроидов) и рассчитываются ближайшие расстояния (евклидово) от данных точек до центроидов, точки которые ближе всего к некоторому центроиду образуют кластер;
- на основе точек вошедших в кластер строится новый центроид, так чтобы расстояние от всех точек до нового центроида было минимально;
- часть точек становится ближе к новому центроиду и входят в его кластер, а часть от центроида отдаляется и начинают входить в другой/другие кластер/кластеры;
- … все это повторяется, пока на некоторой итерации не происходит изменение положения центроидов.
Давайте посмотрим визуализацию алгоритма k-средних, которую сделал Нафтали Харрис.
17.1.1 Пример
Давайте проанализируем данные из датасета iris
:
Для того чтобы запустить метод k-средних в R нужно использовать функцию kmeans()
, указав количество кластеров в centers
:
library(broom)
set.seed(42)
iris %>%
select(Petal.Length, Petal.Width) %>%
kmeans(centers = 3) ->
km
Давайте посмотрим, насколько хорошо алгоритм k-средних справился с заданием. Я воспользуюсь функцией augment()
из пакета broom
, чтобы добавить результаты модели к исходным данным (это работает и с регрессиями)
Мы видим, что алгоритм все разбил на три кластера (1
, 2
, 3
), 1
соответствует setosa
, 2
соответствует versicolor
, 3
соответсвтует virginica
(я смотрю с какой группой ассоциировано наибольшое n
). Я использую функцию recode_factor()
для того чтобы перекодировать переменную .cluster
:
km %>%
augment(iris) %>%
mutate(.cluster = recode_factor(.cluster,
`1` = "setosa",
`2` = "versicolor",
`3` = "virginica"),
correct = Species == .cluster) %>%
ggplot(aes(Petal.Length, Petal.Width))+
geom_point(aes(color = correct, shape = Species))+
geom_point(data = data.frame(km$centers)) # центроиды
Цветом выделены несовпадения с исходными данными, как видно, таких случаев всего 5: два цветка virginica
были отнесены к классу versicolor
, три цветка virginica
были отнесены к versicolor
. Так что в целом, можно сказать, что алгоритм хорошо справился. Черным обозначены центроиды получившихся кластеров.
17.2 Иерархическая кластеризация
Иерархические кластеризации имеют два типа:
- снизу вверх (agglomerative): каждое наблюдение в начальной позиции является кластером, дальше два ближних кластера соединяются в один, а дендограмма отображает порядки таких соединений.
- сверху вниз (divisive): все наблюдения в начальной позиции являются кластером, который дальше делится на более мелкие, а дендограмма отображает порядки таких разъединений. Алгоритмы иерархической кластеризации требуют на вход матрицы расстояний. Алгоритмов кластерного анализа очень много, так что имеет смысл заглянуть в работу [Gordon 1987] и на страницу CRAN.
17.2.1 Матрица расстояний
Матрица расстояний — это матрица n × n, которая содержит значения меры расстояния/сходства между объектами в метрическом пространстве. Существует уйма мер расстояния/сходства, выбор из которых зависит от типа данных. К сожалению, не существует универсального алгоритма выбора метода, так что это остается на откуп исследователям. Кроме того, схожие методы, зародившиеся в биологии, называют string metric: они определяют расстояния между строками (расстояние Хэмминга, расстояние Левинштейна и т. п.)
17.2.1.1 Бинарные данные
Представим вот такие данные для нескольких языков:
df <- tibble(lang = c("Lithuanian", "Latvian", "Prussian", "ChurchSlavonic"),
word_1 = c(1, 1, 1, 0),
word_2 = c(1, 1, 1, 0),
word_3 = c(1, 1, 0, 0),
word_4 = c(1, 0, 0, 0),
word_5 = c(0, 0, 0, 1))
df
Существует множество мер для анализа бинарных данных. Самый распространенный — коэффициент Жаккара. Для каждой пары идиомов строим вот такую таблицу:
идиом i | |||
---|---|---|---|
1 | 0 | ||
идиом j | 1 | a | b |
0 | c | d |
А дальше мы считаем меру сходства:
\[s(i, j)=\frac{a}{a+b+c}\]
В работе [Gower and Legendre 1986] есть и другие методы (14 шт.). Большинство из них есть в функции dist.binary()
пакета ade4
.
Дальше можно использовать функцию dist()
с аргументом binary
. Я использую функцию tidy()
из пакета broom
, чтобы получить таблицу:
Можно визуализировать матрицу расстояния:
df %>%
select(-lang) %>%
dist(method = "binary") %>%
tidy() %>%
mutate(item1 =recode_factor(item1,
`1` = "Lithuanian",
`2` = "Latvian",
`3` = "Prussian",
`4` = "ChurchSlavonic"),
item2 =recode_factor(item2,
`1` = "Lithuanian",
`2` = "Latvian",
`3` = "Prussian",
`4` = "ChurchSlavonic")) %>%
ggplot(aes(item1, item2, fill=distance, label = round(distance, 2))) +
geom_tile()+
geom_text(color = "white")
17.2.2 Расстояние между словами
Мы уже обсуждали расстояние между словами, его тоже можно использовать для кластеризации:
1 2
2 1
3 6 6
17.2.3 Применение иерархической кластеризации
Объект иерархической кластеризации легко визуализировать:
Также можно выделить какое-то количество кластеров:
Функция cutree()
возвращает вектор номеров кластеров в соответсвтии с данными, так что можно строить все предыдущие графики:
Мы видим, что алгоритм все разбил на три кластера (1
, 2
, 3
), 1
соответствует setosa
, 2
соответствует virginica
и versicolor
, 3
соответсвтует versicolor
(я смотрю с какой группой ассоциировано наибольшое n
). Я использую функцию recode_factor()
для того чтобы перекодировать переменную .cluster
:
iris %>%
mutate(cluster = cutree(hc, k=3)) %>%
mutate(cluster = recode_factor(cluster,
`1` = "setosa",
`2` = "virginica",
`3` = "versicolor"),
correct = Species == cluster) %>%
ggplot(aes(Petal.Length, Petal.Width))+
geom_point(aes(color = correct, shape = Species))
Мы видим, что ошибки в осовном сгруппированы на границе двух кластеров (видимо, точек меньше, чем 21 потому что они совпадают).