… И некоторые эксперименты с выбором функций и нормализацией

Давайте проведем этот эксперимент: взгляните на следующие рисунки и посмотрим, сможете ли вы определить, на каком рисунке есть сгруппированные данные: A или B?

Кластеризация как концепцию нетрудно понять, и я не уверен, нужно ли вам изучать что-то помимо того, что вы уже знаете. Если вы ответили B, больше никому не нужно объяснять вам, что такое кластеризация.

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

Итак, если кластеризация - такая простая концепция, что именно нам нужно о них узнать? На самом деле довольно много вещей:

  • что означает кластеризация на практике?
  • как эта концепция используется при решении реальных проблем?
  • как количественно измерить кластеры в большом и многомерном наборе данных?

Давайте ответим на эти вопросы по отдельности, а затем углубимся в некоторые технические детали.

Почему кластеризация? Некоторые варианты использования

Давайте сначала проясним несколько вещей. На рисунке B выше наблюдения сгруппированы. Но в каком отношении? Ответ - они сгруппированы в двумерном пространстве по двум переменным, представленным координатами X и Y.

Но это лишь один из способов увидеть кластеры. Объекты можно сгруппировать миллионами разных способов, таких как возраст, рост, местоположение, цена, пол - вы называете это.

Почему в Macy’s женская одежда находится в одном месте, мужская - в другом углу, а мебель - на совершенно другом этаже? Почему они организуют продукты таким образом, чтобы похожие вещи были вместе, а разные - отделены? Чтобы понять это, нам не нужна наука о данных. Но во многих случаях нам действительно нужна наука о данных, чтобы понять, как объекты объединяются в кластеры и как объекты объединяются. Вот несколько примеров:

  • В исследовательском анализе данных (EDA) кластеризация играет фундаментальную роль в развитии первоначальной интуиции о функциях и закономерностях в данных.
  • В статистическом анализе кластеризация часто используется для выявления переменных (несходства) в разных выборках.
  • Страховые компании используют кластеризацию для обнаружения аномалий и потенциально выявляют мошеннические транзакции.
  • Кластеризация широко используется в сегментации устомеров, например для разработки маркетинговых стратегий, ориентированных на разные группы клиентов.
  • В компьютерном зрении сегментация изображений используется для разделения данных на непересекающиеся группы с помощью распознавания образов.
  • Кластеризация - важный инструмент в биологических науках, особенно в генетической и таксономической классификации и понимании эволюции живых и вымерших организмов.
  • Алгоритмы кластеризации имеют широкий спектр других приложений, таких как создание систем рекомендаций, анализ сетей социальных сетей и т. Д.
  • Пространственная кластеризация помогает выявлять домохозяйства и сообщества со схожими характеристиками для реализации соответствующей политики развития сообществ и налогообложения.

Алгоритмы кластеризации

Легко визуализировать данные в двухмерной плоскости и визуально проверить, сгруппированы они или нет. Но что, если есть 3 или 4 измерения; или даже десятки размеров? Что, если существуют миллионы или даже миллиарды точек данных? Алгоритмы здесь, чтобы помочь. Вот несколько алгоритмов кластеризации, часто используемых в машинном обучении:

  • K-означает
  • Иерархический
  • DBSCAN
  • Spectral
  • Гауссовский
  • Береза
  • Средний сдвиг
  • Распространение сродства

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

Кластеризация K-средних, вероятно, является наиболее популярной и часто используемой. Алгоритм начинается с воображаемой точки данных, называемой «центроидом», вокруг которой разбивается каждый кластер. K-means легко реализовать и интерпретировать. Но одним из ключевых недостатков является его чувствительность к выбросам.

Иерархическая кластеризация более информативна, чем К-средние, но страдает аналогичным недостатком - чувствительностью к экстремальным значениям. Кроме того, реализация этого алгоритма может занять много времени для больших наборов данных.

DBSCAN надежен при наличии выбросов, но имеет свой недостаток - высокую чувствительность к параметрам модели (ε и minPts ) .

Я написал больше об этих алгоритмах и их свойствах в предыдущей статье, если вам интересно.

Выполнение

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

Сначала импортируем несколько библиотек.

# importing libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.cluster import KMeans

Следующим шагом будет импорт данных. Для этой демонстрации я использую знаменитый (и часто используемый!) Набор данных Iris. Данные доступны в Интернете и могут быть легко импортированы с помощью приведенного ниже кода.

Здесь необходимо прояснить одну вещь: набор данных Iris - это «очищенный» набор данных - не требуется проектирования функций, отсутствующих значений или фильтрации. Я использую его исключительно для того, чтобы сосредоточиться на алгоритме, но, конечно, мы знаем, что в реальном мире для их очистки требуется довольно много работы.

# importing **cleaned** data
df = pd.read_csv("https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv")
df.head()

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

# scatterplot
plt.scatter(df["petal_length"], df["petal_width"])
plt.xlabel("Petal length")
plt.ylabel("Petal width")

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

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

# feature selection
df = df[["petal_length", "petal_width"]]
# normalizing inputs
X = preprocessing.scale(df)

При такой минимальной подготовке данных все, что остается, - это создать экземпляр алгоритма K-средних из sklearn и подогнать модель с входными данными X. Единственный параметр, который мы используем, - это n_clusters, чтобы указать количество кластеров, которое мы хотим.

# instantiate model
model = KMeans(n_clusters = 3)
# fit predict
y_model = model.fit_predict(X)

Итак, мы подобрали модель, теперь пора визуализировать их в виде диаграммы рассеяния.

# visualize clusters
plt.scatter(X[:,0], X[:,1], c=model.labels_, cmap='viridis')

Имеют ли кластеры смысл при визуальном осмотре? Довольно хорошо, правда? Теперь мы можем подсчитать, сколько наблюдений попадает под каждый кластер.

# value counts in each cluster
pd.value_counts(y_model)

Давайте держать в уме диаграмму рассеяния и количество данных, они понадобятся нам для сравнения производительности альтернативных вариантов моделирования. Назовем эту модель «базовой».

Технические соображения

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

  • Выбор функций
  • Нормализация
  • Алгоритм

Выбор функции

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

Давайте повторно запустим модель с новыми функциями.

# feature selection
df = df[["petal_length", "petal_width", "sepal_length"]]
# normalizing inputs
X = preprocessing.scale(df)
# instantiate model
model = KMeans(n_clusters = 3)
# fit predict
y_model = model.fit_predict(X)
print("Value Counts")
print(pd.value_counts(y_model))
# visualize clusters
plt.scatter(X[:,0], X[:,1], c=model.labels_, cmap='viridis')

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

Нормализация

Нормализация требует долгого обсуждения, но, чтобы сделать длинную историю короче, цель нормализации - масштабировать данные в том же диапазоне, скажем, от -2 до +2. Преимущество этого заключается в том, что он конденсирует сильно разрозненные / рассредоточенные данные, что упрощает поиск кластеров.

Давайте снова запустим новую настройку.

# feature selection
df = df[["petal_length", "petal_width"]]
# inputs (NOT normalized)
X = df.values
# instantiate model
model = KMeans(n_clusters = 3)
# fit predict
y_model = model.fit_predict(X)
# visualizing clusters
plt.scatter(X[:,0], X[:,1], c=model.labels_, cmap='viridis')
# counts per cluster
print("Value Counts")
print(pd.value_counts(y_model))

Домашнее задание: Можете ли вы теперь сравнить результаты по 3 характеристикам с результатами по 2 элементам в базовой линии? Вы можете визуально осмотреть, а также увидеть количество значений.

Алгоритм

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

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

# import model
from sklearn.cluster import AgglomerativeClustering
# feature selection
df = df[["petal_length", "petal_width"]]
# normalizing inputs
X = preprocessing.scale(df)
# instantiate model
model = AgglomerativeClustering(n_clusters=3, affinity='euclidean', linkage='ward')
# fit/predict model
y_model= model.fit_predict(X)
# ploting clusters
plt.scatter(X[:,0], X[:,1], c=model.labels_, cmap='viridis')
# counts per cluster
print("Value Counts")
print(pd.value_counts(y_model))

Определите количество кластеров

Это бонусная часть. Таким образом, мы как бы произвольно указали 3 кластера в базовой модели и последующих экспериментах. Это было легко определить при визуальном осмотре, потому что это небольшой набор данных. Но на самом деле есть подход, основанный на данных, чтобы сделать это определение - так называемый метод локтя. Приведенный ниже фрагмент кода может показаться немного сложным, чем должен быть, но не прилагайте дополнительных усилий, чтобы понять его, если вы этого не хотите.

# determine number of clusters using "elbow method"
k_range = range(1,10)
sse = [] # we want to minimize SSE
for k in k_range:
    m = KMeans(n_clusters=k, random_state=0)
    m.fit(X)
    sse.append(m.inertia_)
    
plt.xlabel("K")
plt.ylabel("Sum of squared errors")
plt.plot(k_range, sse, marker='x')

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

Резюме

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

  • кластеризация проста как концепция, но требует помощи с машинами для реализации для большого и / или многомерного набора данных
  • варианты использования разнообразны - от описательной статистики, обнаружения аномалий и проектирования систем рекомендаций до биологии, пространственной статистики и городского планирования.
  • на рынке есть несколько алгоритмов, но популярные - K-means, иерархический и DBSCAN кластеризация
  • с очищенными данными запуск и интерпретация кластерного анализа с sklearn - простая задача
  • количество функций, нормализация и алгоритмы могут повлиять на то, как выполняется кластеризация

Надеюсь, это была полезная статья. Если у вас есть комментарии, не стесняйтесь записывать их ниже. Вы можете подписаться на меня в Medium, Twitter или LinkedIn.