Добавил:
baraevaliza
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы по ОМО 2025 / Baraeva_Elizaveta_lb2
.pdf
21
перекрываются в диапазоне (0-0.5), что может указывать на недостаточно
четкое разделение между ними. Форма плотности распределений всех
кластеров схожи. Также на Рисунке 2.6.3 ситуация похожая. Кластер 1 четко
выделяется, а кластеры 0 и 2 перекрываются в диапазоне. Форма плотности
распределений 0 и 1 кластеров схожи. Кластер 3 имеет более плотное
распределение.
На Рисунке 2.6.4 видно, что кластеры попарно перекрываются. Кластеры
0 и 7 перекрываются в диапазоне от 0.5 до 2, кластеры 1 и 2 перекрываются в
диапазоне от -1 до 0.5, кластеры 3 и 4 перекрываются в диапазоне от -0.5 до
1, кластеры 5 и 6 перекрываются в диапазоне от -2 до -0.5. Это может
указывать на недостаточно четкое разделение между ними. Ширина
распределения кластеров 0, 2, 4, 6 схожа, также и у кластеров 1, 3, 5, 7.
Нормальная форма плотности распределений у кластеров 0 и 6. На Рисунке
2.6.5 видно, что кластеры 1, 3, 5 перекрываются в диапазоне от -1 до 1.
Ширина распределения кластеров 0, 1, 3, 5, 6, 7 почти одинаковая, но только
у 3 и 7 схожая плотность. Кластеры 2 и 4 имеют одинаковую ширину
распределения, но разную плотность.
Я считаю, что для датасета blobs кластеризация K-means применилась
успешно, в то время как для датасета circles кластеризация прошла менее
успешно из-за большого количества асимметрий и перекрытий.
2.7. Рассчитайте для каждого кластера кол-во точек, среднее, СКО,
минимум и максимум. Сопоставьте результаты с построенными
графиками.
Создадим функцию cluster_stats, которая принимает датафрейм и
название признака. С помощью groupby датафрейм группируется по номеру

22
кластера, а с помощью agg вычисляются статистические характеристики.
Далее сортируется по номеру кластера и выводится на экран. Реализация
приведена в Листинге 2.7.1, а результат в Таблице 2.7.2 – Таблице 2.7.5.
Листинг 2.7.1 – Расчет статистик
def cluster_stats(df, attribute):
stats = df.groupby('cluster')[attribute].agg(['count',
'mean', 'std', 'min', 'max'])
print(stats.sort_values('cluster'))
cluster_stats(blobs_norm_df, 'x')
cluster_stats(blobs_norm_df, 'y')
cluster_stats(circles_std_df, 'x')
cluster_stats(circles_std_df, 'y')
Таблица 2.7.2 – Результат вывода статистики датасета blobs для x
cluster
count
mean
std
min
max
0
166
0.249492
0.090155
0.000000
0.482227
1
71
0.242878
0.102131
0.037112
0.468100
2
63
0.740832
0.104207
0.527013
1.000000
Таблица 2.7.3 – Результат вывода статистики датасета blobs для y
cluster
count
mean
std
min
max
0
166
0.213274
0.084917
0.000000
0.460471
1
71
0.803645
0.089291
0.559775
1.000000
2
63
0.227612
0.092792
0.025210
0.406916
Таблица 2.7.4 – Результат вывода статистики датасета circles для x
cluster
count
mean
std
min
max
0
33
1.259450
0.356834
0.653029
1.983105
1
75
-0.530798
0.181521
-0.939187
-0.200871
2
33
-0.291297
0.457820
-1.121213
0.474982
3
80
0.542067
0.209067
0.200384
1.024004

23
4
35
0.320190
0.526320
-0.531357
1.221603
5
35
-1.597528
0.194666
-1.947255
-1.254965
6
34
-1.231016
0.421125
-1.917494
-0.449514
7
33
1.547176
0.220462
1.106539
1.955767
Таблица 2.7.5 – Результат вывода статистики датасета circles для y
cluster
count
mean
std
min
max
0
33
-1.139372
0.394222
-1.823277
-0.403788
1
75
0.002209
0.449459
-0.820961
0.900411
2
33
-1.725708
0.154277
-1.986989
-1.450269
3
80
-0.006595
0.455706
-0.801805
0.784234
4
35
1.681425
0.176846
1.319181
2.037882
5
35
-0.513651
0.507454
-1.249664
0.365819
6
34
1.087406
0.361896
0.391005
1.703718
7
33
0.517142
0.513431
-0.294528
1.332306
Результаты соответствуют графикам.
3. DBSCAN:
3.1. Подберите параметры алгоритма DBSCAN, которые на ваш взгляд
дают наилучшие результаты. Опишите процесс (почему и как
изменяли параметры) подбора параметров.
MinPoints возьмем равным 6, чтобы алгоритм не был слишком
чувствительным к шуму. Для подбора значения эпсилон будем использовать
график K-расстояний, который для каждой точки вычисляет расстояния до 6
ближайших соседей, берет дальнее расстояние и строит график для точек,
сортируя эти расстояния по возрастанию. Ордината изгиба графика и будет
значением эпсилон. Для нахождения «соседей» воспользуемся

24
NearestNeighbors из библиотеки sklearn.neighbors. Далее для каждой точки
отсортируем массив расстояний и возьмем последнее. Реализация приведена
в Листинге 3.1.1. Графики представлены на Рисунке 3.1.2 и Рисунке 3.1.3.
Листинг 3.1.1 – Реализация построения графика K-расстояний
from sklearn.neighbors import NearestNeighbors
def k_distance_graph(df):
neighbors = NearestNeighbors(n_neighbors=6).fit(df)
distances, indices = neighbors.kneighbors(df)
distances = sorted(distances[:, 5])
plt.plot(distances)
plt.ylabel("Расстояние до 6-го ближайшего соседа")
plt.xlabel("Точки")
plt.grid(True)
plt.show()
blobs_df = pd.DataFrame(blobs_norm, columns=['x', 'y'])
circles_df = pd.DataFrame(circles_std, columns=['x', 'y'])
k_distance_graph(blobs_df)
k_distance_graph(circles_df)
Рисунок 3.1.2 – График K-расстояний датасета blobs

25
Рисунок 3.1.3 – График K-расстояний датасета circles
Для датасета blobs эпсилон возьмем равным 0.08, а для circles – 0.3.
3.2. Постройте диаграмму рассеяния результатов кластеризации с
выделением разным цветом разных кластеров.
Для кластеризации импортируем DBSCAN из библиотеки sklearn.cluster.
Создадим функцию dbscan, которая принимает датафрейм, значение эпсилон
и значение minPoints. Она кластеризует данные, отдельно записывает
кластеры и выбросы и рисует диаграмму. Реализация приведена в Листинге
3.2.1. Диаграммы представлены на Рисунке 3.2.2 и Рисунке 3.2.3.
Листинг 3.2.1 – Реализация DBSCAN и построения диаграмм
from sklearn.cluster import DBSCAN
def dbscan(df, esp, min_samples):
clusters = DBSCAN(eps=esp,
min_samples=min_samples).fit_predict(df)
core_points = df[clusters != -1]
outliers = df[clusters == -1]
plt.scatter(core_points.iloc[:, 0], core_points.iloc[:, 1],
c=clusters[clusters != -1], s=50)

26
plt.scatter(outliers.iloc[:, 0], outliers.iloc[:, 1],
c='red', marker='x', s=50)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
dbscan(blobs_df, 0.08, 6)
dbscan(circles_df, 0.3, 6)
Рисунок 3.2.2 – Диаграмма рассеяния датасета blobs
Рисунок 3.2.3 – Диаграмма рассеяния датасета circles

27
3.3. Сделайте выводы об успешности кластеризации.
Кластеризация датасета blobs выполнена успешно. DBSCAN нашел
логично отделенные кластеры и корректно определил выбросы. С K-means
количество и вид кластеров совпадают.
Кластеризация датасета circles выполнена также хорошо. Алгоритм
корректно определил как плотные компактные группы, так и сложную
структуру – кольцо. С K-means количество кластеров не совпадает.
Одинаковы только 2 внутренних кластера и отчасти желтый кластер.
4. Иерархическая кластеризация:
4.1. Проведите иерархическую кластеризацию для параметра linkage
указанного в вашем варианте, используя количество кластеров,
полученных в п.2 или п.3. Постройте дендрограмму. Сделайте
выводы, о разделении кластеров и необходимости изменить
количество кластеров (если считаете, что необходимо изменить
количество кластеров, то повторите кластеризацию с другим
количеством кластеров).
Для иерархической кластеризации импортируем AgglomerativeClustering
из библиотеки sklearn.cluster. Создадим функцию plot_dendrogram, которая
принимает датасет в виде numpy.ndarray и параметры для дендрограммы.
Создается модель AgglomerativeClustering с параметрами, позволяющими
построить полную дендрограмму (без ограничения на число кластеров). Для
каждого шага объединения кластеров подсчитывается, сколько точек в них
входит. Формируется linkage_matrix – матрица, которая описывает, какие
кластеры объединяются, на каком расстоянии и сколько элементов они
содержат. Строится сама дендрограмма с помощью dendrogram из

28
scipy.cluster.hierarchy, а также добавляется подпись по оси x. В конце функция
вызывается для двух датасетов blobs и circles. Реализация приведена в
Листинге 4.1.1. Дендрограммы представлены на Рисунке 4.1.2 и Рисунке
4.1.3.
Листинг 4.1.1 – Реализация построения дендрограмм
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram
def plot_dendrogram(norm, **kwargs):
model = AgglomerativeClustering(distance_threshold=0,
n_clusters=None).fit(norm)
counts = np.zeros(model.children_.shape[0])
n_samples = len(model.labels_)
for i, merge in enumerate(model.children_):
current_count = 0
for child_idx in merge:
if child_idx < n_samples:
current_count += 1
else:
current_count += counts[child_idx - n_samples]
counts[i] = current_count
linkage_matrix = np.column_stack([model.children_,
model.distances_, counts]).astype(float)
dendrogram(linkage_matrix, **kwargs)
plt.xlabel("Количество точек в узле (или индекс точки, если
скобки отсутствуют)")
plt.show()
plot_dendrogram(blobs_norm, truncate_mode="level", p=3)
plot_dendrogram(circles_std, truncate_mode="level", p=3)

29
Рисунок 4.1.2 – Дендрограмма датасета blobs
Рисунок 4.1.3 – Дендрограмма датасета circles
Главный критерий – поиск значительного увеличения расстояния между
объединяемыми кластерами. На Рисунке 4.1.2 видны 3 больших скачка,
значит для этого датасета оптимальное количество кластеров – 3. На Рисунке

30
4.1.3 видны 3 больших скачка: с 10 до 20, с 7.5 до 17.5, с 5 до 12.5 и 1
поменьше: с 7.5 до 12.5. Для этого датасета оптимальное количество
кластеров – 4.
4.2. Постройте диаграмму рассеяния результатов кластеризации с
выделением разным цветом разных кластеров.
Создадим функцию hierarchy_clustering, которая принимает датафрейм и
метки классов. В ней строится диаграмма рассеяния. До вызова функции
используется иерархическая кластеризация. Для датасета blobs количество
кластеров равно 3, а для датасета circles кластеризация производится для 8 и
4 кластеров, т.к. в п.2 и п.3 было получено разное количество кластеров. В
конце функция вызывается 3 раза. Реализация приведена в Листинге 4.2.1.
Диаграммы представлены на Рисунке 4.2.2, Рисунке 4.2.3 и Рисунке 4.2.4.
Листинг 4.2.1 – Реализация иерархической кластеризации и построения
диаграмм рассеяния
def hierarchy_clustering(df, clust):
plt.scatter(df.iloc[:, 0], df.iloc[:, 1], c=clust)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
blobs_ag_clust = AgglomerativeClustering(n_clusters = 3,
linkage = 'ward').fit_predict(blobs_df)
circles_ag_clust_8 = AgglomerativeClustering(n_clusters = 8,
linkage = 'ward').fit_predict(circles_df)
circles_ag_clust_4 = AgglomerativeClustering(n_clusters = 4,
linkage = 'ward').fit_predict(circles_df)
hierarchy_clustering(blobs_df, blobs_ag_clust)
hierarchy_clustering(circles_df, circles_ag_clust_8)
hierarchy_clustering(circles_df, circles_ag_clust_4)
Соседние файлы в папке Лабы по ОМО 2025
