Сравнительное исследование алгоритмов кластеризации клиентских данных

В этой статье проекта мы проанализируем три алгоритма кластеризации: K-Means, K-Medoids и иерархическая кластеризация. Мы сравним производительность этих алгоритмов на образце набора данных, используя оценку Силуэта. Мы также обсудим факторы, которые следует учитывать при выборе алгоритма кластеризации.

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

K-Means — это популярный алгоритм кластеризации, который работает путем деления набора данных на k кластеров, где k — указанное пользователем число. Алгоритм работает путем итеративного назначения каждой точки данных кластеру с ближайшим средним значением. K-Means — это простой и эффективный алгоритм, но он может быть чувствителен к выбросам и шуму.

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

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

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

Описание набора данных:

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

Набор данных содержит образец данных 8069 с такими атрибутами, как ID, Пол, Ever_Married, Возраст, Выпускник, Профессия, Work_exprience, Spend_score, Family_size, Var_1, Сегментация, в наборе данных отсутствует несколько данных, которые можно использовать для предварительной обработки данных.

Импортируйте все необходимые библиотеки:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans, AgglomerativeClustering
from sklearn_extra.cluster import KMedoids
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.metrics import silhouette_score

Прочитайте набор данных:

df=pd.read_csv('dataset.csv')
df

Преобразуйте строковые данные в числовые данные:

Profession = {
    'Healthcare':1,'Engineer':2,'Lawyer':3,'Entertainment':4, 'Artist':5,
       'Executive':6, 'Doctor':7, 'Homemaker':8, 'Marketing':8
}
data['Profession'] = data['Profession'].map(Profession)

var = {
    'Cat_4':4, 'Cat_6':6, 'Cat_7':7, 'Cat_3':3, 'Cat_1':1, 'Cat_2':2, 'Cat_5':5
}
data['Var_1'] = data['Var_1'].map(var)

Graduate = {
    'No':0, 'Yes':1
}
data['Graduated']=data['Graduated'].map(Graduate)

married = {
    'No':0, 'Yes':1
}
data['Ever_Married']=data['Ever_Married'].map(married)

gender = {
    'Male':0, 'Female':1
}
data['Gender'] = data['Gender'].map(gender)

spending ={
    'Low':0, 'Average':1, 'High':2
}
data['Spending_Score']=data['Spending_Score'].map(spending)

segu = {
    'D':4, 'A':0, 'B':1, 'C':2
}
data['Segmentation']=data['Segmentation'].map(segu)


data = data.drop('ID',axis=1)

Код сначала создает словарь Profession, который сопоставляет каждой профессии число. Затем код использует метод map() для замены каждого значения в столбце «Профессия» соответствующим номером. Код повторяет этот процесс для столбцов Var_1, Graduated, Ever_Married, Gender, Spending_Score и Segmentation. Наконец, код удаляет столбец ID из фрейма данных.

Обновите значение Null, указав среднее значение всех данных в этих конкретных столбцах:

from sklearn.impute import SimpleImputer
# Create a SimpleImputer object
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')

# Fit the imputer to the DataFrame
imputer.fit(df)

# Transform the DataFrame
imputed_df = imputer.transform(df)

# Convert the imputed DataFrame to a Pandas DataFrame
df = pd.DataFrame(imputed_df, columns=df.columns)

Код импортирует класс SimpleImputer из sklearn.impute. Он создает объект SimpleImputer и помещает его в DataFrame. Затем отсутствующие значения вменяются средним значением неотсутствующих значений в каждом столбце. Наконец, вмененный DataFrame преобразуется в Pandas DataFrame.

Выберите номер кластера:

# Choose an appropriate number of clusters
num_clusters = 5

Выполните алгоритмы кластеризации:

# Perform K-Means clustering
kmeans = KMeans(n_clusters=num_clusters, random_state=42)
kmeans_labels = kmeans.fit_predict(data_scaled)

# Perform K-Medoids clustering
kmedoids = KMedoids(n_clusters=num_clusters, random_state=42)
kmedoids_labels = kmedoids.fit_predict(data_scaled)

# Perform Hierarchical clustering
hierarchical = AgglomerativeClustering(n_clusters=num_clusters, affinity='euclidean', linkage='ward')
hierarchical_labels = hierarchical.fit_predict(data_scaled)

Код выполняет три различных алгоритма кластеризации данных: K-Means, K-Medoids и Hierarchical.

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

Кластеризация K-Medoids похожа на K-Means, но вместо использования среднего значения точек данных для их распределения по кластерам используется медиана.

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

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

Выполните уменьшение размерности:

# Apply PCA for dimensionality reduction
pca = PCA(n_components=2)
principal_components = pca.fit_transform(data_scaled)

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

Код сначала создает объект PCA с двумя основными компонентами. Затем он использует метод fit_transform() для преобразования data_scaled DataFrame в новый DataFrame с двумя столбцами, каждый из которых представляет главный компонент.

Создайте фрейм данных с результатами PCA и метками кластеров:

pca_df = pd.DataFrame(data=principal_components, columns=['principal component 1'
                                            , 'principal component 2'])
pca_df['KMeans'] = kmeans_labels
pca_df['KMedoids'] = kmedoids_labels
pca_df['Hierarchical'] = hierarchical_labels

Код создает новый фрейм данных с именем pca_df. DataFrame содержит два основных компонента, а также метки кластеров из алгоритмов K-Means, K-Medoids и Hierarchical clustering.

Код сначала создает DataFrame с именем pca_df из основных компонентов. В качестве аргумента данных задаются основные компоненты, а в качестве аргумента столбцов задаются имена двух основных компонентов.

Затем код добавляет метки кластеров из трех алгоритмов кластеризации в кадр данных pcs_df. Создаются столбцы KMeans, KMedoids и Hierarchical, а метки кластера назначаются соответствующим столбцам.

Преобразуйте центры кластера с помощью PCA:

kmeans_centers_2d = pca.transform(kmeans.cluster_centers_)
kmedoids_centers_2d = pca.transform(kmedoids.cluster_centers_)

Код преобразует центры кластеров из алгоритмов кластеризации K-Means и K-Medoids в 2D-пространство с использованием PCA.

Постройте точечную диаграмму для каждого алгоритма кластеризации:

fig, axes = plt.subplots(1, 3, figsize=(20, 6))
colors = ['r', 'g', 'b', 'y', 'c', 'm']
titles = ['K-Means', 'K-Medoids', 'Hierarchical']

for i, algorithm in enumerate(['KMeans', 'KMedoids', 'Hierarchical']):
    for j in range(num_clusters):
        axes[i].scatter(pca_df.loc[pca_df[algorithm] == j, 'principal component 1'],
                        pca_df.loc[pca_df[algorithm] == j, 'principal component 2'],
                        c=colors[j], label=f'Cluster {j}')
    if algorithm == 'KMeans':
        axes[i].scatter(kmeans_centers_2d[:, 0], kmeans_centers_2d[:, 1], c='black', marker='x', s=100, label='Centroids')
    elif algorithm == 'KMedoids':
        axes[i].scatter(kmedoids_centers_2d[:, 0], kmedoids_centers_2d[:, 1], c='black', marker='x', s=100, label='Medoids')
    elif algorithm == 'Hierarchical':
        for cluster in np.unique(hierarchical_labels):
            cluster_points = principal_components[hierarchical_labels == cluster]
            representative_point = cluster_points.mean(axis=0)
            axes[i].scatter(representative_point[0], representative_point[1], c='black', marker='x', s=100, label='Representative Points' if cluster == 0 else None)

    axes[i].set_title(titles[i])
    axes[i].set_xlabel("Principal Component 1")
    axes[i].set_ylabel("Principal Component 2")
    axes[i].legend()

plt.show()

Код создает 3 подграфика, каждый из которых показывает результаты различных алгоритмов кластеризации: K-Means, K-Medoids и Hierarchical. На каждом подграфике точки данных окрашены в соответствии с их кластером, а центроиды кластера или репрезентативные точки отмечены черными маркерами X. Заголовки и метки осей также устанавливаются для каждого подграфика.

ПРИМЕЧАНИЕ. Иерархическая кластеризация не имеет явных кластерных центров, таких как K-Means и K-Medoids. Однако вы можете рассчитать среднее значение каждого кластера в качестве репрезентативной точки для целей визуализации. Вот как вы можете изменить раздел графика, чтобы включить репрезентативные точки для иерархической кластеризации

Расчет оценки силуэта:

from sklearn.metrics import silhouette_score
kmeans_silhouette = silhouette_score(data_scaled, kmeans_labels)
kmedoids_silhouette = silhouette_score(data_scaled, kmedoids_labels)
hierarchical_silhouette = silhouette_score(data_scaled, hierarchical_labels)

print("Silhouette Scores:")
print(f"K-Means: {(kmeans_silhouette)*100}")
print(f"K-Medoids: {(kmedoids_silhouette)*100}")
print(f"Hierarchical: {(hierarchical_silhouette)*100}")

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

K-Means – лучший алгоритм кластеризации данных. Однако K-Medoids и Hierarchical также являются хорошими алгоритмами кластеризации ваших данных. Лучший алгоритм кластеризации ваших данных зависит от ваших конкретных потребностей.