Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы по ОМО 2025 / Baraeva_Elizaveta_lb2

.pdf
Скачиваний:
0
Добавлен:
09.09.2026
Размер:
1 Мб
Скачать
☆
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