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

聚类算法(K-means、DBSCAN)

聚类算法

K-means 算法

算法原理

K-means 是一种基于类内距离最小化的划分式聚类算法,其核心思想是通过迭代优化将数据划分为 K 个簇。目标函数为最小化平方误差(SSE):
S S E = ∑ i = 1 K ∑ x ∈ C i ∣ ∣ x − μ i ∣ ∣ 2 SSE = \sum_{i=1}^{K} \sum_{x \in C_i} ||x - \mu_i||^2 SSE=i=1KxCi∣∣xμi2
其中 μ i \mu_i μi 是第 i i i 个簇的质心。

算法步骤

  1. 初始化

    • 随机选择 K 个初始质心(或使用 k-means++ 优化初始化)
  2. 迭代优化

    • 分配阶段:将每个样本分配到距离最近的质心所属簇
      C i = { x : ∣ ∣ x − μ i ∣ ∣ 2 ≤ ∣ ∣ x − μ j ∣ ∣ 2 , ∀ j } C_i = \{ x : ||x - \mu_i||^2 \leq ||x - \mu_j||^2, \forall j \} Ci={x:∣∣xμi2∣∣xμj2,j}
    • 更新阶段:重新计算每个簇的质心
      μ i = 1 ∣ C i ∣ ∑ x ∈ C i x \mu_i = \frac{1}{|C_i|} \sum_{x \in C_i} x μi=Ci1xCix
  3. 终止条件

    • 质心位置不再变化(收敛)
    • 达到最大迭代次数
    • SSE 变化量小于阈值

特点

  • 时间复杂度: O ( n ∗ K ∗ I ∗ d ) O(n*K*I*d) O(nKId),n 为样本数,I 为迭代次数
  • 需预先指定 K 值
  • 对初始质心敏感,可能收敛到局部最优

DBSCAN 算法

算法原理

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度可达性的聚类算法,由Ester等人在1996年提出,其核心思想是通过数据点的局部密度分布识别聚类结构,并有效处理噪声。算法中的关键概念包括:

  1. 核心点:以某点为中心、半径ε邻域内的点数≥MinPts的点,是簇形成的基础。
  2. 边界点:位于核心点的ε邻域内,但自身邻域内点数<MinPts的点。
  3. 噪声点:既非核心点也非边界点的孤立点。
  4. 密度可达性:若点A通过一系列核心点间接可达点B,则称A与B密度可达。
  5. 密度连通性:若存在核心点O,使得点A和B均密度可达于O,则A与B密度连通。

算法步骤

  1. 初始化参数:设置邻域半径ε和最小密度阈值MinPts。
  2. 遍历未访问点:随机选择一个未访问点,计算其ε邻域内的点数:
    • 若点数<MinPts:标记为噪声点(可能后续被重新归类为边界点)。
    • 若点数≥MinPts:标记为核心点,创建新簇,递归合并所有密度可达点。
  3. 扩展聚类:通过核心点的邻域不断吸收边界点和可达核心点,直至无法扩展。
  4. 重复处理:遍历所有未访问点,直至数据集处理完毕。

特性

  • 时间复杂度:O(n log n)(使用空间索引时)
  • 可发现任意形状的簇
  • 自动识别噪声点
  • 对参数敏感

聚类评估指标

1. 轮廓系数 (Silhouette Coefficient)

综合衡量样本的簇内紧密度簇间分离度
s ( i ) = b ( i ) − a ( i ) max ⁡ { a ( i ) , b ( i ) } s(i) = \frac{b(i) - a(i)}{\max\{a(i), b(i)\}} s(i)=max{a(i),b(i)}b(i)a(i)

  • a ( i ) a(i) a(i):样本 i 到同簇其他点的平均距离
  • b ( i ) b(i) b(i):样本 i 到最近其他簇的平均距离
  • 取值范围:[-1, 1],值越大聚类质量越高

2. Calinski-Harabasz 指数

通过方差比评估聚类质量:
C H = t r ( B k ) / ( K − 1 ) t r ( W k ) / ( n − K ) CH = \frac{tr(B_k)/(K-1)}{tr(W_k)/(n-K)} CH=tr(Wk)/(nK)tr(Bk)/(K1)

  • B k B_k Bk:簇间协方差矩阵
  • W k W_k Wk:簇内协方差矩阵
  • 值越大表示簇间差异越大,簇内越紧密

K-means 的 K 值选择方法详解

肘部法则 (Elbow Method)

计算不同 K 值对应的 SSE:

sse = []
for k in range(1, 11):kmeans = KMeans(n_clusters=k)kmeans.fit(data)sse.append(kmeans.inertia_)

相关文章:

  • 基于mybatis与PageHelper插件实现条件分页查询(3.19)
  • iOS中使用AWS上传zip文件到Minio上的oss平台上
  • 使用Matlab工具将RAW文件转化为TXT文件,用于FPGA仿真输入
  • 用Mac M4构建多架构Docker镜像指南
  • 若依框架免登陆、页面全屏显示、打开新标签页(看板大屏)
  • neo4j-community-3.5.5-unix.tar.gz安装
  • SpringBoot + Vue 实现云端图片上传与回显(基于OSS等云存储)
  • map和set封装
  • 开源身份和访问管理(IAM)解决方案:Keycloak
  • 信息收集之hack用的网络空间搜索引擎
  • 快速搭建 Cpolar 内网穿透(Mac 系统)
  • Spark-SQL连接Hive全攻略
  • 基础服务系列-Jupyter Notebook 支持JavaScript
  • 解决使用hc595驱动LED数码管亮度低的问题
  • MetaGPT智能体框架深度解析:记忆模块设计与应用实践
  • Versal Adaptive SoC AI Engine 知识分享6
  • 一图掌握 C++ 核心要点
  • 【阿里云大模型高级工程师ACP习题集】2.1 用大模型构建新人答疑机器人
  • 在CSDN的1095天(创作纪念日)
  • uniapp打ios包
  • 普京签署法律,诋毁俄军将面临最高7年监禁
  • 比起追逐爆款,动画行业更需要打开思路“重塑肉身”
  • 央行等:在上海试点通过再贴现窗口支持人民币跨境贸易融资
  • 长三角主流媒体将走进“来电”宜昌,探寻高质量发展密码
  • 广西柳州23年的蝶变:从“酸雨之城”到“文明之城”
  • 对话地铁读书人|来自法学教授的科普:读书日也是版权日