聚类算法(六)——谱聚类 (含代码)

聚类算法相关:

聚类算法(一)——DBSCAN

聚类算法(二)—— 优缺点对比

聚类算法(三)—— 评测方法1

聚类算法(三)—— 评测方法2

聚类算法(三)—— 评测方法3(代码)

聚类算法(四)—— 基于词语相似度的聚类算法(含代码)

聚类算法(五)——层次聚类 linkage (含代码)

聚类算法(六)——谱聚类 (含代码)

 

原理

 

    谱聚类是一种基于图论的聚类方法,通过对样本数据的拉普拉斯矩阵的特征向量进行聚类,从而达到对样本数据聚类的目的。谱聚类可以理解为将高维空间的数据映射到低维,然后在低维空间用其它聚类算法(如KMeans)进行聚类。

 

代码

'''
谱聚类方法
参考github代码:https://github.com/leekeiling/Cluster/blob/master/spectral.py
原理介绍:https://blog.csdn.net/qq_24519677/article/details/82291867
'''


from sklearn.cluster import KMeans
import numpy as np
import math as m
import matplotlib.pyplot as plt
import pandas as pd
from collections import OrderedDict


from cluster_v2 import Embedding, load_keywords

# import evaluate as eval

# flame.txt
# Jain_cluster=2.txt
# Aggregation_cluster=7.txt
# Spiral_cluster=3.txt
# Pathbased_cluster=3.txt

data_path = "flame.txt"


def load_data():
    """
    导入数据
    :return:
    """
    points = np.loadtxt(data_path, delimiter='\t')
    return points


def get_dis_matrix(data):
    """
    获得邻接矩阵
    :param data: 样本集合
    :return: 邻接矩阵
    """
    nPoint = len(data)
    dis_matrix = np.zeros((nPoint, nPoint))
    for i in range(nPoint):
        for j in range(i + 1, nPoint):
            dis_matrix[i][j] = dis_matrix[j][i] = m.sqrt(np.power(data[i] - data[j], 2).sum())
    return dis_matrix


def getW(data, k):
    """
    利用KNN获得相似矩阵
    :param data: 样本集合
    :param k: KNN参数
    :return:
    """
    dis_matrix = get_dis_matrix(data)
    W = np.zeros((len(data), len(data)))
    for idx, each in enumerate(dis_matrix):
        index_array = np.argsort(each)
        W[idx][index_array[1:k+1]] = 1
    tmp_W = np.transpose(W)
    W = (tmp_W+W)/2
    return W


def getD(W):
    """
    获得度矩阵
    :param W:  相似度矩阵
    :return:   度矩阵
    """
    D = np.diag(sum(W))
    return D


def getL(D, W):
    """
    获得拉普拉斯举着
    :param W: 相似度矩阵
    :param D: 度矩阵
    :return: 拉普拉斯矩阵
    """
    return D - W


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


def plotRes(data, clusterResult, clusterNum):
    """
    结果可视化
    :param data:  样本集
    :param clusterResult: 聚类结果
    :param clusterNum:  聚类个数
    :return:
    """
    nPoints = len(data)
    scatterColors = ['black', 'blue', 'green', 'yellow', 'red', 'purple', 'orange']
    for i in range(clusterNum):
        color = scatterColors[i % len(scatterColors)]
        x1 = [];  y1 = []
        for j in range(nPoints):
            if clusterResult[j] == i:
                x1.append(data[j, 0])
                y1.append(data[j, 1])
        plt.scatter(x1, y1, c=color, alpha=1, marker='+')
    plt.show()


if __name__ == '__main__':
    cluster_num = 10
    KNN_k = 5
    
    keywords = [] # 需要聚类的词语  句子的话可以采用fasttext向量或者TfidfVectorizer, 参见开头其它聚类文章
    embedding_file2 = ''
    embedding_model2 = Embedding(embedding_file2, 200, type='w2v')
    X = [embedding_model2.get_word_embedding(keyword) for keyword in keywords]
    data = X
    # data = load_data()
    data = np.asarray(data)
    W = getW(data, KNN_k)
    D = getD(W)
    L = getL(D, W)
    eigvec = getEigen(L)
    clf = KMeans(n_clusters=cluster_num)
    s = clf.fit(eigvec)
    labels = s.labels_
    # plotRes(data, np.asarray(C), 7)  # plot 展示
    print(labels)
    data = []
    dic = OrderedDict()
    for keyword, label in zip(keywords, labels):
        dic.setdefault(label, [])
        dic[label].append(keyword)
    for item in dic:
        data.extend([[x, item] for x in dic[item]])
        data.append([])
    df = pd.DataFrame(data=data, columns=['keyword', 'class_index'])
    df.to_excel(result_file, index=False)

参考链接:

https://blog.csdn.net/qq_24519677/article/details/82291867

https://github.com/leekeiling/Cluster/blob/master/spectral.py

  • 6
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微知girl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值