машинное обучение
March 31, 2022

Как разбить объекты на категории и дать им краткую характеристику

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

Рассмотрим задачу на примере датасета о цветках Ириса, который получим с помощью библиотеки 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()

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