数学建模学习-谱聚类(Spectral Clustering)教程(30)
写在最前
注意本文的相关代码及例子为同学们提供参考,借鉴相关结构,在这里举一些通俗易懂的例子,方便同学们根据实际情况修改代码,很多同学私信反映能否添加一些可视化,这里每篇教程都尽可能增加一些可视化方便同学理解,但具体使用时,同学们要根据实际情况选择是否在论文中添加可视化图片。
系列教程计划持续更新,同学们可以免费订阅专栏,内容充足后专栏可能付费,提前订阅的同学可以免费阅读,同时相关代码获取可以关注博主评论或私信。
目录
算法简介
谱聚类(Spectral Clustering)是一种基于图论的聚类算法,它利用数据点之间的相似性来进行聚类。与传统的聚类算法(如K-means)相比,谱聚类能够识别出任意形状的簇,并且对于非凸数据集的聚类效果特别好。该算法通过将数据转换到特征空间,利用图的拉普拉斯矩阵的特征向量来降维,然后在低维空间中进行聚类。
算法特点
- 非线性分离能力:能够处理非线性可分的数据集,如同心圆、螺旋形等复杂形状。
- 数学理论基础扎实:基于图论和矩阵理论,具有良好的理论支撑。
- 参数相对较少:主要参数是聚类数量和相似度度量方式。
- 计算复杂度较高:需要计算特征值和特征向量,对于大规模数据集计算开销较大。
- 对噪声相对敏感:需要合理选择相似度度量方式和参数。
算法原理
谱聚类的基本步骤如下:
-
构建相似度矩阵:
- 计算数据点之间的相似度(常用高斯核函数)
- 构建邻接矩阵W
-
计算拉普拉斯矩阵:
- 度矩阵D: D i i = ∑ j W i j D_{ii} = \sum_{j} W_{ij} Dii=∑jWij
- 未归一化拉普拉斯矩阵: L = D − W L = D - W L=D−W
- 归一化拉普拉斯矩阵: L s y m = D − 1 / 2 L D − 1 / 2 L_{sym} = D^{-1/2}LD^{-1/2} Lsym=D−1/2LD−1/2
-
特征分解:
- 计算拉普拉斯矩阵的特征值和特征向量
- 选取最小的k个特征值对应的特征向量
-
降维聚类:
- 使用选取的特征向量构建新的特征矩阵
- 对新特征矩阵进行K-means聚类
环境准备
首先需要安装必要的Python包:
numpy>=1.21.0
scipy>=1.7.0
scikit-learn>=0.24.2
matplotlib>=3.4.2
pandas>=1.3.0
可以使用pip安装:
pip install -r requirements.txt
代码实现
我们将通过两个示例来展示谱聚类的效果:半月形数据集和同心圆数据集。
数据生成
def generate_data():
"""生成示例数据集"""
# 生成两个半月形数据集
n_samples = 200
X1, y1 = make_moons(n_samples=n_samples, noise=0.1)
# 生成同心圆数据集
X2, y2 = make_circles(n_samples=n_samples, noise=0.05, factor=0.5)
return X1, y1, X2, y2
可视化函数
def plot_clusters(X, labels, title, filename):
"""绘制聚类结果"""
plt.figure(figsize=(8, 6))
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.colorbar(label='聚类标签')
plt.title(title)
plt.xlabel('X轴')
plt.ylabel('Y轴')
plt.savefig(f'images/{filename}.png')
plt.close()
主函数实现
def main():
# 生成数据
X1, y1, X2, y2 = generate_data()
# 对半月形数据进行谱聚类
sc1 = SpectralClustering(n_clusters=2, affinity='nearest_neighbors',
assign_labels='kmeans', random_state=42)
labels1 = sc1.fit_predict(X1)
plot_clusters(X1, labels1, '半月形数据的谱聚类结果', 'moons_clustering')
# 对同心圆数据进行谱聚类
sc2 = SpectralClustering(n_clusters=2, affinity='nearest_neighbors',
assign_labels='kmeans', random_state=42)
labels2 = sc2.fit_predict(X2)
plot_clusters(X2, labels2, '同心圆数据的谱聚类结果', 'circles_clustering')
# 比较不同亲和度矩阵的效果
affinities = ['rbf', 'nearest_neighbors']
for affinity in affinities:
sc = SpectralClustering(n_clusters=2, affinity=affinity,
assign_labels='kmeans', random_state=42)
labels = sc.fit_predict(X1)
plot_clusters(X1, labels,
f'使用{affinity}亲和度矩阵的谱聚类结果',
f'affinity_{affinity}')
结果分析
让我们来看看谱聚类在不同数据集上的表现:
-
半月形数据集结果:
-
同心圆数据集结果:
-
不同亲和度矩阵的比较:
- RBF核函数结果:
- K近邻图结果:
从结果可以看出:
4. 谱聚类能够很好地识别非凸的数据集形状
5. 对于同心圆这样的复杂结构,谱聚类表现出色
6. 不同的亲和度矩阵可能会导致略微不同的聚类结果
应用场景
谱聚类在以下场景中特别有用:
-
图像分割:
- 可以用于图像的区域分割
- 能够识别图像中的自然边界
-
社交网络分析:
- 社区发现
- 用户群体划分
-
生物信息学:
- 蛋白质结构分析
- 基因表达数据聚类
-
推荐系统:
- 用户行为分析
- 商品类别划分
-
交通流量分析:
- 交通模式识别
- 路网社区划分
注意事项
在使用谱聚类时,需要注意以下几点:
-
计算复杂度:
- 对于大规模数据集,计算特征值和特征向量的开销很大
- 建议在数据量较大时使用近似方法
-
参数选择:
- 聚类数量k的选择很重要
- 相似度度量方式的选择会影响结果
- 需要根据实际问题调整参数
-
数据预处理:
- 建议对数据进行标准化
- 处理异常值和噪声数据
-
内存消耗:
- 需要存储n×n的相似度矩阵
- 对于大规模数据集可能需要使用稀疏矩阵表示
-
结果评估:
- 使用多个评估指标
- 考虑领域知识验证结果
同学们如果有疑问可以私信答疑,如果有讲的不好的地方或可以改善的地方可以一起交流,谢谢大家。