当前位置: 首页 > news >正文

一些常见的聚类算法原理解析与实践

目录

  • 一、K-means
  • 二、学习向量量化(LVQ)
  • 三、DBSCAN聚类
  • 四、BERT-TOPIC
    • 1、bertopic安装:
    • 2、算法过程
    • 3、python中的实践
  • 五、基于共现网络的聚类算法
    • 1、Louvain社区检测
    • 2、谱聚类(Spectral Clustering)
  • 六、高斯混合聚类(Mixtrue-of-Gaussian)
  • 七、聚类效果度量指标
    • 1、轮廓系数(Silhouette Coefficient)
    • 2、模块度

sklearn. version = ‘1.7.0’

一、K-means

  • 质心:每个簇的"中心点"(簇内所有点的均值位置,非实际点);
  • 每个样本都由一个 n 维的向量表示;
  • 聚类过程:
    • 设置聚类簇数 k;
    • 随机选择 k 个初始样本,作为 k 个簇的初始质心,对应 k 个均值向量;
    • 计算所有训练样本与 k 个初始质心的距离,分配样本到最近的质心;
    • 得到 k 个簇,根据每个簇中所有的样本计算各个簇新的均值向量(簇中所有样本对应维度的向量求均值),得到 k 个新质心,重复上一步,直至达到最大轮数或阈值。
  • 对异常值非常敏感!异常值会显著拉偏质心位置,可以使用K-medoids算法(用实际点而非均值作为中心);
  • 球形数据适合基于距离的聚类算法(如k-means),非球形数据则适合基于密度或连通性的算法,该类数据可以考虑DBSCAN或谱聚类;
  • python中的实践:
from sklearn.cluster import KMeanskm = KMeans(n_clusters=num_clusters)
result_labels = km.fit_predict(embeds) # embeds:array-like of shape (n_samples, n_features)
print('k-means的聚类中心结果:',km.cluster_centers_)

二、学习向量量化(LVQ)

  • LVQ 主要用于模式分类,但也可用于聚类分析;
  • 是一种带监督的聚类;
  • 跟k-meas相似,原型向量类似于质心,聚类前也需要指定聚类簇数;
  • 算法过程:
    针对数据集:D={(x1,y1),(x2,y2),…,(xn,yn)},其中xi是数据点(特征向量),yi是类别标签(监督信息)。
    (1)初始化原型向量:
       选择 K 个原型向量 {p1,p2,…,pK},每个原型向量pj 有一个类别标签cj
       初始化方法:随机选择 K 个训练样本作为初始原型,或使用 K-means 聚类中心作为初始原型。
    (2)对于每个训练样本(xi,yi),计算 xi 与所有原型向量 pj 的距离,选择距离最近的原型 pj*
    (3)调整原型向量:
       如果 pj* 的标签 cj* 与 yi 相同(分类正确),则:
       pj∗ ← pj∗ + α(xi − pj∗)
       如果 pj* 的标签 cj* 与 yi 不同(分类错误),则:
       pj∗ ← pj∗ - α(xi − pj∗)
    (4)更新学习率(通常采用逐渐衰减的学习率):
       αt0 ⋅ (1−t/T)
       T 是最大迭代次数,t 是当前迭代。
    (5)循环以上(2)-(4)步骤,直到满足停止条件。
       停止条件可以是:①最大迭代次数、②原型向量的变化小于阈值、③分类准确率不再显著提升。

三、DBSCAN聚类

【HDBSCAN 聚类……】

  • 是一种密度聚类;
  • 需提前指定的参数:
    • eps(ε):邻域半径,用于定义“附近”的范围;
    • min_samples(MinPts):核心点所需的最小邻域点数。
  • 算法过程:
    针对数据集:D = {x₁, x₂, …, xₙ};
    (1)所有点标记为未访问(unvisited),初始化簇编号 C = 0;
    (2)针对每个点p∈D:
    • 如果 p 已被访问,跳过;
    • 否则,标记 p 为已访问。
      • 计算 p 的 eps(ε) 邻域内的点数 N_eps(p) 。
      • 如果 N_eps(p) ≥ min_samples,则 p 是核心点:
        • 创建一个新簇 C = C + 1。
        • 将 p 加入簇 C。
        • 遍历 N_eps(p) 中的所有点 q :
          • 如果 q 是未访问且也是核心点,则递归扩展其邻域(深度优先搜索)
          • 如果 q 不属于任何簇,将其加入簇 C。
      • 否则 p 是噪声或边界点:
        暂时标记为噪声(后续可能被重新分类为边界点)。
  • 适合非球形数据;
  • 在python中的实践:
from sklearn.cluster import DBSCANdbscan = DBSCAN(eps=2, min_samples=3)
labels = dbscan.fit_predict(X)

四、BERT-TOPIC

1、bertopic安装:

  • 建议安装时创建一个全新的conda环境,直接先安装bertopic:pip install bertopic -i https://pypi.tuna.tsinghua.edu.c
  • 安装时会安装大量的相关模块,比如hdbscan、scikit-learn、torch、transformers、sentence-transformers等(如果后续要将结果写入excel需要单独安装 openpyxl);
  • 安装完成后,各个相关模块版本如下图:
    在这里插入图片描述

2、算法过程

  • 文档嵌入:使用embedding模型;
  • 向量降维:使用UMAP算法;
  • 聚类:使用HDBSCAN算法;
  • 主题表示:使用c-TF-IDF。

3、python中的实践

1、整个模型构建的过程如下:

  • 相同的输入和参数,每次聚类结果都不同。
model_dir= 'E:/CQF/work_yanxue/AI_yanxue/LLM/models/embedding_model/m3e-base'
embedding_model = SentenceTransformer(model_dir)umap_model = UMAP(n_neighbors=15, n_components=5,min_dist=0.0,metric='cosine')hdbscan_model = HDBSCAN(min_cluster_size=10, metric='euclidean', prediction_data=True)lis_stopwords = ['我','的','你好','啊','吗']
vectorizer_model = CountVectorizer(stop_words=lis_stopwords)ctfidf_model = ClassTfidfTransformer()topic_model = BERTopic(embedding_model=embedding_model,    # Step 1 - Extract embeddingsumap_model=umap_model,              # Step 2 - Reduce dimensionalityhdbscan_model=hdbscan_model,        # Step 3 - Cluster reduced embeddingsvectorizer_model=vectorizer_model,  # Step 4 - Tokenize topicsctfidf_model=ctfidf_model,          # Step 5 - Extract topic wordsnr_topics='none',top_n_words = 10 # The number of words per topic to extract.比如1簇中可能有2k个词,只抽取10个进行显示,此时无法知道2k个词具体是什么
)
filtered_text = data_prod_kws('C:\\Users\\cqf\\Downloads\\data (1).txt')
print('词数量:', len(filtered_text))
topics, probabilities = topic_model.fit_transform(filtered_text)
topic_info = topic_model.get_topic_info()
topic_info.to_excel('data/聚类结果.xlsx',index=False)
print(topic_info)topics = topic_model.get_topics()
print(topics)topic_freqs = topic_model.get_topic_freq()
topic_freqs.to_excel('data/聚类主题频次.xlsx',index=False)
print('主题频次:', topic_freqs)

2、输入的数据为包含所有关键词的 list,比如 ['聚类', '相似性度量', '大数据聚类', '小数据聚类', '聚类评价', '区块链', '隐私保护', '对等网络', '聚类分析', '比特币']

  • 数据处理代码:
def data_prod_kws(file):text = []with open(file, 'r', encoding='utf-8') as f:dics = json.load(f)for dic in dics:text.extend([w for w in dic['中文关键词'].split(',')])return list(set(text))
  • 聚类结果:
    • get_topic_info()的结果:
      count:该主题下存在的所有词数,相加为参与聚类的所有词;
      representation:top_n_words 参数指定的10个词;
      representative docs:默认给3个词.
      在这里插入图片描述
    • get_topic_freq()的结果:
      在这里插入图片描述
    • get_topics()的结果:
      每个聚类下面 top_n_words 个representation词以及他们对应的 c-TF-IDF score。
{-1: [('mann', np.float64(0.01204125761183207)), ('citespace', np.float64(0.010686919578811734)), ('一带一路', np.float64(0.009196415268009182)), ('支持向量机', np.float64(0.005623271905033993)), ('偏最小二乘', np.float64(0.005623271905033993)), 
('kendall突变检验', np.float64(0.005623271905033993)), ('kendall趋势检验', np.float64(0.005623271905033993)), ('气相色谱', np.float64(0.005623271905033993)), ('电动汽车', np.float64(0.005623271905033993)), ('dbscan', np.float64(0.005623271905033993))], 0: [('means', np.float64(0.008056103664799924)), ('means算法', np.float64(0.008056103664799924)), ('means聚类算法', np.float64(0.006719382727287874)), ('means聚类', np.float64(0.005963621503722352)), ('均值聚类', np.float64(0.0051318754150817825)), ('dea', np.float64(0.004202358326079973)), ('模糊c', np.float64(0.004202358326079973)), ('est', np.float64(0.0031379543007534444)), ('means聚类分析', np.float64(0.0031379543007534444)), ('gmm', np.float64(0.0031379543007534444))], 1: [('模糊聚类算法', np.float64(0.04361382912059102)), ('层次聚类分析', np.float64(0.04361382912059102)), ('dpca', np.float64(0.025855984653890975)), ('bagging集成聚类', np.float64(0.025855984653890975)), ('ap聚类', np.float64(0.025855984653890975)), 
('ap聚类算法', np.float64(0.025855984653890975)), ('初始聚类中心', np.float64(0.025855984653890975)), ('hca', np.float64(0.025855984653890975)), ('index聚类有效性检验指标', np.float64(0.025855984653890975)), ('ipc聚类', np.float64(0.025855984653890975))],

3、输入的数据为 list,其中元素为每篇文献用空格分隔的关键词,比如 ["聚类 相似性度量 大数据聚类 小数据聚类 聚类评价", "区块链 隐私保护 对等网络 聚类分析 比特币"]

  • 数据处理代码:
def data_prod_docs(file):text = []with open(file, 'r', encoding='utf-8') as f:dics = json.load(f)for dic in dics:text.append(dic['中文关键词'].replace(',', ' '))# text.append(dic['中文关键词'])return text
  • 聚类结果:
    • 跟2中的输入结果相比,效果不是很好,聚类数量过少,且有时才2个簇;(如果每个doc中的词用逗号分隔,效果更差……)
    • get_topic_info()的结果:
      count:该主题下所有 doc 数,每个 doc 是 list 中的一个字符串,相加为参与聚类的所有 doc 数;
      representation:top_n_words 参数指定的10个词;
      representative docs:默认给3个 doc(非3个词).
      在这里插入图片描述

五、基于共现网络的聚类算法

1、Louvain社区检测

  • 主要用于复杂网络分析领域;
  • 一种基于模块度(Modularity)优化的社区发现(Community Detection)算法;
  • 聚类依据是模块度增益(ΔQ),计算公式:
    例如将节点 i 从社区 D 移动到社区 C 带来的模块度变化,其中:
    Σin:社区 C 内部边的权重和
    Σtot:与社区 C 相连的所有边的权重和
    ki,in:节点 i 与社区 C 内节点的边权重和
    ki:节点 i 的度

ΔQ = [(Σin + ki,in)/2m - (Σtot + ki)2/(2m)2] - [Σin/2m - (Σtot)2/(2m)2 - (ki)2/(2m)2]

  • 算法过程:
    例如有网络:[(‘A’,‘B’), (‘A’,‘C’), (‘B’,‘C’), (‘C’,‘D’), (‘D’,‘E’), (‘D’,‘F’), (‘E’,‘F’)]
    • 第一阶段:模块度优化
      初始化:将每个节点分配到独立的社区;
         得到社区:{‘A’:0, ‘B’:1, ‘C’:2, ‘D’:3, ‘E’:4, ‘F’:5}
      遍历节点
      (1)对于每个节点 i,计算将其移动到邻居社区的ΔQ
      (2)将节点 i 移动到使ΔQ最大的社区(若ΔQ>0)
      (3)重复:直到没有节点移动能提高模块度
         得到社区:{‘A’:1, ‘B’:1, ‘C’:1, ‘D’:4, ‘E’:5, ‘F’:4}
    • 第二阶段:社区聚合
      (1)将第一阶段得到的社区视为新网络的"超级节点":
         社区1:{A,B,C} → 新节点X
         社区2:{D,E,F} → 新节点Y
      (2)超级节点之间的边权重为原社区间所有边权重和
         X-Y权重:原C-D边权重=1
      (3)社区内部的边形成新节点的自环,可以得到每个社区的权重
         X自环:社区1内部边AB,AC,BC → 权重3
         Y自环:社区4内部边DE,DF,EF → 权重3
  • 适合有社区关系(比如关键词的共现关系)的数据;
  • python中有专业的第三方模块进行louvain聚类计算:
import community as community_louvain
import networkx as nxG_datas = [('基金', 1, {'weight': 1}),('人工智能', 'AI研学', {'weight': 1}),(2, 0, {'weight': 1}),(3, 4, {'weight': 1}),(4, 5, {'weight': 1}),(5, 3, {'weight': 1}),(0, 3, {'weight': 0.1})  # 弱连接
]
G = nx.Graph()
G.add_edges_from(G_datas)# Louvain社区检测
partition = community_louvain.best_partition(G, weight='weight') # 返回结果是dict类型,如{'基金': 社区编号0, '人工智能': 社区编号2, ……}

2、谱聚类(Spectral Clustering)

  • 适合处理非凸分布(如环形、流形结构)的数据,是K-means等传统聚类方法的有力补充;
  • 计算复杂度很高;本质是构建相似性矩阵W、度矩阵D后,计算拉普拉斯矩阵L,然后分解L得到最终的数据集特征向量U,使用k-means等其他聚类算法对特征向量聚类;
  • 需提前指定聚类簇数;
  • 算法过程:
    针对数据集X={x1,x2,…,xn}:
    • 构建相似性矩阵 W(Affinity Matrix):
      计算所有数据点两两之间的相似度(算法如高斯核函数RBF Kernel),生成矩阵 W;
    • 计算度矩阵 D(Degree Matrix):
      度矩阵 D 是一个对角矩阵,对角线元素为每个节点的度(即相似性矩阵的行和):Diinj=1Wij
    • 计算拉普拉斯矩阵 L(Laplacian Matrix):
      非归一化拉普拉斯矩阵:L=D−W
      对称归一化拉普拉斯矩阵:L= I−D−1/2WD−1/2
      游走归一化拉普拉斯矩阵:L= I−D−1 W
    • 计算拉普拉斯矩阵的特征向量 U
      对 L 进行特征分解,取前 k 个最小的非零特征值对应的特征向量,组成矩阵 U∈Rn×k
    • 使用k-means等算法对特征向量进行聚类
      将 U 的行向量作为数据点在低维空间的表示,用K-means等算法聚类。
  • 在python中的实践:
from sklearn.cluster import SpectralClusteringmodel = SpectralClustering(n_clusters=2,affinity='nearest_neighbors',  # 默认值 'rbf'assign_labels='kmeans'         # 对特征向量聚类的方法,默认值kmeans
)
labels = model.fit_predict(X)

还有一种是层次聚类(Hierarchical Clustering),详细的后续有时间补充。

六、高斯混合聚类(Mixtrue-of-Gaussian)

  • 是一种软聚类,算法仅提供概率归属,最终样本归属于概率最大的簇;

  • 需要提前定义k(高斯分布个数,也是最终的簇数);

  • 需要初始化高斯分布的各个参数:Πk(混合系数),uk(均值),Σk(协方差矩阵);

  • 算法过程:
    假设数据由 K 个高斯分布混合而成,其概率密度函数为:
    p(x) = ΣKk=1Πk * N(x|uk, Σk)
    其中,
    Πk:第 k 个高斯分布的混合系数(权重),满足ΣKk=1Πk = 1
    N(x|uk, Σk):第 k 个高斯分布的概率密度函数,均值为 uk协方差矩阵是 Σk

    • (1)随机或通过k-means初始化高斯分布的参数: uk, Σk,Πk(一般为 1/K) ;
    • (2)E步(Exceptation):
      计算每个样本xi属于第 k 个高斯分布的后验概率 γik(责任值,表示 xi 属于簇 k 的概率):
      在这里插入图片描述
    • (3)M步(Maximization):
      更新均值uk
      在这里插入图片描述
      更新协方差Σk
      在这里插入图片描述
      更新混合系数Πk:其中,N为样本总数
    • (4)收敛判断
      计算对数似然函数,判断是否收敛,若似然值拜年话小于阈值或达到最大迭代次数,则停止,否则返回E步。
      在这里插入图片描述
  • python中的实践:

from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(n_components = k, covariance_type = 'full', # 协方差矩阵的定义方式,full表示每个高斯分布都有自己的协方差矩阵init_params = 'kmeans' # 默认使用k-means方式初始化权重、均值、精度)

除上述之外,还有:

  • AGNES聚类:每个样本初始为一个簇,迭代合并距离最近的簇,直到所有样本聚为一类。
  • Meanshift聚类:是一种密度聚类,是指是沿着密度上升的方向寻找同属一个簇的数据点。
  • 在python中调用:
from sklearn.cluster import AgglomerativeClustering, MeanShift

七、聚类效果度量指标

1、轮廓系数(Silhouette Coefficient)

  • 用于衡量每个样本与其所在簇的紧密度(Cohesion)和与最近簇的分离度(Separation)。它综合了簇内紧密度和簇间分离度,结果范围在[−1,1] 之间:
    • 值接近 1:表示样本很好地聚集在簇内,且与其他簇分离得很好,聚类效果好。
    • 值接近 0:表示样本位于两个簇的边界,聚类效果一般。
    • 值接近 -1:表示样本可能被错误地分配到簇中,聚类效果差。

2、模块度

  • 计算公式,其中:
    • Aij:节点i和节点j之间的边权重
    • ki :节点i的度(所有边的权重和)
    • m:网络中所有边的权重和
    • ci:节点i所属的社区
    • δ:克罗内克函数(同一社区为1,否则为0)

Q = (1/2m) * Σij [Aij - (ki * kj)/2m] * δ(ci, cj)

基于Kleinberg算法的关键词突现实现:
Detecting ‘bursts’ in time series data with Kleinberg’s burst detection algorithm
GitHub:BURST DETECTION

在这里插入图片描述

http://www.dtcms.com/a/337828.html

相关文章:

  • 【OLAP】trino安装和基本使用
  • BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain
  • 机器学习之数据预处理(一)
  • 深度学习-计算机视觉-微调 Fine-tune
  • 【MongoDB】多种聚合操作详解,案例分析
  • Java文件操作/IO
  • RabbitMQ高级特性——TTL、死信队列、延迟队列、事务、消息分发
  • 【展厅多媒体】互动地砖屏怎么提升展厅互动感的?
  • python基于机器学习进行数据处理与预测(火灾的三因素回归问题)
  • 探索机器学习:从核心概念到实战应用
  • 精通sqlmap tamper:WAF绕过实战技巧剖析
  • 磁流变液迟滞性能的机器学习软件设计
  • MySQL实战优化高手教程 – 从架构原理到生产调优
  • 突破成长瓶颈:产品运营能力体系化提升技巧
  • 大数据毕业设计选题推荐:基于Hadoop+Spark的城镇居民食品消费分析系统源码
  • 28、企业安防管理(Security)体系构建:从生产安全到日常安保的全方位防护
  • 【秋招笔试】2025.08.16科大讯飞秋招机考真题
  • 从虚拟到现实:数字孪生赋能智能制造
  • 跨设备文件共享优化:cpolar 提升 PicoShare 访问速度方案
  • Nextcloud 私有云部署:cpolar 内网穿透服务实现安全远程文件访问
  • 知识点 | 麒麟OS环境中curl -4回显真实IP的原因
  • Nextcloud容器化部署革新:Docker+Cpolar构建高效私有云远程访问新架构
  • Harmonyos之字体设置功能
  • 什么是Hystrix?实现原理是什么?
  • Hadoop - 1:Hadoop 技术解析;Hadoop是什么;Hadoop优势;Hadoop组成;HDFS、YARN、MapReduce 三者关系
  • docker——docker执行roslaunch显示错误
  • listagg 多了空格 Oracle数据库
  • 【嵌入式人工智能产品开发实战】(二十四)—— 政安晨:解释一下小智AI项目中析构函数的应用
  • McCabe 环形复杂度
  • Owen大规模文本嵌入生成