通俗易懂讲透谱聚类(Spectral Clustering)
通俗易懂讲透谱聚类(Spectral Clustering)|本科生/研究生都能看懂
谱聚类是解决复杂形状、非线性边界数据最强的聚类算法之一,K-Means分不出来的月牙形、环形、交错数据,它都能轻松搞定。
本文用大白话+生活案例+数学推导+可直接运行代码+总结,适合课堂笔记、实验报告。
一、谱聚类是什么?一句话讲明白
谱聚类 = 把数据建成图 → 切图分组 → 降维 → 简单聚类
核心:不直接看原始坐标,而是看点与点之间的“连接关系”。
对比一下:
- K-Means:只看距离,只擅长球形簇
- 谱聚类:看连接强度,擅长任意形状、交错、非线性分布的数据
二、超通俗小案例:5个地点自动分两组
有5个地点 A、B、C、D、E,距离如下,想分成两个“活动圈”。
| A | B | C | D | E | |
|---|---|---|---|---|---|
| A | 0 | 2 | 8 | 10 | 9 |
| B | 2 | 0 | 7 | 9 | 8 |
| C | 8 | 7 | 0 | 2 | 3 |
| D | 10 | 9 | 2 | 0 | 1 |
| E | 9 | 8 | 3 | 1 | 0 |
谱聚类怎么做?
- 建图:把地点当“点”,距离当“边权重”
- 转相似度:距离越近,相似度越高
- 建拉普拉斯矩阵:记录点之间的连接关系
- 特征分解:把复杂数据投影到简单空间
- 聚类:在新空间里轻松分成两类
结果
组1:A、B
组2:C、D、E
三、谱聚类核心流程(最标准 6 步)
-
构建相似度矩阵 W
用高斯核(RBF)计算两点相似性:
wij=e−∥xi−xj∥22σ2w_{ij}=e^{-\frac{\|x_i-x_j\|^2}{2\sigma^2}}wij=e−2σ2∥xi−xj∥2 -
构建度矩阵 D
对角矩阵,每个值是当前点所有相似度之和:
Dii=∑jWijD_{ii}=\sum_j W_{ij}Dii=∑jWij -
构建拉普拉斯矩阵 L
最常用对称归一化拉普拉斯:
Lsym=I−D−1/2WD−1/2L_{sym}=I-D^{-1/2}WD^{-1/2}Lsym=I−D−1/2WD−1/2 -
特征分解
求 L 最小的 k 个特征值对应的特征向量。 -
构建新特征空间
把特征向量按行拼成新数据,每行代表一个点。 -
普通聚类
在新空间里跑 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σ2∥xi−xj∥2)
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=I−D−1/2WD−1/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()
代码输出三张图
- 原始图像
- 谱聚类分割图
- 区域边界图
七、谱聚类优缺点(面试/报告必背)
✅ 优点
- 擅长非线性、任意形状簇
- 高维数据表现好
- 只需相似度矩阵,可自定义相似规则
- 数学优美、理论稳定
❌ 缺点
- 计算慢 O(n³),大数据不行
- 内存占用大(n×n 矩阵)
- 对参数敏感(gamma、核函数)
- 需要指定簇数 k
八、适用场景(什么时候用?)
👉 首选谱聚类
- 数据形状不规则:月牙、环形、交错
- 小规模高维数据
- 图像分割、视频分割、图节点聚类
- 社交网络、文本聚类、特征学习
👉 不要用
- 数据量 >1万 → 用 K-Means / Mini-Batch K-Means
- 带噪声、密度不均 → 用 DBSCAN
- 不知道簇数 → 用 Mean Shift / 层次聚类
九、一句话总结
谱聚类是基于图论与特征分解的高级聚类算法,擅长处理K-Means无法解决的非线性、复杂形状数据,是机器学习、图像处理、数据挖掘中最强大的聚类工具之一。
更多推荐
所有评论(0)