聚类算法详解:K-means、层次聚类与 DBSCAN

聚类算法详解:K-means、层次聚类与 DBSCAN

聚类(Clustering)是无监督学习中最重要的任务之一。它不依赖人工提供的类别标签,而是根据样本之间的相似性,将数据自动划分为若干组,使同一组中的样本尽可能相似,不同组之间的样本尽可能不同。

聚类广泛应用于客户分群、图像分割、异常检测、文本主题发现、设备状态分析、生物信息学和工业过程分析等场景。

本文围绕三类经典聚类模型展开:

  • 质心模型(Centroid Models):K-means 聚类;
  • 连接模型(Connectivity Models):层次聚类;
  • 密度模型(Density Models):DBSCAN。

这三种方法分别从"距离中心""样本连接关系"和"局部密度"三个角度理解数据结构。掌握它们,不仅能够完成常见聚类任务,也能理解不同聚类算法为什么会得到完全不同的结果。


一、什么是聚类

假设有一个没有类别标签的数据集:

X={x1,x2,...,xn}X=\{x_1,x_2,\ldots,x_n\}X={x1,x2,...,xn}

其中,每个样本都由若干特征组成。聚类算法的目标是把数据划分为若干簇:

C={C1,C2,...,Ck}C=\{C_1,C_2,\ldots,C_k\}C={C1,C2,...,Ck}

理想情况下,同一簇中的样本具有较高相似度,不同簇之间具有较低相似度。

聚类和分类的最大区别在于:

对比项 分类 聚类
学习类型 监督学习 无监督学习
是否需要标签 需要 不需要
目标 预测已知类别 发现潜在结构
常见算法 逻辑回归、决策树、神经网络 K-means、层次聚类、DBSCAN

聚类并不存在唯一正确答案。对于同一份数据,采用不同的距离度量、参数或算法,可能得到不同的聚类结果。因此,聚类结果需要结合数据分布、业务目标和评价指标共同判断。


二、聚类前的数据准备

聚类算法通常高度依赖样本之间的距离,因此数据预处理非常重要。

1. 特征缩放

假设一个数据集包含"年龄"和"年收入"两个特征。年龄通常在几十以内,而年收入可能达到几十万。如果直接计算欧氏距离,年收入会主导距离结果。

标准化的常见形式为:

z=x−μσz=\frac{x-\mu}{\sigma}z=σx−μ

其中:

  • x 表示原始特征值;
  • μ 表示该特征的均值;
  • σ 表示该特征的标准差;
  • z 表示标准化后的值。

在 Scikit-learn 中可以使用:

python 复制代码
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

2. 异常值处理

极端异常值可能显著改变 K-means 的质心位置,也可能影响层次聚类的合并顺序。对于明显错误的数据,可以考虑删除、截断或使用稳健缩放。

DBSCAN 可以识别部分离群点,但这并不意味着可以完全忽略数据清洗。

3. 高维数据降维

在高维空间中,距离之间的差异可能逐渐变得不明显,这种现象常被称为"维度灾难"。

常见处理方法包括:

  • 使用 PCA 降维;
  • 删除冗余特征;
  • 进行特征选择;
  • 使用适合高维数据的相似度度量。

三、质心模型:K-means 聚类

K-means 是最经典、最常用的聚类算法之一。它将数据划分为 K 个簇,每个簇由一个质心表示。

K-means 的核心思想是:

每个样本属于距离自己最近的质心,并不断更新质心,直到聚类结果稳定。

1. K-means 的目标函数

假设数据被划分为 K 个簇,每个簇的质心为 μ_k。K-means 希望最小化所有样本到其所属质心的平方距离之和:

J=∑k=1K∑xi∈Ck∥xi−μk∥22J=\sum_{k=1}^{K}\sum_{x_i\in C_k}\left\|x_i-\mu_k\right\|_2^2J=k=1∑Kxi∈Ck∑∥xi−μk∥22

其中:

  • K 是簇的数量;
  • C_k 是第 k 个簇;
  • μ_k 是第 k 个簇的质心;
  • J 也称为簇内平方和、惯性或 SSE。

质心由簇内所有样本的平均值计算:

μk=1∣Ck∣∑xi∈Ckxi\mu_k=\frac{1}{|C_k|}\sum_{x_i\in C_k}x_iμk=∣Ck∣1xi∈Ck∑xi

2. K-means 的运行步骤

K-means 通常按照以下步骤迭代:

  1. 预先指定簇的数量 K
  2. 随机选择 K 个初始质心;
  3. 将每个样本分配给距离最近的质心;
  4. 根据当前簇内样本重新计算质心;
  5. 重复分配与更新,直到质心基本不再变化或达到最大迭代次数。

样本分配规则可以写成:

ci=arg⁡min⁡k∥xi−μk∥22c_i=\arg\min_k\left\|x_i-\mu_k\right\|_2^2ci=argkmin∥xi−μk∥22

K-means 每次迭代都不会增加目标函数,因此最终会收敛。不过,它通常只能收敛到局部最优解,而不保证得到全局最优解。

3. K-means 聚类示意图

图中的普通点表示样本,较大的 X 标记表示每个簇的质心。K-means 实际上是在不断移动这些质心,使簇内样本到质心的总距离尽可能小。

4. K-means++ 初始化

传统随机初始化可能选出位置很接近的初始质心,导致收敛速度慢或结果较差。

K-means++ 会尽量让初始质心彼此分散,从而提高聚类稳定性。Scikit-learn 默认通常采用 K-means++ 初始化。

python 复制代码
from sklearn.cluster import KMeans

model = KMeans(
    n_clusters=3,
    init="k-means++",
    n_init=10,
    random_state=42
)

labels = model.fit_predict(X_scaled)
centers = model.cluster_centers_

主要参数包括:

  • n_clusters:簇的数量;
  • init:质心初始化方式;
  • n_init:使用不同初始质心重复运行的次数;
  • max_iter:单次运行的最大迭代次数;
  • random_state:随机种子。

5. 如何选择 K

K-means 最大的问题之一是必须提前指定 K。常见方法包括肘部法和轮廓系数。

5.1 肘部法

依次尝试不同的 K,记录簇内平方和。当增加簇数带来的收益明显减小时,曲线会出现类似手肘的拐点。

代码示例:

python 复制代码
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

inertias = []
k_values = range(1, 11)

for k in k_values:
    model = KMeans(
        n_clusters=k,
        n_init=10,
        random_state=42
    )
    model.fit(X_scaled)
    inertias.append(model.inertia_)

plt.plot(k_values, inertias, marker="o")
plt.xlabel("Number of clusters")
plt.ylabel("Inertia")
plt.show()

肘部法直观,但有些数据并不存在明显拐点。

5.2 轮廓系数

对于样本 i,定义:

  • a(i):样本与同簇其他样本的平均距离;
  • b(i):样本与最近其他簇中样本的平均距离。

轮廓系数为:

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)

轮廓系数的范围为 -11

  • 接近 1:样本与本簇匹配良好,与其他簇区分明显;
  • 接近 0:样本位于两个簇的边界附近;
  • 小于 0:样本可能被分到了错误的簇。
python 复制代码
from sklearn.metrics import silhouette_score

score = silhouette_score(X_scaled, labels)
print("Silhouette score:", score)

6. K-means 的优点

  • 原理简单,容易理解和实现;
  • 计算速度快,适合较大规模数据;
  • 对近似球状、大小相近的簇效果较好;
  • 结果易于解释,每个簇都有明确质心;
  • 可以对新样本快速分配簇。

7. K-means 的局限

  • 必须提前指定 K
  • 对初始质心敏感;
  • 对异常值敏感;
  • 更适合凸形、近似球状的簇;
  • 不擅长发现弯月形、环形等复杂结构;
  • 当不同簇的密度和大小差异明显时,效果可能较差;
  • 主要适用于数值型特征和均值有意义的数据。

四、连接模型:层次聚类

层次聚类(Hierarchical Clustering)根据样本或簇之间的连接关系,逐步构建一个树状层次结构。

与 K-means 不同,层次聚类不只给出一个固定划分,还可以通过树状图观察从细粒度到粗粒度的完整合并过程。

层次聚类分为两类:

  • 凝聚式层次聚类:从每个样本各自成簇开始,逐步合并;
  • 分裂式层次聚类:从所有样本属于一个簇开始,逐步拆分。

实际应用中,凝聚式层次聚类更常见。

1. 凝聚式层次聚类流程

  1. 初始时,每个样本都是一个独立簇;
  2. 计算所有簇之间的距离;
  3. 合并距离最近的两个簇;
  4. 重新计算新簇与其他簇之间的距离;
  5. 重复合并,直到达到指定簇数或所有样本合并为一个簇。

关键问题是:

两个簇之间的距离应该如何定义?

这由链接准则决定。

2. 常见链接准则

2.1 Single Linkage

单链接使用两个簇中最近样本之间的距离:

d(A,B)=min⁡x∈A,y∈Bd(x,y)d(A,B)=\min_{x\in A,y\in B}d(x,y)d(A,B)=x∈A,y∈Bmind(x,y)

优点是能够发现细长或不规则形状的簇,但容易产生"链式效应",即一些距离较近的点把多个区域串联起来。

2.2 Complete Linkage

全链接使用两个簇中最远样本之间的距离:

d(A,B)=max⁡x∈A,y∈Bd(x,y)d(A,B)=\max_{x\in A,y\in B}d(x,y)d(A,B)=x∈A,y∈Bmaxd(x,y)

它更倾向于形成紧凑的簇,但对异常值较敏感。

2.3 Average Linkage

平均链接使用两个簇之间所有样本对距离的平均值:

d(A,B)=1∣A∣∣B∣∑x∈A∑y∈Bd(x,y)d(A,B)=\frac{1}{|A||B|}\sum_{x\in A}\sum_{y\in B}d(x,y)d(A,B)=∣A∣∣B∣1x∈A∑y∈B∑d(x,y)

它通常比单链接和全链接更加平衡。

2.4 Ward Linkage

Ward 方法选择使簇内平方误差增加最少的合并方案。

若合并簇 AB,其代价可表示为:

Δ(A,B)=∣A∣∣B∣∣A∣+∣B∣∥μA−μB∥22\Delta(A,B)=\frac{|A||B|}{|A|+|B|}\left\|\mu_A-\mu_B\right\|_2^2Δ(A,B)=∣A∣+∣B∣∣A∣∣B∣∥μA−μB∥22

Ward 方法往往得到大小相对均衡、结构较紧凑的簇,常与欧氏距离一起使用。

3. 树状图 Dendrogram

树状图能够展示层次聚类的整个合并过程:

横轴表示样本或样本组,纵轴表示合并距离。两个分支在越高的位置合并,通常意味着它们之间差异越大。

通过在某个高度水平切割树状图,可以得到相应数量的簇。

4. 使用 Scikit-learn 实现层次聚类

python 复制代码
from sklearn.cluster import AgglomerativeClustering

model = AgglomerativeClustering(
    n_clusters=3,
    linkage="ward"
)

labels = model.fit_predict(X_scaled)

可选的 linkage 包括:

  • ward
  • complete
  • average
  • single

对于较新的 Scikit-learn 版本,可以使用 metric 指定距离度量。当使用 ward 时,通常要求采用欧氏距离。

5. 使用 SciPy 绘制树状图

python 复制代码
import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import linkage, dendrogram

Z = linkage(X_scaled, method="ward")

dendrogram(Z)
plt.xlabel("Samples")
plt.ylabel("Merge distance")
plt.show()

linkage 返回一个合并矩阵,记录每一步合并的两个簇、合并距离以及新簇中的样本数。

6. 层次聚类的优点

  • 可以展示数据的多层次结构;
  • 不必在算法开始前立即确定最终簇数;
  • 树状图具有较强可解释性;
  • 可以使用不同距离和链接准则;
  • 适合探索中小规模数据集。

7. 层次聚类的局限

  • 计算和内存开销通常高于 K-means;
  • 大规模数据上的效率较低;
  • 早期错误合并通常无法撤销;
  • 结果对距离度量和链接准则敏感;
  • 异常值可能形成孤立分支或影响合并结构;
  • 不同切割高度会得到不同簇数。

五、密度模型:DBSCAN

DBSCAN 的全称是 Density-Based Spatial Clustering of Applications with Noise,即"带噪声的基于密度的空间聚类"。

它不使用质心,也不要求所有簇是球状结构。DBSCAN 的核心思想是:

如果某个区域中的样本足够密集,那么这些样本应属于同一个簇;低密度区域则可以作为簇之间的边界。

DBSCAN 还能够自动识别噪声点,因此常用于异常点较多、簇形状不规则的数据。

1. 两个关键参数

DBSCAN 主要由两个参数控制:

  • eps:邻域半径;
  • min_samples:一个点成为核心点所需的最少邻域样本数。

peps 邻域定义为:

Nε(p)={q∣d(p,q)≤ε}N_{\varepsilon}(p)=\{q\mid d(p,q)\leq\varepsilon\}Nε(p)={q∣d(p,q)≤ε}

当邻域中的样本数量满足以下条件时,点 p 是核心点:

∣Nε(p)∣≥MinPts|N_{\varepsilon}(p)|\geq\text{MinPts}∣Nε(p)∣≥MinPts

2. 三类样本点

DBSCAN 将样本分为三类。

2.1 核心点

eps 邻域内至少包含 min_samples 个样本的点。

核心点处于高密度区域,可以继续向外扩展簇。

2.2 边界点

自身邻域样本不足,不能成为核心点,但位于某个核心点的邻域中。

边界点属于簇,但不能继续扩展其他样本。

2.3 噪声点

既不是核心点,也不属于任何核心点邻域的样本。

在 Scikit-learn 中,噪声点的标签通常为 -1

3. DBSCAN 的聚类过程

  1. 任选一个尚未访问的样本;
  2. 检查其 eps 邻域;
  3. 如果它是核心点,则建立一个新簇;
  4. 将其邻域中的样本加入候选集合;
  5. 对候选集合中的核心点继续扩展邻域;
  6. 直到没有新的密度可达样本;
  7. 继续处理下一个未访问样本;
  8. 无法归入任何簇的点被标记为噪声。

4. DBSCAN 聚类示意图

对于弯月形数据,K-means 往往会按照空间中心进行切割,而 DBSCAN 可以沿着高密度区域恢复非球形簇,并把孤立点标记为噪声。

5. 使用 Scikit-learn 实现 DBSCAN

python 复制代码
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler

X_scaled = StandardScaler().fit_transform(X)

model = DBSCAN(
    eps=0.3,
    min_samples=5
)

labels = model.fit_predict(X_scaled)

统计簇数量时,需要排除噪声标签:

python 复制代码
import numpy as np

unique_labels = set(labels)
n_clusters = len(unique_labels) - (1 if -1 in unique_labels else 0)
n_noise = np.sum(labels == -1)

print("Number of clusters:", n_clusters)
print("Number of noise points:", n_noise)

6. 如何选择 eps

一种常见方法是绘制 K-distance 曲线。

基本步骤如下:

  1. 对每个样本计算其第 k 个最近邻的距离;
  2. 将这些距离从小到大排序;
  3. 绘制排序后的距离曲线;
  4. 选择曲线开始快速上升的位置作为 eps 的候选值。

通常可以令 kmin_samples 接近。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors

neighbors = NearestNeighbors(n_neighbors=5)
neighbors_fit = neighbors.fit(X_scaled)

distances, indices = neighbors_fit.kneighbors(X_scaled)
k_distances = np.sort(distances[:, -1])

plt.plot(k_distances)
plt.xlabel("Sorted samples")
plt.ylabel("5th nearest-neighbor distance")
plt.show()

K-distance 曲线只能提供候选范围,最终仍需结合聚类数量、噪声比例和业务意义调整。

7. 如何选择 min_samples

常见经验包括:

  • 在二维数据中,可以从 45 开始尝试;
  • 特征维度较高时,通常需要适当增大;
  • min_samples 越大,成为核心点的条件越严格;
  • 参数过大可能把大量正常点标记为噪声;
  • 参数过小可能把随机波动识别为小簇。

经验值并不是固定规则,仍需通过数据分布和验证结果选择。

8. DBSCAN 的优点

  • 不需要提前指定簇数;
  • 能发现任意形状的簇;
  • 能识别噪声点和离群点;
  • 不依赖质心;
  • 对弯曲、环形和非凸形数据通常优于 K-means。

9. DBSCAN 的局限

  • epsmin_samples 较敏感;
  • 不同密度的簇难以使用同一组参数同时识别;
  • 高维空间中的距离会变得不稳定;
  • 特征缩放对结果影响很大;
  • 对非常大的数据集,邻域搜索可能带来较高开销;
  • 噪声点不一定是真正的业务异常,需要进一步判断。

六、三种聚类算法的完整代码对比

下面使用同一个数据集分别运行 K-means、层次聚类和 DBSCAN。

python 复制代码
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
from sklearn.cluster import AgglomerativeClustering
from sklearn.cluster import DBSCAN

X, _ = make_moons(
    n_samples=500,
    noise=0.07,
    random_state=42
)

X_scaled = StandardScaler().fit_transform(X)

kmeans = KMeans(
    n_clusters=2,
    n_init=10,
    random_state=42
)
kmeans_labels = kmeans.fit_predict(X_scaled)

hierarchical = AgglomerativeClustering(
    n_clusters=2,
    linkage="ward"
)
hierarchical_labels = hierarchical.fit_predict(X_scaled)

dbscan = DBSCAN(
    eps=0.25,
    min_samples=6
)
dbscan_labels = dbscan.fit_predict(X_scaled)

results = {
    "K-means": kmeans_labels,
    "Hierarchical": hierarchical_labels,
    "DBSCAN": dbscan_labels
}

for name, labels in results.items():
    plt.figure()
    plt.scatter(
        X_scaled[:, 0],
        X_scaled[:, 1],
        c=labels,
        s=20
    )
    plt.title(name)
    plt.show()

在弯月形数据上:

  • K-means 更倾向于使用直线边界切分数据;
  • Ward 层次聚类也更偏向紧凑簇;
  • DBSCAN 可以沿弯月形高密度区域识别两个簇。

这说明算法选择不能只看是否"运行成功",而要判断算法假设是否符合数据结构。


七、聚类结果的评价指标

无监督学习没有真实标签时,可以使用内部评价指标。

1. 轮廓系数

轮廓系数同时衡量簇内紧密程度和簇间分离程度,取值越大通常越好。

python 复制代码
from sklearn.metrics import silhouette_score

score = silhouette_score(X_scaled, labels)
print(score)

注意:当所有样本都属于同一个簇,或每个样本单独成簇时,轮廓系数无法正常计算。

2. Calinski-Harabasz 指数

该指标比较簇间离散程度和簇内离散程度:

CH=Tr⁡(Bk)/(k−1)Tr⁡(Wk)/(n−k)CH=\frac{\operatorname{Tr}(B_k)/(k-1)}{\operatorname{Tr}(W_k)/(n-k)}CH=Tr(Wk)/(n−k)Tr(Bk)/(k−1)

一般来说,数值越大表示簇间分离越明显、簇内越紧凑。

python 复制代码
from sklearn.metrics import calinski_harabasz_score

score = calinski_harabasz_score(X_scaled, labels)
print(score)

3. Davies-Bouldin 指数

Davies-Bouldin 指数衡量每个簇与最相似簇之间的平均相似度:

DB=1k∑i=1kmax⁡j≠iSi+SjMijDB=\frac{1}{k}\sum_{i=1}^{k}\max_{j\neq i}\frac{S_i+S_j}{M_{ij}}DB=k1i=1∑kj=imaxMijSi+Sj

其中:

  • S_i 表示第 i 个簇内部的离散程度;
  • M_ij 表示两个簇中心之间的距离。

该指标通常越小越好。

python 复制代码
from sklearn.metrics import davies_bouldin_score

score = davies_bouldin_score(X_scaled, labels)
print(score)

4. 有真实标签时的外部指标

在实验数据中,有时保留了真实类别,但聚类过程不使用这些标签。此时可以使用:

  • 调整兰德指数 ARI;
  • 归一化互信息 NMI;
  • 调整互信息 AMI;
  • Fowlkes-Mallows 指数。

聚类标签的数字本身没有类别顺序。例如,真实类别 0 可能对应聚类标签 2,因此不能直接使用普通分类准确率评价。


八、如何选择合适的聚类算法

1. 选择 K-means 的情况

适合:

  • 数据量较大;
  • 特征主要是连续数值;
  • 簇近似球状;
  • 各簇大小和密度接近;
  • 已知或可以估计簇数;
  • 需要对新样本快速分配类别。

不适合:

  • 簇形状复杂;
  • 异常值较多;
  • 不同簇密度差异很大;
  • 质心缺乏实际意义。

2. 选择层次聚类的情况

适合:

  • 数据规模较小或中等;
  • 希望观察多层次结构;
  • 不确定最终簇数;
  • 需要通过树状图解释样本关系;
  • 希望比较不同链接准则。

不适合:

  • 数据规模非常大;
  • 需要频繁增加新数据;
  • 对计算效率要求很高;
  • 早期错误合并会产生严重影响。

3. 选择 DBSCAN 的情况

适合:

  • 不知道簇数;
  • 簇形状不规则;
  • 数据中存在噪声;
  • 簇可以通过局部密度连接;
  • 希望同时完成聚类和噪声识别。

不适合:

  • 不同簇的密度差异很大;
  • 数据维度很高;
  • 无法找到稳定的邻域半径;
  • 特征尺度差异尚未处理。

九、三种算法对比

特征 K-means 层次聚类 DBSCAN
模型类型 质心模型 连接模型 密度模型
是否预先指定簇数 可后续切割决定
是否支持任意形状簇 较弱 取决于链接方式
是否识别噪声 默认不识别
对异常值敏感 中到高 相对较低
大规模数据效率 较高 较低 取决于邻域搜索
主要参数 K 簇数、链接准则、距离 epsmin_samples
典型输出 质心与簇标签 树状结构与簇标签 簇标签与噪声点
适合的数据结构 紧凑球状簇 层次关系明显的数据 密度连续、形状复杂的数据

十、常见错误与排查方法

1. 忘记标准化

症状:

  • 某个大数值特征主导聚类;
  • 聚类结果与直觉完全不同;
  • DBSCAN 几乎把所有点放在一起或全部判为噪声。

解决方法:

python 复制代码
from sklearn.preprocessing import StandardScaler

X_scaled = StandardScaler().fit_transform(X)

2. 只使用二维可视化判断结果

PCA、t-SNE 或 UMAP 可视化会改变部分空间关系。二维图只能帮助理解,不能完全替代原始特征空间中的评价。

3. 把聚类编号理解为大小顺序

聚类标签 012 只是编号,不代表等级、大小或优先级。

4. 只看一个评价指标

高轮廓系数不一定代表业务上有意义。聚类结果还需要回答:

  • 每个簇是否具有稳定特征;
  • 不同簇是否存在清晰业务差异;
  • 聚类是否能支持后续决策;
  • 结果对参数变化是否稳定。

5. 在 DBSCAN 中直接使用原始尺度

当各特征量纲不同,固定的 eps 很难同时适用于所有维度。应先标准化,再进行参数搜索。

6. 在 K-means 中忽略异常值

异常值会拉动均值,从而移动质心。可以先使用箱线图、稳健统计方法或异常检测算法识别极端点。

7. 将 DBSCAN 噪声点直接视为异常事件

DBSCAN 的噪声标签只表示该点在当前参数下不属于足够密集的区域。它可能是:

  • 真正异常;
  • 稀有但正常的样本;
  • 簇边缘样本;
  • 参数设置不合理导致的误判。

十一、一个更完整的聚类实验流程

实际项目中,可以按照以下流程开展聚类分析。

第一步:明确目标

先确定聚类是为了:

  • 用户分群;
  • 设备状态划分;
  • 产品分组;
  • 异常发现;
  • 图像区域分割;
  • 文本主题分析。

目标不同,特征选择和算法选择也不同。

第二步:理解数据

检查:

  • 样本数量;
  • 特征类型;
  • 缺失值;
  • 异常值;
  • 特征分布;
  • 特征相关性;
  • 是否存在明显时间或空间结构。

第三步:预处理

包括:

  • 缺失值填补;
  • 类别变量编码;
  • 特征标准化;
  • 异常值处理;
  • 必要时降维。

第四步:建立基线

可以先尝试:

  • K-means;
  • Ward 层次聚类;
  • DBSCAN。

使用统一的数据预处理,比较不同模型的结果。

第五步:参数搜索

K-means:

  • 尝试多个 K
  • 比较惯性、轮廓系数和业务解释。

层次聚类:

  • 比较不同链接准则;
  • 检查树状图;
  • 尝试不同切割高度。

DBSCAN:

  • 绘制 K-distance 曲线;
  • 搜索 eps
  • 调整 min_samples
  • 检查噪声比例。

第六步:解释簇

对每个簇统计:

  • 样本数量;
  • 特征均值与中位数;
  • 关键特征分布;
  • 与其他簇的主要差异;
  • 代表性样本;
  • 业务含义。

第七步:稳定性验证

可以对数据进行重复采样,或轻微改变参数,观察:

  • 簇数量是否稳定;
  • 样本归属是否频繁变化;
  • 簇特征是否保持一致;
  • 业务结论是否可靠。

十二、总结

K-means、层次聚类和 DBSCAN 分别代表三种不同的聚类思想。

K-means 使用质心描述簇,通过最小化样本到质心的平方距离形成紧凑分组。它速度快、实现简单,但需要预先指定簇数,并更适合近似球状的数据。

层次聚类通过逐步合并或拆分样本建立树状结构。它能够展示多层次关系,适合探索性分析,但计算成本较高,结果也依赖链接准则。

DBSCAN 使用局部密度发现簇,不需要指定簇数,能够识别任意形状的簇和噪声点。不过,它对参数和特征尺度敏感,也难以同时处理密度差异很大的多个簇。

可以将三种方法概括为:

  • K-means 关注"样本离哪个中心最近";
  • 层次聚类关注"哪些样本或簇应该先连接";
  • DBSCAN 关注"哪些区域足够密集并能够相互到达"。

在实际任务中,不应机械地追求某一种算法,而应根据数据形状、样本规模、噪声情况、参数可解释性和业务目标综合选择。一个可靠的聚类结果不仅要在指标上表现良好,还应具有稳定、清晰且可应用的业务含义。

相关推荐
碧海银沙音频科技研究院2 小时前
4 BES2710编译环境搭建方法
嵌入式硬件·算法
mifengxing2 小时前
LeetCode 238 除自身以外数组的乘积|无除法O(n)时间+O(1)空间双解法
java·算法·leetcode
依然鸣2 小时前
PTA团体程序设计天梯赛L2真题讲解L2-045-048
数据结构·c++·经验分享·学习·算法·pat考试·pat
丢掉幻想准备斗争2 小时前
5.5树与二叉树的应用
算法
ZhouDevin3 小时前
算法论文/模型微调2——仅骨干1%~3% 参数达到与全量微调相当的性能
算法
Sinosecu-OCR3 小时前
文通OCR技术深度解析:自研算法如何搞定复杂场景识别?
算法·ocr·ocr识别系统
鬼手点金3 小时前
机器学习、深度学习、强化学习、神经网络、自注意力机制
人工智能·深度学习·神经网络·机器学习·skill·vibecoding·opencode
张继雁3 小时前
夏季切削液发臭不用瞎换液
论文阅读·机器学习·创业创新·学习方法·业界资讯·远程工作
CQU_JIAKE3 小时前
8.5【A】
数据结构·算法