Задача кластеризации

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

Давайте посмотрим на пример. Перед вами игрушечный data frame.

В каждой строчке у нас наблюдения, а столбцы это переменные, которые описывают наши наблюдения. Можно представить, что наблюдения это люди, у которых есть пронумерованные карты от 1 до 10. А переменные это описание масти каждой пронумерованной карты. Можете ли вы разбить этих людей на группы? Почему вы так решили?

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

Люди в каждой группе имеют одинаковые масти пронумерованных карт. Например, в “желтой” группе у всех 2 карта это черви.

Зачем нам нужна кластеризация?

Кластеризация зачастую это вспомогательная модель, которая может помочь нам достичь нашей цели. Пример из ритейл. Магазин решил повысить цены так, чтобы увеличить выручку компании. Но повышать цену на все товары очень глупо, так как покупатели могут просто уйти в другой магазин, тем самым продажи магазина упадут. В итоге мы получим не увеличение выручки, а ее уменьшение. Но товары можно разбить, например, на две группы: эластичные и неэластичные. Продажи неэластичных товаров при увеличении цены падают не так сильно как у эластичных. Здесь задача кластеризации состоит в том, чтобы разбить все товары на 2 группы.

Pipeline

Чтобы решить задачу кластеризации, нужно выполнить следующие этапы.

  1. Подготовить данные – с частью подготовки данных, в которую входила очистка от выбросов, а также работа с пропущенными значениями, мы уже познакомились. Но есть еще скалирование и отбор переменных, с которыми мы познакомимся в дальнейшем.
  2. Выбор критерия “близости” – в игрушечном примере выше, все было достаточно просто. В группы попали люди, которые имели одинаковые масти у пронумерованных карт. А что если у одного из людей в “синей” группе последняя карта будет не черви, а крести. Он все еще останется в синей группе, так как 9 из 10 мастей совпали? Или же он уже ближе к зеленой группе? А может он образует уже четвертую группу, в которой будет состоять один. Выбор критерия “близости” очень важен, часто нужно понимать ту область из которой пришли данные. Это может очень сильно облегчить выбор правильного критерия.
  3. Выбор модели кластеризации - моделей кластеризации достаточно много и все они разные. Важно понимать что за задачу вы решаете и почему именно эта модель подходит вам лучше всего.
  4. Анализ полученных результатов – нужно проверить, что то как кластеризация поделила наши наблюдения на группы (кластеры) нас устраивает и имеет локигу. Обычно в этом помогают знания из предметной области для которой эта задача решается.
  5. Если нас не устраивает результат, то возможно стоит вернуться к самому первому этапу. На рисунке нарисовано, что ко второму, но первый этап, на котором проводится отбор признаков может сильно улучшить результат.

“Похожесть” наблюдений

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

Давайте вспомним одну из метрик расстояния, которое мы проходили еще в школе. Это евклидово расстояние. Предположим, у нас есть 3 точки с координатами x и y.

Найдем евклидово расстояние между первой и второй точками по формуле:

\[ d(p_1, p_2) = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} \]

В R есть встроенная функция dist, которая находит расстояние между всеми объектами.

##          1        2        3
## 1 0.000000 5.099020 4.472136
## 2 5.099020 0.000000 1.414214
## 3 4.472136 1.414214 0.000000

Изобразим их.

Если мы работаем с большим количество координат, то формула будет следующей:

\[ p_i = (p_1^i, ..., p_n^i) \]

\[ d(p_i, p_j) = \sqrt{(p_1^i - p_1^j)^2 + ... (p_n^i - p_n^j)^2} = \sqrt{\sum_{k=1}^{n}{(p_k^i - p_k^j)^2}} \]

Скалирование признаков

Давайте разберемся почему скалирование признаков очень важно для нас. Предположим, что мы хотим кластеризовать лиюдей по росту и весу. Рост у нас будет в футах (ft), а вес в английских фунтах (lbs).

  • 6 ft = 182.8 см, 8 ft = 243.8 см
  • 200 lbs = 90.72 кг, 202 lbs = 91.63 кг

Второй или третий ближе к первому?

##          1        2
## 2 2.000000         
## 3 2.000000 2.828427

Логически 2 намного ближе к 1 чем 3. Но если посчитать евклидово растояние, то получится, что растояния будут равны. Это произошло из-за того, что наши признаки (рост и вес) имеют разный масштаб. Чтобы избавиться от масшатаба, нужно отскалировать наши признаки.

Самые известные способы скалирования:

  • Standard scaler – переменные будут иметь одинаковый масштаб, среднее равно 0, стандартное отлонени равно 1, эти параметры можно менять.

\[ feature_{scaled} = \frac{feature - mean(feature)}{sd(feature)} \]

Чтобы выполнить такое скалирование, понадобится встроенная функция scale.

## # A tibble: 3 x 2
##    h[,1]  w[,1]
##    <dbl>  <dbl>
## 1 -0.577 -0.577
## 2 -0.577  1.15 
## 3  1.15  -0.577
##          1        2
## 2 1.732051         
## 3 1.732051 2.449490
  • Min-Max scaler

Отбор признаков

У вас может быть очень много признаков, но это не значит, что нужно их все использовать в кластеризации. Важно выкинуть переменные, которые могут быть просто шумом.