层次聚类算法在瑞士卷数据集上的应用

层次聚类是一种常用的数据聚类方法,它可以在没有预设类别数量的情况下,根据数据点之间的距离进行聚类。本文将介绍如何在瑞士卷数据集上应用层次聚类算法,包括无结构和有结构的聚类方法。瑞士卷数据集是一个非线性的三维数据集,常用于测试聚类算法的性能。

无结构层次聚类

在无结构层次聚类中,不考虑数据点之间的连接性约束,仅根据距离进行聚类。这种方法可能会在瑞士卷的不同折叠处形成跨越的聚类,从而破坏了数据集的结构。以下是使用Python进行无结构层次聚类的代码示例:

from sklearn.datasets import make_swiss_roll from sklearn.cluster import AgglomerativeClustering import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 生成瑞士卷数据集 n_samples = 1500 noise = 0.05 X, _ = make_swiss_roll(n_samples, noise=noise) X[:, 1] *= 0.5 # 使数据集更细长 # 执行无结构层次聚类 print("执行无结构层次聚类...") st = time.time() ward = AgglomerativeClustering(n_clusters=6, linkage="ward") ward.fit(X) elapsed_time = time.time() - st label = ward.labels_ print(f"耗时:{elapsed_time:.2f}秒") print(f"数据点数量:{label.size}") # 绘制无结构层次聚类结果 fig1 = plt.figure() ax1 = fig1.add_subplot(111, projection="3d", elev=7, azim=-80) ax1.set_position([0, 0, 0.95, 1]) for l in np.unique(label): ax1.scatter(X[label == l, 0], X[label == l, 1], X[label == l, 2], color=plt.cm.jet(float(l) / np.max(label + 1)), s=20, edgecolor="k") plt.suptitle(f"无连接性约束(耗时{elapsed_time:.2f}秒)")

在上述代码中,首先生成了瑞士卷数据集,然后使用AgglomerativeClustering类进行无结构层次聚类。最后,使用matplotlib库绘制了聚类结果。可以看到,无结构聚类在瑞士卷的不同折叠处形成了跨越的聚类,破坏了数据集的结构。

有结构层次聚类

为了解决无结构层次聚类中的问题,可以引入连接性约束,即在聚类过程中考虑数据点之间的连接性。这种方法可以更好地保持数据集的结构,形成更合理的聚类结果。以下是使用Python进行有结构层次聚类的代码示例:

from sklearn.neighbors import kneighbors_graph # 定义k-最近邻连接性 connectivity = kneighbors_graph(X, n_neighbors=10, include_self=False) # 执行有结构层次聚类 print("执行有结构层次聚类...") st = time.time() ward = AgglomerativeClustering(n_clusters=6, connectivity=connectivity, linkage="ward") ward.fit(X) elapsed_time = time.time() - st label = ward.labels_ print(f"耗时:{elapsed_time:.2f}秒") print(f"数据点数量:{label.size}") # 绘制有结构层次聚类结果 fig2 = plt.figure() ax2 = fig2.add_subplot(121, projection="3d", elev=7, azim=-80) ax2.set_position([0, 0, 0.95, 1]) for l in np.unique(label): ax2.scatter(X[label == l, 0], X[label == l, 1], X[label == l, 2], color=plt.cm.jet(float(l) / np.max(label + 1)), s=20, edgecolor="k") plt.suptitle(f"有连接性约束(耗时{elapsed_time:.2f}秒)") plt.show()

在上述代码中,首先定义了k-最近邻连接性,然后在AgglomerativeClustering类中引入了连接性约束。最后,使用matplotlib库绘制了聚类结果。可以看到,有结构聚类在瑞士卷的不同折叠处形成了更合理的聚类结果,保持了数据集的结构。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485