有和没有结构的凝聚聚类#
此示例展示了对数据施加连接图以捕获局部结构的影响。该图只是 20 个最近邻的图。
施加连接有两个优点。首先,使用稀疏连接矩阵进行聚类通常更快。
其次,在使用连接矩阵时,单链接、平均链接和完全链接是不稳定的,并且倾向于创建几个快速增长的聚类。事实上,平均链接和完全链接通过在合并两个聚类时考虑两个聚类之间的所有距离来对抗这种渗透行为(而单链接通过仅考虑聚类之间的最短距离来夸大这种行为)。连接图打破了平均链接和完全链接的这种机制,使它们类似于更脆弱的单链接。这种影响在非常稀疏的图(尝试减少 kneighbors_graph 中的邻居数量)和完全链接中更为明显。特别是,在图中具有非常少的邻居,会强加一种接近单链接的几何形状,而单链接众所周知具有这种渗透不稳定性。
# Authors: Gael Varoquaux, Nelle Varoquaux
# License: BSD 3 clause
import time
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import AgglomerativeClustering
from sklearn.neighbors import kneighbors_graph
# Generate sample data
n_samples = 1500
np.random.seed(0)
t = 1.5 * np.pi * (1 + 3 * np.random.rand(1, n_samples))
x = t * np.cos(t)
y = t * np.sin(t)
X = np.concatenate((x, y))
X += 0.7 * np.random.randn(2, n_samples)
X = X.T
# Create a graph capturing local connectivity. Larger number of neighbors
# will give more homogeneous clusters to the cost of computation
# time. A very large number of neighbors gives more evenly distributed
# cluster sizes, but may not impose the local manifold structure of
# the data
knn_graph = kneighbors_graph(X, 30, include_self=False)
for connectivity in (None, knn_graph):
for n_clusters in (30, 3):
plt.figure(figsize=(10, 4))
for index, linkage in enumerate(("average", "complete", "ward", "single")):
plt.subplot(1, 4, index + 1)
model = AgglomerativeClustering(
linkage=linkage, connectivity=connectivity, n_clusters=n_clusters
)
t0 = time.time()
model.fit(X)
elapsed_time = time.time() - t0
plt.scatter(X[:, 0], X[:, 1], c=model.labels_, cmap=plt.cm.nipy_spectral)
plt.title(
"linkage=%s\n(time %.2fs)" % (linkage, elapsed_time),
fontdict=dict(verticalalignment="top"),
)
plt.axis("equal")
plt.axis("off")
plt.subplots_adjust(bottom=0, top=0.83, wspace=0, left=0, right=1)
plt.suptitle(
"n_cluster=%i, connectivity=%r"
% (n_clusters, connectivity is not None),
size=17,
)
plt.show()
脚本总运行时间:(0 分钟 2.316 秒)
相关示例
比较玩具数据集上的不同层次链接方法
数字的 2D 嵌入上的各种凝聚聚类
层次聚类:结构化与非结构化 Ward
在硬币图像上演示结构化 Ward 层次聚类