谱聚类与Python代码实现

一、 谱聚类

        谱聚类是一种基于图论矩阵特征分解(谱分析)的聚类方法。它的核心思想是将数据点视为图中的节点,通过计算数据之间的相似度矩阵,分析图的拉普拉斯矩阵(Laplacian Matrix)的谱(特征值和特征向量),从而在低维嵌入空间中进行聚类。谱聚类的特点适用于复杂形状的数据(如环形、流形结构),而传统方法(如K-means)仅适用于凸分布数据。基于全局结构,通过图拉普拉斯矩阵捕捉数据的整体连通性,而非局部距离。依赖相似度矩阵,计算开销较大,适用于中小规模数据集。优点与局限性:能发现非凸分布的簇。对噪声和离群点有一定鲁棒性。局限性:计算复杂度高((O(n^3)),适用于中小数据。相似度矩阵和参数的选择影响结果。应用场景:图像分割、社交网络分析、文本聚类等复杂结构数据。

二、算法解释

        主要想法是把所有的数据看作空间中的点,这些点之间的边连接起来。距离较远的两个点之间的边权重值较低,而距离较近的两个点之间的边权重值高,通过对所有数据点组成的图进行切图,让切图后不同的子图边权重。

        算法的具体技术思路:

        1、把数据组织成无向权重图并计算链接矩阵W、度矩阵D、拉普拉斯矩阵L。用数据样本点表示节点V(vertex),用样本之间有无连接表示有无边连接,用样本间的权重(用不同距离计算公式表示)的等于0与否表示有无连接,不为0的权重就是边的权重。

                                         

                                                                                    图 2-1 数据的图嵌入

import numpy as np
# np.set_printoptions(threshold=np.inf)
from sklearn.cluster import KMeans
import math
import matplotlib.pyplot as plt

def load_data(filename):
 ........

def getW(data, k):
    """
    获的邻接矩阵 W
    :param data: 样本集合
    :param k : KNN参数
    :return: W
    """
    n = len(data)
    dist_matrix = get_dist_matrix(data)
    W = np.zeros((n, n))
    for idx, item in enumerate(dist_matrix):
        idx_array = np.argsort(item)  # 每一行距离列表进行排序,得到对应的索引列表
        W[idx][idx_array[1:k+1]] = 1  # 权值直接取1 而不是其他的核函数;
    transpW =np.transpose(W)
    return (W+transpW)/2   # 这里的邻接矩阵采用的是K邻近法,并且是只要满足一个邻接即为相邻的K邻近法


def plotRes(data, clusterResult, clusterNum):
   ........


def cluster(data, cluster_num, k):
    
    # ratio 方法
    data = np.array(data)
    W = getW(data, k)
    D = getD(W)
    L = getL(D,W)
    
    # RatioCut方法
    # eigvec = getEigen(L, cluster_num)
    
    # 这里采用  n_cut 方法
    # n n_cut
    # print(np.diag(D))
    temp_D = np.diag(np.diag(D) ** (-1/2))
    New_L= np.dot(np.dot(temp_D,L),temp_D)
    eigvec = getEigen(New_L, cluster_num)
    #对 eigvec 标准化
    eigvec_normalized = eigvec / np.linalg.norm(eigvec, axis=0, keepdims=True)
    
    clf = KMeans(n_clusters=cluster_num)
    s = clf.fit(eigvec_normalized)  # 聚类
    label = s.labels_
    return  label


if __name__ == '__main__':
    cluster_num = 3
    knn_k = 6
    filename = 'output.txt'
    data = load_data(filename=filename)
    data = data[0:-1]  # 取全部数据
    label = cluster(data, cluster_num, knn_k)
    plotRes(data, label, cluster_num)


def getD(W):
   .......

def getEigen(L, cluster_num):
    """
    获得拉普拉斯矩阵的特征矩阵
    :param L:
    :param cluter_num: 聚类数目
    :return:
    """
    eigval, eigvec = np.linalg.eig(L)
    ix = np.argsort(eigval)[0:cluster_num]
    return eigvec[:, ix]

聚类前数据:

聚类后数据:

四、参考文献

1、数据挖掘——谱聚类(spectral clustering)基本原理及python实现_谱聚类算法原理与实现-CSDN博客

2、理解谱聚类 https://zhuanlan.zhihu.com/p/57369475

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值