机器学习之其他聚类(层次聚类+DBSCAN算法)

其他聚类(层次聚类+DBSCAN算法)

层次聚类 与 DBSCAN算法 解释 无监督学习。

  1. 层次聚类

    • 核心概念 :层次聚类是一种无需预先指定簇数量的聚类方法。它通过逐步合并或分裂数据点,构建出一个层次化的聚类结构。

      【谨记】:层次聚类中每个样本只属于一个类,所以层次聚类属于硬聚类。(一般来说聚类分为硬聚类和软聚类,硬聚类明确一个样本只属于一个类,而软聚类的一个样本可以属于多个类)。

    • 两种方向:

      • 凝聚型(自底向上):每个点初始为一个簇,逐步合并 最相似的簇【推荐,常用✅】。
      • 分裂型(自顶向下):每个点初始为一个簇,逐步分裂成更小的簇。
    • 工作流程------凝聚型(自底向上):

      • 1、初始化:每个点独立成簇

      • 2、计算距离 :计算所有簇间距离矩阵,该步骤称为Linkage(连接方法/连接准则)

        刚开始时,每个点独立成簇,这时算的是点与点之间的距离 (通常用欧氏距离)。

        d=(x1−x2)2+(y1−y2)2 d = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} d=(x1−x2)2+(y1−y2)2

        但当点合并成簇之后,衡量'簇与簇'之间的距离就不再是简单的点对点欧氏距离,而是需要采用特定的连接准则(Linkage)。通常采用 Ward法(最小方差法) ,它通过计算合并后的方差增量来评估距离。

        1. 计算方法(Ward法) :计算合并这两个簇后,簇内方差(误差平方和 ESS)增加多少,选择使方差增加最小的两个簇合并。

        2. 公式(Ward法) :

          Δ(A,B)=∣A∣⋅∣B∣∣A∣+∣B∣∥μA−μB∥2 \Delta(A, B) = \frac{|A| \cdot |B|}{|A| + |B|} \| \mu_A - \mu_B \|^2 Δ(A,B)=∣A∣+∣B∣∣A∣⋅∣B∣∥μA−μB∥2

          • Δ(A,B):合并簇 (A) 和簇 (B) 带来的方差增量(即合并代价)。
          • ∣A∣、∣B∣:簇 (A) 和簇 (B) 中的样本数量。
          • μA、μB:簇 (A) 和簇 (B) 的质心(中心点)。
          • ∥μA−μB∥^2:两个质心之间的欧氏距离的平方。
      • 3、合并最近簇:选择使方差增加最小的两个簇合并

      • 4、迭代重复,直到满足停止条件

    • 案例:鸢尾花数据集进行聚类划分

      python 复制代码
      import numpy as np
      import matplotlib.pyplot as plt
      import seaborn as sns
      from sklearn import datasets
      from sklearn.cluster import AgglomerativeClustering
      from scipy.cluster.hierarchy import dendrogram, linkage
      from sklearn.metrics import adjusted_rand_score
      
      plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']  # 黑体优先,备选微软雅黑
      plt.rcParams['axes.unicode_minus'] = False  # 解决负号变成方框
      sns.set(font="SimHei") # seaborn热力图也要指定字体
      
      # 准备数据
      iris = datasets.load_iris()
      x = iris.data
      y_true = iris.target # 真实标签,仅用于最后的评估对比,聚类本身是无监督的
      
      # 数据标准化(层次聚类基于距离,标准化非常重要!!!!)
      from sklearn.preprocessing import StandardScaler
      scaler = StandardScaler()
      X_scaled = scaler.fit_transform(x)
      
      # 构建层次聚类模型
      model = AgglomerativeClustering(
          n_clusters=3,  # 最终簇的数量
          linkage='ward' # 最小化方差【推荐】
      )
      # 训练模型并预测
      y_pred = model.fit_predict(X_scaled)
      
      # 【可视化】:树状图 (Dendrogram)
      plt.figure(figsize=(12, 5))
      # 使用 scipy 的 linkage 计算距离矩阵
      Z = linkage(X_scaled, method='ward')
      dendrogram(Z)
      plt.title('层次聚类树状图 (Iris Dataset)', fontsize=14)
      plt.xlabel('样本索引', fontsize=12)
      plt.ylabel('距离', fontsize=12)
      k = 3 # 最终簇的数量
      # 找第k个和第k-1个簇合并时的距离,取其均值作为切割线高度
      cut_height = (Z[-k, 2] + Z[-(k-1), 2]) / 2
      plt.axhline(y=cut_height, color='r', linestyle='--', label=f'切割线 (height={cut_height:.2f})') # 辅助线,展示如何划分簇
      plt.legend()
      plt.show()
      
      # 【可视化】:聚类结果散点图
      plt.figure(figsize=(8, 6))
      plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=y_pred, cmap='viridis', s=60, alpha=0.8)
      plt.title('层次聚类结果 (K=3)', fontsize=14)
      feature_names = iris.feature_names[:2] # 获取前两个特征的名称
      feature_names_cn = ['萼片长度 (cm)', '萼片宽度 (cm)']
      plt.xlabel(f'特征值一:{feature_names_cn[0]}(标准化)', fontsize=12)
      plt.ylabel(f'特征值二:{feature_names_cn[1]}(标准化)', fontsize=12)
      plt.show()
      
      # 模型评估
      ari = adjusted_rand_score(y_true, y_pred)
      print(f"调整兰德指数 (ARI): {ari:.2f}")
      ----------------------------------------------------------------------------
      调整兰德指数 (ARI): 0.62
      ----------------------------------------------------------------------------   


  2. DBSCAN聚类

    • 核心概念:DBSCAN是基于密度的聚类方法,通过识别高密度区域来形成簇。

    • 核心优势:

      • 自动确定簇数:无需预先指定K值,根据数据密度自动发现簇的数量。
      • 任意形状检测:突破K-means的球形限制,能发现环形、月牙形等复杂形状。
      • 噪声点识别:能自动识别并标记离群点(噪声点标记为 -1)。
    • 基本概念:

      • 邻域 :对于数据集中的任意点P,以P为中心,半径为 eps 的区域称为 P 的邻域。
      • 核心点(Core Point) :如果一个点的邻域(给定半径 eps的区域 )内至少有 min_samples 个邻居点,那么这个点被称为核心点。
      • 边界点(Border Point) :一个点的邻域内没有达到min_samples 个点,但它在某个核心点的邻域内,这样的点被称为边界点。
      • 噪声点(Noise Point):既不是核心点也不是边界点,被标记为离群值。
    • 【算法逻辑 】:以未访问核心点为起点,搜索其eps 邻域,将邻域内核心点、边界点归入同一簇;邻域内找到的所有核心点可继续向外扩张,而边界点仅归入簇、不能扩展。不断收集所有密度相连的点形成簇。无法被纳入任何簇的点即为噪声点。

    • 案例:鸢尾花数据集进行聚类划分

      • eps (邻域半径):范围太小会产生更多小簇和噪声;太大则合并成同一簇。

        建议数据标准化后 尝试 0.3-0.5(可用K-距离图辅助选择)。

      • min_samples (最小样本数):太小会产生更多簇;太大会形成更紧密的簇。

        建议至少设为维度数+1 或维度*2。

      python 复制代码
      import numpy as np
      import matplotlib.pyplot as plt
      import seaborn as sns
      from sklearn import datasets
      from sklearn.cluster import AgglomerativeClustering
      from scipy.cluster.hierarchy import dendrogram, linkage
      from sklearn.metrics import adjusted_rand_score
      from sklearn.cluster import DBSCAN
      
      plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']  # 黑体优先,备选微软雅黑
      plt.rcParams['axes.unicode_minus'] = False  # 解决负号变成方框
      sns.set(font="SimHei") # seaborn热力图也要指定字体
      
      # 准备数据
      iris = datasets.load_iris()
      x = iris.data
      y_true = iris.target # 真实标签,仅用于最后的评估对比,聚类本身是无监督的
      
      # 数据标准化(层次聚类基于距离,标准化非常重要!!!!)
      from sklearn.preprocessing import StandardScaler
      scaler = StandardScaler()
      X_scaled = scaler.fit_transform(x)
      
      # 创建并训练 DBSCAN 模型
      # eps: 邻域半径
      # min_samples: 核心点所需的最小样本数
      model = DBSCAN(
          eps=0.5,            # 邻域半径
          min_samples=8,      # 最小样本数
          metric='euclidean'  # 距离度量方式(默认方法)
      )
      y_pred = model.fit_predict(X_scaled)
      
      # 统计结果
      n_clusters = len(set(y_pred)) - (1 if -1 in y_pred else 0)  # 去除-1(噪声点)后的簇数量
      n_noise = list(y_pred).count(-1)  # 统计噪声点数量
      print(f"聚类数量: {n_clusters}")
      print(f"噪声点数量: {n_noise}")
      
      # 评估模型(使用ARI指标,对比真实标签,值越接近1越好)
      ari = adjusted_rand_score(y_true, y_pred)
      print(f"调整兰德指数(ARI): {ari:.4f}")
      
      
      # 结果可视化(只取前两个特征绘制二维散点图以便观察)
      plt.figure(figsize=(10, 6))
      # 绘制正常簇
      # 利用布尔索引找出非噪声点(标签 != -1)
      core_samples_mask = np.zeros_like(y_pred, dtype=bool)
      core_samples_mask[model.core_sample_indices_] = True  # 核心点掩码
      non_noise = y_pred != -1
      # 绘制所有非噪声点
      plt.scatter(X_scaled[non_noise, 0], X_scaled[non_noise, 1],
                  c=y_pred[non_noise], cmap='viridis', s=50, alpha=0.7, label='聚类点')
      # 绘制噪声点(黑色叉号标记)
      plt.scatter(X_scaled[~non_noise, 0], X_scaled[~non_noise, 1],
                  c='black', marker='x', s=50, label='噪声点(-1)')
      plt.title(f'DBSCAN 聚类结果 (簇数: {n_clusters}, 噪声点: {n_noise})')
      plt.xlabel('特征1 (标准化后)')
      plt.ylabel('特征2 (标准化后)')
      plt.legend()
      plt.show()
      ------------------------------------------------------------------------------
      聚类数量: 3
      噪声点数量: 59
      调整兰德指数(ARI): 0.4436
      ------------------------------------------------------------------------------
  3. 三大聚类算法对比:

    对比维度 K-means 层次聚类 DBSCAN
    簇的形状 球形/凸形 任意形状 任意形状
    是否需要指定K 需要 需要(可选) 不需要
    噪声处理 强制分配到某簇 强制分配到某簇 可识别噪声点(标记为-1)
    计算复杂度 O(n·k·i) O(n²·log n) O(n·log n)
    大数据集性能 优秀 较慢 良好
    参数调节难度 简单(K值) 中等(连接方法) 较难(eps, min_samples)
    可解释性 高 很高(树状图) 中等
  4. 算法选择策略:

    • 数据规模评估:

      • 小数据集 (<10K):三种算法均可使用。
      • 大数据集 (>100K):优先选择 K-means 或 DBSCAN(因为层次聚类计算复杂度高,处理大数据会非常慢)。
    • 簇形状判断:

      • 球形分布:K-means 效果最佳。
      • 复杂形状(如环形、月牙形):选择层次聚类 或 DBSCAN。
    • 簇形状判断:

      • 球形分布:K-means 效果最佳。
      • 复杂形状(如环形、月牙形):选择层次聚类 或 DBSCAN。
    • K值是否已知:

      • 明确簇数:K-means 最高效。
      • 未知簇数:选择 DBSCAN 或 层次聚类(两者都能自动探索簇的数量)。
    • 可解释性需求:

      • 需要层次关系(如生物分类):选择 层次聚类(树状图非常直观)。
      • 仅需簇划分:选择 K-means 或 DBSCAN。
  5. 注意点:

    算法 常见陷阱 原因与现象 规避策略(操作建议)
    K-means 初始化敏感 不同的随机种子(random_state)可能导致完全不同的聚类结果,陷入局部最优。 多次运行取最优(如 n_init=10),或使用 K-means++ 初始化算法(sklearn默认已采用)。
    假设球形簇 对环形、月牙形等复杂形状数据效果极差,会强行切割数据。 遇到此类数据立即放弃K-means,改用 DBSCAN (基于密度)或 层次聚类。
    受离群点影响大 极值会严重拉偏质心位置,导致正常数据被错误划分。 聚类前进行严格的数据清洗,剔除极端异常值,或改用对噪声不敏感的 DBSCAN。
    层次聚类 计算成本极高 复杂度达 O(n2log⁡n)O (n 2logn)。当样本量 > 10,000 时,内存和计算时间呈指数级膨胀。 大数据集(>100K)禁止直接使用。可采用"抽样聚类"策略,或改用K-means/DBSCAN。
    无法撤销合并(错误累积) 一旦两个簇合并,后续就无法撤销。如果某一步合并错误,错误会一直累积影响最终结果。 多尝试不同的 linkage(连接方法);结合业务常识反复验证树状图的切割位置。
    连接方法选择困难 single(最小距离)容易产生链式效应,complete(最大距离)容易产生小型簇,结果差异大。 强烈推荐默认使用 ward(最小方差法),通常能产生更紧凑、更平衡的簇。
    DBSCAN 参数调优极其困难 eps 和 min_samples 极度敏感。eps 稍微变动0.1,结果可能天差地别。 先小样本,后大数据 。绘制 K-距离图 找拐点定 eps;固定 eps 微调 min_samples,控制噪声比例在5%-20%。
    密度差异大表现不佳 算法要求全局密度统一。数据集中既有密集簇又有稀疏簇时,单一参数无法兼顾。 尝试对数据进行分层处理,或改用 HDBSCAN(层次密度的DBSCAN变体)等改进算法。
    高维诅咒 高维空间中所有点距离趋同,"密度"概念失效,导致聚类效果急剧下降。 运行DBSCAN前,先使用 PCA(主成分分析) 或 t-SNE 进行降维处理。
相关推荐
ofoxcoding1 小时前
Gemini TTS 与 ElevenLabs 语音合成实测:同一段视频旁白效果对比
ai·ffmpeg·音视频
雪雪9081 小时前
Work Agent深度解读:AI如何自主完成多步骤长程工作任务
人工智能
小宋10211 小时前
Recursive Language Models 实战:递归处理超长外部文本
人工智能·深度学习·机器学习
星云低代码开发平台1 小时前
AI 定时任务接 ERP:账号切换后的权限校验与异常状态设计
人工智能·定时任务·erp
烟雨江南7851 小时前
灵声智库-招投标会议语音识别怎么做?实时转写、多人发言与会议留痕方案
人工智能·音视频·语音识别·ai客服
李福春1 小时前
斗破Google ADK Java苍穹-第7境斗皇-御天地-Harness治理
java·人工智能·python·深圳同盟·腾讯云架构师技术同盟·adk java·harness 治理
看浪的路人1 小时前
第1讲:2026 大模型应用开发全景——Prompt / RAG / 微调 / Agent 到底先用哪个
人工智能·算法
wjkjpcba1 小时前
机器人控制板PCBA贴片厂家制造工艺解析:SMT贴片、DIP插件与检测流程
人工智能·机器人·smt贴片加工·pcba贴片加工厂
星核0penstarry1 小时前
企业接入多家 AI API,聚合平台能解决什么、不能解决什么
人工智能·大模型·ai编程·合规·api聚合平台·大模型网关·接入层