谱聚类笔记(Iris)

本文详细介绍了如何使用谱聚类算法对Iris数据集进行分类,包括构建关系矩阵、拉普拉斯矩阵操作、特征值分解及聚类过程。通过高斯核函数和K-means方法,展示了从数据到聚类结果的完整流程,并分享了学习过程中遇到的问题和心得。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

谱聚类(Iris)


写在前面
谱聚类原理推导实在是看了好久,也半懂不懂,目前的成果还要感谢多篇博客(太多了写懵了没记住都是哪个不好意思)
可能我的文里面还有错误,还有没解决的问题。
欢迎指出错误,有好理解的解释也欢迎评论教我一下,或者易懂的教程、文章、视频在评论区推荐一下~
难兄难弟互助,共同进步~

实验过程

谱聚类函数

# 谱聚类函数
import numpy as np
from kernels import *
# 这里用的是高斯核,可以换别的和,直接复用之前写kernel k-means的核函数文件

# 求关系矩阵W
def W_Matrix(m,dataset, createMatrix,kernel):
    '''
    对数据集dataset求关系矩阵,用的是kernel核函数
    写在createMatrix里面
    '''
    for i in range(m):
        x = dataset[i]
        for j in range(m):
            y = dataset[j]
            createMatrix[i,j] = kernel(x,y) #计算的高斯核函数放入创建的空矩阵中
    #createMatrix = createMatrix - np.identity(m) # np.identity()创建单位对角矩阵  //  生成对角线为0的矩阵
    return createMatrix


'''
input:
dataset: iris.data 只包含样本的特征值,本实验中大小为150*4
number_cluster: 要分成的类别数,这里是3
num_lowerdim: 谱聚类本意上是降维处理,取L矩阵前k个特征值,这个参数就是这个k。(可惜iris数据集维度不大,不小心就升维了)
kernel: 在构造关系矩阵时,采用全连接方法,核函数可以改变用别的。
cluster_method: 最后对于特征矩阵行元素的聚类方法,这里用的时k-means,可以用别的。

'''
# 谱聚类主函数
def Spectral_Clustering(dataset,number_cluster,num_lowerdim,kernel,cluster_method):
    # 创建空矩阵,用来装邻接矩阵W
    createMatrix = np.zeros((dataset.shape[0],dataset.shape[0]))
    # 通过高斯核求全连接的关系矩阵W
    W=W_Matrix(dataset.shape[0],dataset,createMatrix,kernel)
    # 对W矩阵每行相加,得到度矩阵D
    sumD = []
    for i in range(W.shape[0]):
        sum = 0
        for j in range(W.shape[1]):
            sum +=W[i,j]
        sumD.append(sum)
    D = np.diag(sumD)
    # L 拉普拉斯矩阵,等于度矩阵减邻接矩阵
    L = D - W
    # print(L)
    # 求度矩阵的-1/2次,用来给L标准化
    Dn = np.mat(np.diag(np.power(sumD,-0.5)))
    #W = np.mat(W)
    # 对L标准化
    L = Dn*L*Dn
    # 求L的特征值特征向量
    eigvals, eigvecs = np.linalg.eig(L)
    # 得到L的最小k个特征值对应的特征向量
    k = num_lowerdim
    indices = eigvals.argsort()[:k]
    k_min_eigvecs = eigvecs[:,indices]
    # 将对应的特征向量组成的矩阵按照行,标准化,得到n*k维的特征矩阵F
    X = np.linalg.norm(k_min_eigvecs, axis=1)
    Y = np.zeros((dataset.shape[0],k))
    for i in range(dataset.shape[0]):
        for j in range(k):
            Y[i,j] = k_min_eigvecs[i,j]/X[i]
    # print("特征向量单位化:", Y)
    # 标准化的F矩阵,每一行作为一个k维样本,用k-means进行聚类,聚类维数为number_cluster
    if cluster_method=='KMeans' :
        from sklearn.cluster import KMeans
        method  = KMeans
    
    NJW = method(n_clusters=number_cluster).fit_predict(k_min_eigvecs)
    return NJW
谱聚类流程:
算法步骤

​ 输入:样本集D=(x1,x2,…,xn)(x1,x2,…,xn),相似矩阵的生成方式, 降维后的维度k1k1, 聚类方法,聚类后的维度k2k2

输出: 簇划分C(c1,c2,…ck2)C(c1,c2,…ck2).

1) 根据输入的相似矩阵的生成方式构建样本的相似矩阵S

2)根据相似矩阵S构建邻接矩阵W,构建度矩阵D

3)计算出拉普拉斯矩阵L

4)构建标准化后的拉普拉斯矩阵L‘ = D−1/2LD−1/2D−1/2LD−1/2

5)计算D−1/2LD−1/2D−1/2LD−1/2最小的k1k1个特征值所各自对应的特征向量ff

6) 将各自对应的特征向量ff组成的矩阵按行标准化,最终组成n×k1n×k1维的特征矩阵F

7)对F中的每一行作为一个k1k1维的样本,共n个样本,用输入的聚类方法进行聚类,聚类维数为k2k2。

8)得到簇划分C(c1,c2,…ck2)C(c1,c2,…ck2).

转载自谱聚类(spectral clustering)原理总结 - 刘建平Pinard - 博客园 (cnblogs.com)

变量传递

原理很复杂,但是代码很简单:
D ( 样 本 ) → W ( 邻 接 矩 阵 ) → D ( 度 矩 阵 ) → L → L ′ → f i → F → C D(样本)\rightarrow W(邻接矩阵)\rightarrow D(度矩阵)\rightarrow L\rightarrow L'\rightarrow f_i\rightarrow F\rightarrow C D()W()D()LLfiFC

主要函数参数
input:
1. dataset: iris.data 只包含样本的特征值,本实验中大小为150*4

2. num_lowerdim: 谱聚类本意上是降维处理,取L矩阵前k个特征值,这个参数就是这个k。(可惜iris数据集维度不大,不小心就升维了)

3. number_cluster: 要分成的类别数,这里是3

4. kernel: 在构造关系矩阵时,采用全连接方法,核函数可以改变用别的。

5. cluster_method: 最后对于特征矩阵行元素的聚类方法,这里用的时k-means,可以用别的。
output:

​ 一个向量,里面顺次是每个样本聚类的标签,同标签数值相同,但是不一定是几

核函数

用的是kernel k-means时候写的核函数文件,在这里调用的是高斯核,封装成参数写在主函数里面

Main

from sklearn.datasets import load_iris
import numpy as np
from SpectralClustering import *
import matplotlib.pyplot as plt
# 加载数据集,用的是sklearn的数据集
iris = load_iris()
NJW = Spectral_Clustering(iris.data,number_cluster=3,num_lowerdim=3,kernel = squared_exponential_kernel,cluster_method='KMeans')

#将结果与数据拼接在一起
NJW = NJW.squeeze()
NJW = NJW[:,None]
df1 = np.concatenate([iris.data,NJW], axis=1)

#可视化
def draw(data,dim0,dim1):
    colorSet = ["black", "blue", "green", "yellow", "red", "purple", "orange", "brown"]
    for i in range(iris.data.shape[0]):
        x = data[i][dim0]
        y = data[i][dim1]
        color = colorSet[int(data[i][-1]) % len(colorSet)]
        plt.scatter(x,y, marker="o", c=color, s=20)
    plt.xlabel("x")
    plt.ylabel("y")
    plt.show()
draw (df1,0,1)
draw (df1,1,2)
draw (df1,3,0)

没啥好说的,都写在注释里面了。

引入数据集

调用谱聚类主要函数

结果可视化

实验结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

谱聚类笔记

网上有很多文章写的有问题,也有几篇讲的非常好的。书上写的有点复杂,不大好按照思路一步一步引导。

下面是我学的过程中整理的思路,还有问题没解决,之后再进行补充
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值