通俗易懂讲透谱聚类(Spectral Clustering)|本科生/研究生都能看懂

谱聚类是解决复杂形状、非线性边界数据最强的聚类算法之一,K-Means分不出来的月牙形、环形、交错数据,它都能轻松搞定。

本文用大白话+生活案例+数学推导+可直接运行代码+总结,适合课堂笔记、实验报告。


一、谱聚类是什么?一句话讲明白

谱聚类 = 把数据建成图 → 切图分组 → 降维 → 简单聚类
核心:不直接看原始坐标,而是看点与点之间的“连接关系”

对比一下:

  • K-Means:只看距离,只擅长球形簇
  • 谱聚类:看连接强度,擅长任意形状、交错、非线性分布的数据

二、超通俗小案例:5个地点自动分两组

有5个地点 A、B、C、D、E,距离如下,想分成两个“活动圈”。

ABCDE
A028109
B20798
C87023
D109201
E98310

谱聚类怎么做?

  1. 建图:把地点当“点”,距离当“边权重”
  2. 转相似度:距离越近,相似度越高
  3. 建拉普拉斯矩阵:记录点之间的连接关系
  4. 特征分解:把复杂数据投影到简单空间
  5. 聚类:在新空间里轻松分成两类

结果

组1:A、B
组2:C、D、E


三、谱聚类核心流程(最标准 6 步)

  1. 构建相似度矩阵 W
    用高斯核(RBF)计算两点相似性:
    wij=e−∥xi−xj∥22σ2w_{ij}=e^{-\frac{\|x_i-x_j\|^2}{2\sigma^2}}wij=e2σ2xixj2

  2. 构建度矩阵 D
    对角矩阵,每个值是当前点所有相似度之和:
    Dii=∑jWijD_{ii}=\sum_j W_{ij}Dii=jWij

  3. 构建拉普拉斯矩阵 L
    最常用对称归一化拉普拉斯
    Lsym=I−D−1/2WD−1/2L_{sym}=I-D^{-1/2}WD^{-1/2}Lsym=ID1/2WD1/2

  4. 特征分解
    求 L 最小的 k 个特征值对应的特征向量。

  5. 构建新特征空间
    把特征向量按行拼成新数据,每行代表一个点。

  6. 普通聚类
    在新空间里跑 K-Means,得到最终簇。


四、核心公式(报告/作业直接用)

1. 相似度(RBF 核)

wij=exp⁡(−∥xi−xj∥22σ2)w_{ij} = \exp\left(-\frac{\|x_i - x_j\|^2}{2\sigma^2}\right)wij=exp(2σ2xixj2)

2. 度矩阵

Dii=∑j=1nwijD_{ii} = \sum_{j=1}^n w_{ij}Dii=j=1nwij

3. 归一化拉普拉斯矩阵

Lsym=I−D−1/2WD−1/2L_{sym} = I - D^{-1/2}WD^{-1/2}Lsym=ID1/2WD1/2

4. 聚类目标:最小化归一化割(Ncut)

Ncut(A1,...Ak)=∑i=1kCut(Ai,Ai‾)Vol(Ai)Ncut(A_1,...A_k) = \sum_{i=1}^k \frac{Cut(A_i,\overline{A_i})}{Vol(A_i)}Ncut(A1,...Ak)=i=1kVol(Ai)Cut(Ai,Ai)


五、为什么谱聚类这么强?(关键理解)

  • K-Means 假设簇是凸的、球形
  • 谱聚类不假设形状,只看图连接
  • 非线性可分数据,变成线性可分

一句话:
谱聚类 = 用图论+线性代数,给数据“换一套坐标系”,让复杂数据变简单。


六、完整实战代码:图像分割(可直接复制运行)

谱聚类最经典应用:图像分割,把图片按颜色/位置分成区域。

# 安装依赖
# pip install numpy matplotlib scikit-learn scikit-image

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import SpectralClustering
from skimage import io, color
from skimage.transform import rescale
import warnings
warnings.filterwarnings('ignore')

# ====================== 1. 加载并缩小图片 ======================
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a3/June_odd-eyed-cat.jpg/800px-June_odd-eyed-cat.jpg"
image = io.imread(image_url)
image = rescale(image, 0.2, multichannel=True)  # 缩小加速
rows, cols, _ = image.shape

# ====================== 2. 构造像素特征:RGB + 坐标 ======================
X = []
for i in range(rows):
    for j in range(cols):
        r, g, b = image[i, j]
        X.append([r, g, b, i/rows, j/cols])
X = np.array(X)

# ====================== 3. 谱聚类 ======================
n_clusters = 4
sc = SpectralClustering(
    n_clusters=n_clusters,
    affinity='rbf',
    gamma=10,
    random_state=42
)
labels = sc.fit_predict(X)

# ====================== 4. 可视化结果 ======================
# 原图
plt.figure(figsize=(12, 4))
plt.subplot(131)
plt.imshow(image)
plt.title("Original Image")
plt.axis('off')

# 分割图
seg_img = np.zeros((rows, cols, 3))
colors = np.random.rand(n_clusters, 3)
for i in range(rows):
    for j in range(cols):
        seg_img[i, j] = colors[labels[i * cols + j]]

plt.subplot(132)
plt.imshow(seg_img)
plt.title("Segmented Image")
plt.axis('off')

# 边界图
bound = np.zeros_like(seg_img)
for i in range(1, rows-1):
    for j in range(1, cols-1):
        if labels[i*cols+j] != labels[i*cols+j+1] or \
           labels[i*cols+j] != labels[(i+1)*cols+j]:
            bound[i, j] = [1, 0, 0]

plt.subplot(133)
plt.imshow(bound)
plt.title("Boundary")
plt.axis('off')

plt.tight_layout()
plt.show()

代码输出三张图

  1. 原始图像
  2. 谱聚类分割图
  3. 区域边界图

七、谱聚类优缺点(面试/报告必背)

✅ 优点

  1. 擅长非线性、任意形状簇
  2. 高维数据表现好
  3. 只需相似度矩阵,可自定义相似规则
  4. 数学优美、理论稳定

❌ 缺点

  1. 计算慢 O(n³),大数据不行
  2. 内存占用大(n×n 矩阵)
  3. 对参数敏感(gamma、核函数)
  4. 需要指定簇数 k

八、适用场景(什么时候用?)

👉 首选谱聚类

  • 数据形状不规则:月牙、环形、交错
  • 小规模高维数据
  • 图像分割、视频分割、图节点聚类
  • 社交网络、文本聚类、特征学习

👉 不要用

  • 数据量 >1万 → 用 K-Means / Mini-Batch K-Means
  • 带噪声、密度不均 → 用 DBSCAN
  • 不知道簇数 → 用 Mean Shift / 层次聚类

九、一句话总结

谱聚类是基于图论与特征分解的高级聚类算法,擅长处理K-Means无法解决的非线性、复杂形状数据,是机器学习、图像处理、数据挖掘中最强大的聚类工具之一。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐