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

Кластеризация

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

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

Вы можете скачать набор данных здесь

С этим набором данных мы применим следующие шаги:

· Исследование и предварительная обработка данных

· Кластеризация K-средних с заранее определенным количеством кластеров

· Оптимизация количества кластеров с использованием графика изгиба и силуэта

· Выполнение агломеративной иерархической кластеризации с использованием дендрограммы

· Визуализация кластеров с использованием PCA (анализ основных компонентов)

Исследование и предварительная обработка данных

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

# load the customer data
raw_df = pd.read_csv(‘Datasets/customer-segmentation/Mall_Customers.csv’, index_col=’CustomerID’)
raw_df.head()

Здесь мы видим, что «Пол» является категориальным столбцом, поэтому мы будем использовать горячее кодирование для преобразования этого столбца в двоичные значения.

# One-hot encoding of gender column
encoded_df = pd.get_dummies(raw_df, prefix=’Gender’, drop_first=True)
# Standardize the dataset
scaler = StandardScaler()
# Scales only the numerics columns
scaled_features = pd.DataFrame(scaler.fit_transform(encoded_df.loc[:,[‘Age’, ‘Annual Income (k$)’, ‘Spending Score (1–100)’]]),
 index=encoded_df.index, columns=[‘Scaled_Age’, ‘Scaled_AnnualIncome’, ‘Scaled_SpendingScore’])
# Concat with the Gender column
scaled_df = pd.concat([scaled_features, encoded_df.loc[:,[‘Gender_Male’]]], axis=1)

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

K-средние значения с использованием предопределенного количества кластеров

Прежде чем применять K-Means к нашему набору данных, давайте кратко рассмотрим кластеризацию K-Means.

Алгоритм k-средних относится к категории кластеризации на основе прототипов.

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

Алгоритм K-средних можно обобщить в следующие четыре шага:

1. Случайным образом выбрать k центроидов из точек выборки в качестве начальных центров кластеров.

2. Назначьте каждый образец ближайшему центроиду

3. Переместите центроиды в центр сэмплов, которые были ему назначены.

4. Повторяйте шаги 2 и 3 до тех пор, пока назначение кластера не изменится или не будет достигнут заданный пользователем допуск или максимальное количество итераций.

Теперь следующий вопрос заключается в том, как мы можем измерить сходство между двумя точками выборки. Наиболее часто используемой мерой для определения сходства является квадрат евклидова расстояния между двумя точками x и y в m-мерном пространстве:

В приведенном выше уравнении индекс j относится к j-му измерению (столбцу признаков) точек выборки x и y.

Интуитивно алгоритмы K-средних можно рассматривать как простую задачу оптимизации, итеративный подход к минимизации внутрикластерной суммы квадратов ошибок (SSE), которую также называют инерцией кластера:

Здесь mu — центр тяжести j-го кластера, а w(i, j) = 1, если образец x находится в j-м кластере, иначе w(i, j) = 0.

Мы применим K-Means к нашему набору данных, используя класс KMeans из модуля кластеров scikit-learn.

Создайте кластеры с помощью KMeans

result_df = scaled_df.copy()
kmeans = KMeans(n_clusters=5)
clusters = kmeans.fit_predict(result_df.values)
result_df[‘Cluster’] = clusters
result_df.head()

Оптимизация количества кластеров с использованием графика изгиба и силуэта

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

Из приведенных выше двух графиков мы можем сказать, что 5 — это оптимальное количество кластеров. Я рекомендую вам попробовать с 4 и 6 и увидеть разницу.

Получите полный код здесь

Агломеративная иерархическая кластеризация с использованием дендрограммы

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

Существует два основных подхода к иерархической кластеризации: агломеративный и разделительный.

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

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

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

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

# Apply complete linkage agglomeration using linkage function which # returns a linkage matrix
row_clusters = linkage(scaled_df.values, method=’complete’, metric=’euclidean’)
# Now let’s make a dendrogram
plt.figure(figsize=(12, 8))
row_dndr = dendrogram(row_clusters, labels=scaled_df.index)
plt.tight_layout()
plt.ylabel(‘Euclidean Distance’)
plt.show()

Визуализация кластеров с помощью PCA (анализ основных компонентов)

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

# PCA with three priciple components
pca = PCA(n_components=3)
# PCA Dataframe
PCs = pd.DataFrame(pca.fit_transform(result_df.drop([‘Cluster’], axis=1)))
PCs.columns = [‘PC1’, ‘PC2’, ‘PC3’]
# Concatenate all PCs dataframes with result df
result_df = pd.concat([result_df, PCs], axis=1, join=’inner’)
# Seperate out 5 different clusters
cluster0 = result_df[result_df[‘Cluster’] == 0]
cluster1 = result_df[result_df[‘Cluster’] == 1]
cluster2 = result_df[result_df[‘Cluster’] == 2]
cluster3 = result_df[result_df[‘Cluster’] == 3]
cluster4 = result_df[result_df[‘Cluster’] == 4]

Теперь, чтобы визуализировать основные компоненты кластера, мы будем использовать 3D-диаграмму рассеяния из объектов графиков.

# plotly imports
import plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
# trace1 for `cluster0`
trace1 = go.Scatter3d(x=cluster0[‘PC1’], y=cluster0[‘PC2’], z=cluster0[‘PC3’], mode=’markers’, name=’Cluster0', 
 marker=dict(color = ‘rgba(255, 128, 255, 0.8)’), text=None)
# trace2 for `cluster1`
trace2 = go.Scatter3d(x=cluster1[‘PC1’], y=cluster1[‘PC2’], z=cluster0[‘PC3’], mode=’markers’, name=’Cluster1', 
 marker=dict(color = ‘rgba(255, 128, 2, 0.8)’), text=None)
# trace3 for `cluster2`
trace3 = go.Scatter3d(x=cluster2[‘PC1’], y=cluster2[‘PC2’], z=cluster0[‘PC3’], mode=’markers’, name=’Cluster2', 
 marker=dict(color = ‘rgba(20, 128, 200, 0.8)’), text=None)
# trace4 for `cluster3`
trace4 = go.Scatter3d(x=cluster3[‘PC1’], y=cluster3[‘PC2’], z=cluster0[‘PC3’], mode=’markers’, name=’Cluster3', 
 marker=dict(color = ‘rgba(0, 255, 200, 0.8)’), text=None)
# trace5 for `cluster4`
trace5 = go.Scatter3d(x=cluster4[‘PC1’], y=cluster4[‘PC2’], z=cluster0[‘PC3’], mode=’markers’, name=’Cluster4', 
 marker=dict(color = ‘rgba(150, 0, 200, 0.8)’), text=None)
data = [trace1, trace2, trace3, trace4, trace5]
title = ‘3D Visualization of clusters using PCA’
layout = dict(title=title, xaxis=dict(title=’PC1',   ticklen=5,zeroline=False),
 yaxis=dict(title=’PC2', ticklen=5, zeroline=False))
fig = dict(data=data, layout=layout)
iplot(fig)

Получите полный код здесь

Вывод

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