scikit-learn/SpectralClustering

用相似度邻接矩阵进行谱聚类

scikit-learn 将样本间的相似度保存为加权邻接矩阵,计算图 Laplacian 的谱嵌入,再据此划分样本簇。

1.6.1检索与计算核验 2026-10-12
相关概念

工程问题#

样本簇可能沿弯曲形状分布,直接按原始坐标到中心的距离划分并不总合适。谱聚类先把样本看作图上的顶点,用成对相似度表达连接强度,再利用图结构寻找分组。

实际实现#

在默认 RBF affinity 路径中,SpectralClustering.fit 通过 pairwise_kernels 构造 n×n 的 affinity_matrix_,矩阵的第 i、j 项是样本 i 与 j 的相似度边权。_spectral_embedding 将其作为 adjacency 传给 SciPy,计算归一化 Laplacian 和特征向量;之后默认用 k-means 给嵌入分配标签。

处理流程#

  1. 以样本为顶点,用 RBF 核生成成对相似度邻接矩阵
  2. 核对矩阵对称性并检查图的连通性
  3. 根据邻接矩阵的度计算归一化 Laplacian,求谱嵌入
  4. 在嵌入上分配聚类标签并返回结果

源码片段#

固定版本 · 原文摘录
sklearn/cluster/_spectral.py1.6.1 · L721–L733
查看原文件
721        elif self.affinity == "precomputed":722            self.affinity_matrix_ = X723        else:724            params = self.kernel_params725            if params is None:726                params = {}727            if not callable(self.affinity):728                params["gamma"] = self.gamma729                params["degree"] = self.degree730                params["coef0"] = self.coef0731            self.affinity_matrix_ = pairwise_kernels(732                X, metric=self.affinity, filter_params=True, **params733            )
SpectralClustering.fit / affinity_matrix_

precomputed 模式接收已有相似度矩阵;默认 RBF 路径通过 pairwise_kernels 生成成对边权。矩阵两维都对应样本编号。

sklearn/cluster/_spectral.py1.6.1 · L745–L763
查看原文件
745        maps = _spectral_embedding(746            self.affinity_matrix_,747            n_components=n_components,748            eigen_solver=self.eigen_solver,749            random_state=random_state,750            eigen_tol=self.eigen_tol,751            drop_first=False,752        )753        if self.verbose:754            print(f"Computing label assignment using {self.assign_labels}")755756        if self.assign_labels == "kmeans":757            _, self.labels_, _ = k_means(758                maps,759                self.n_clusters,760                random_state=random_state,761                n_init=self.n_init,762                verbose=self.verbose,763            )
SpectralClustering.fit / embedding and labels

将相似度矩阵传入谱嵌入,随后默认对嵌入调用 k-means。邻接矩阵实际参与了聚类训练,而非仅被导出供展示。

sklearn/manifold/_spectral_embedding.py1.6.1 · L323–L335
查看原文件
323    n_nodes = adjacency.shape[0]324    # Whether to drop the first eigenvector325    if drop_first:326        n_components = n_components + 1327328    if not _graph_is_connected(adjacency):329        warnings.warn(330            "Graph is not fully connected, spectral embedding may not work as expected."331        )332333    laplacian, dd = csgraph_laplacian(334        adjacency, normed=norm_laplacian, return_diag=True335    )
_spectral_embedding / csgraph_laplacian

从 adjacency 的形状取得顶点数,检查连通性,并交给 SciPy 计算 Laplacian;默认 norm_laplacian 为真。

scipy/sparse/csgraph/_laplacian.pyv1.15.2 · L550–L563
查看原文件
550    np.fill_diagonal(m, 0)551    w = m.sum(axis=axis)552    if normed:553        isolated_node_mask = (w == 0)554        w = np.where(isolated_node_mask, 1, np.sqrt(w))555        m /= w556        m /= w[:, np.newaxis]557        m *= -1558        _setdiag_dense(m, 1 - isolated_node_mask)559    else:560        m *= -1561        _setdiag_dense(m, w)562563    return m.astype(dtype, copy=False), w.astype(dtype, copy=False)
_laplacian_dense

稠密路径先清除对角项,再沿矩阵一维求度并归一化。这里按行列处理图的边权,生成用于特征分解的 Laplacian。

四段源码连接相似度矩阵构造、谱嵌入及标签分配、Laplacian 调用和稠密矩阵处理。特征求解器内部及核函数的数值实现没有包含在摘录中。

收益与取舍#

工程分析

带来的收益

  • 矩阵项直接对应一对样本的连接强度,能交给图 Laplacian 与线性代数例程处理
  • 支持把外部已经计算好的相似度矩阵作为图输入,沿用相同的后续流程

付出的代价

  • 稠密 n×n 相似度矩阵需要 O(n²) 存储,逐行或逐列求度需扫描矩阵;特征求解和标签分配还有各自的成本
  • 核参数与相似度定义会改变图结构和聚类结果;自定义 affinity 不能把距离数值未经转换直接当作相似度
  • 近邻图模式可以使用稀疏矩阵,但其存储、查边和遍历成本与此处的稠密表示不同

可比较的选择

近邻图的稀疏邻接矩阵只保留局部连接以减少图存储和计算,但邻域大小会影响连通性;它是不同的建图选择,不保证与全连接 RBF 图得到相同结果。

直接对原始特征做 k-means无需构造全样本相似度矩阵和求图特征向量,但使用的几何表示与优化目标不同。

版本与适用范围#

核验 scikit-learn 1.6.1 与 SciPy v1.15.2,重点为默认 RBF affinity 的稠密表示。这里保存的是图的边权,不是 Isomap 算出的全点对最短距离。SciPy 构造 Laplacian 时忽略邻接矩阵的对角项;稀疏近邻图和其他特征求解器走各自分支。

参考来源#

源码、官方文档与原始论文
01
相似度邻接矩阵构造

sklearn/cluster/_spectral.py · SpectralClustering.fit / affinity_matrix_

源码1.6.1
02
谱嵌入与标签分配

sklearn/cluster/_spectral.py · SpectralClustering.fit / embedding and labels

源码1.6.1
03
从邻接矩阵构造 Laplacian

sklearn/manifold/_spectral_embedding.py · _spectral_embedding / csgraph_laplacian

源码1.6.1
04
稠密矩阵归一化实现

scipy/sparse/csgraph/_laplacian.py · _laplacian_dense

源码v1.15.2
19 个匹配案例