实验7: 谱聚类

一、实验目的

了解谱聚类的构建过程和代码实现,应用谱聚类解决简单的实际问题。

二、实验准备

安装python和pycharm,了解python基础编程和pycharm使用。

三、实验内容

基于程序中生成的数据,补充完整下面谱聚类算法相关程序,粘贴运行成功的结果截图,并给每行程序添加注释。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn import datasets     #导入相应的包

def calculate_w_ij(a,b,sigma=1):#计算距离
    w_ab = np.exp(-np.sum((a-b)**2)/(2*sigma**2)) #高斯相似度,距离远,相似度小
    return w_ab

def Construct_Matrix_W(data,k=5):
    # 计算临接矩阵
    rows = data.shape[0]#取出数据行数
    W = np.zeros((rows,rows))#对矩阵进行初始化:初始化W为rows*rows的方阵
    for i in range(rows):#遍历行
        for j in range(rows):#遍历列
            if(i!=j):#计算不重复点的距离
                W[i][j] = calculate_w_ij(data[i,:],data[j,:])#调用函数计算距离
        t = np.argsort(W[i,:])#对W中进行行排序,并提取对应索引
        for x in range(rows-k):#对W进行处理
            W[i][   t[x]      ] = 0
    W = (W+W.T)/2   #主要是想处理可能存在的复数的虚部,都变为实数
    return W

def Calculate_Matrix_L_sym(W): # 计算标准化的拉普拉斯矩阵
    degreeMatrix = np.sum(     W     ,   axis=1        )#按照行对W矩阵进行求和
    L = np.diag(degreeMatrix) - W#计算对应的对角矩阵减去w
    #拉普拉斯矩阵标准化,就是选择Ncut切图
    sqrtDegreeMatrix = np.diag(1.0 / (degreeMatrix ** (0.5)))  # D^(-1/2)
    L_sym = np.dot(np.dot(sqrtDegreeMatrix, L), sqrtDegreeMatrix)  # D^(-1/2) L D^(-1/2)
    return L_sym

def normalization(matrix): # 归一化
    sum = np.sqrt(np.sum(matrix**2,axis=1,keepdims=True))#求数组的正平方根
    nor_matrix = matrix/sum#求平均
    return nor_matrix

def showCluster(res, k):   #绘制聚类结果函数
    m,n = res[:,0:2].shape#m,n是(800,2)
    mark =['or','ob', 'og', 'ok', 'oy']#设置mark
    if k > len(mark):#如果k值大于mark的最大长度,即不能找到对应值
        print("k值太大了")#进行提示
        return 1#返回标识符
    for i in range(m):
        markIndex = int(res[i,2])
        plt.plot(res[i, 0], res[i, 1], mark[    markIndex          ])
    plt.show()

if __name__=="__main__":

    data,y= datasets.make_moons(n_samples=800, shuffle=True, noise=0.05, random_state=None)#导入数据
    '''
    制作样本数据,产生的结果为一个简单的样本数据集,用于可视化聚类算法和分类算法。
    参数:n_samples:整数型, 可选,默认为100。总的产生的样本点的数量。
    shuffle:布尔型,可选填(默认为True)。是否对样本进行重新洗牌。
    noise:浮点型orNone型(默认为None)。加到数据里面的高斯噪声的标准差。
    返回值:data:产生的形状为[n_samples, 2]的一个数组。产生的样本。
    y:产生的形状为[n_samples]维的一个数组。每个样本的分类结果(0或1)
    '''
    W = Construct_Matrix_W(data)#计算data的邻接矩阵
    L_sym = Calculate_Matrix_L_sym(W)#依据W计算标准化拉普拉斯矩阵

    lam, H = np.linalg.eig(L_sym)#特征值分解

    t = np.argsort(lam)#将lam中的元素进行排序,返回排序后的下标
    H = np.c_[H[:,t[0]],H[:,t[1]]]#0和1类的两个矩阵按行连接,就是把两矩阵左右相加,要求行数相等。
    H = normalization(H)#归一化处理

    model = KMeans(n_clusters=2)#新建2簇的Kmeans模型
    model.fit(      H       )#训练
    labels =model.labels_#得到聚类后的每组数据对应的标签类型

    res = np.c_[data,labels]#按照行数连接data和labels
    showCluster(res,k=2)#绘制聚类结果

 

运行结果:

python中怎么使用谱聚类 谱聚类python代码_谱聚类