Как разбить объекты на категории и дать им краткую характеристику
Зачастую возникает задача разбить объекты на категории и найти их типичные характеристики. Одним из способов сделать это является кластеризация на группы и подсчет средних метрик.
Рассмотрим задачу на примере датасета о цветках Ириса, который получим с помощью библиотеки Scikit-learn:
import pandas as pd from sklearn.cluster import KMeans from sklearn.datasets import load_iris import matplotlib.pyplot as plt import seaborn as sns sns.set()
df, target = load_iris(return_X_y=True, as_frame=True) df['target'] = target df.head()
Теперь проведем кластеризацию методом k-средних и запишем метки в столбец 'cluster':
cl = KMeans(n_clusters=3) labels = cl.fit_predict(df) df['cluster'] = labels df.head()
Следует отметить, что кластеризация не зная о том, что у нас три класса объектов разделила их почти правильно (я немного схитрил, так как знал количество разных групп и задал это число при инициализации объекта класса):
df[df['target']==df['cluster']].shape[0], df.shape[0]
Визуализация по двум параметрам ('sepal length (cm)', 'petal length (cm)') подтверждает наш вывод о хорошей кластеризации:
fig, axis = plt.subplots(1,2, figsize=(15,6)) sns.scatterplot(data = df, ax = axis[0], x='sepal length (cm)', y = 'petal length (cm)', hue='target') sns.scatterplot(data = df, ax = axis[1], x='sepal length (cm)', y = 'petal length (cm)', hue='cluster')
Имея в распоряжении классы, мы можем сгруппировать по ним объекты и подсчитать агрегирующие метрики, например, среднее:
df.drop('target', axis=1).groupby('cluster').mean()
Чем сильнее средние признаков отличаются, тем лучше они характеризуют разные группы.