欢迎光临
我们一直在努力

DBSCAN 参数选择方法与离群值检测

目录

  • 一、DBSCAN 参数
  • 二、参数选择方法
    • 2.1 MinPts 的经验选取
    • 2.2 Eps 的选取 —— K-Distance(k-距离)图法
  • 三、Python 实现:参数选择与离群值检测
    • 3.1 导包与生成示例数据
    • 3.2 绘制 K-Distance 图确定 Eps
    • 3.3 执行 DBSCAN 聚类与离群值检测
    • 3.4 可视化聚类与离群值
  • 四、关键注意事项与调参建议
  • 五、小结
  • 六、参考链接

一、DBSCAN 参数

参数含义说明
Eps(ε) 邻域半径 若两点距离 ≤ Eps,则认为互为邻域
MinPts 核心点最少样本数 某点的 Eps 邻域内至少含 MinPts 个点(含自身),才被标记为核心点
  • 核心点(Core Point):Eps 邻域内样本数 ≥ MinPts
  • 边界点(Border Point):落在某核心点的 Eps 邻域内,但自身不满足 MinPts
  • 噪声点(Noise / Outlier):既非核心点也非边界点,DBSCAN 标记为 -1

二、参数选择方法

2.1 MinPts 的经验选取

推荐经验公式:

MinPts = D + 1 (D 为数据特征维度)

更保守的做法是取:

MinPts = 2 × D – 1

  • 二维数据(D=2):MinPts 常取 3~5,常用 MinPts = 4
  • 噪声较多或数据量较大时,可适当增大 MinPts 以减少假簇

注意:k-distance 图中的 k = MinPts – 1


2.2 Eps 的选取 —— K-Distance(k-距离)图法

步骤:

  • 取 k = MinPts – 1
  • 对数据集中每个点,计算其到第 k 个最近邻的距离(跳过自身)
  • 将所有点的 k-distance 从大到小排序
  • 绘制 k-distance 曲线,寻找明显拐点(Elbow / Knee)
  • 拐点对应的纵坐标即为推荐的 Eps
  • 原理: 拐点之前是密集区域的点,之后是稀疏或孤立点。拐点距离反映了"正常密度区域的最大合理邻域半径"。


    三、Python 实现:参数选择与离群值检测

    3.1 导包与生成示例数据

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.cluster import DBSCAN
    from sklearn.neighbors import NearestNeighbors
    from sklearn.preprocessing import StandardScaler
    from sklearn.datasets import make_moons

    # 固定随机种子,保证可复现
    np.random.seed(2021)

    # 生成半月形非线性数据(含一定噪声)
    X, y_true = make_moons(n_samples=400, noise=0.07, random_state=42)

    # DBSCAN 对量纲敏感,务必标准化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)


    3.2 绘制 K-Distance 图确定 Eps

    def plot_k_distance(X, k, figsize=(8, 5)):
    """
    绘制 k-distance 图辅助选择 DBSCAN 的 eps

    Parameters:
    X: 标准化后的特征矩阵
    k: 取 MinPts – 1(即计算第 k 近邻距离)
    """
    nbrs = NearestNeighbors(n_neighbors=k + 1, algorithm='auto').fit(X)
    distances, _ = nbrs.kneighbors(X)

    # 第 k 列 = 第 k 近邻距离(第 0 列是自身)
    k_dist = np.sort(distances[:, k])[::1]

    plt.figure(figsize=figsize)
    plt.plot(k_dist)
    plt.xlabel("Points sorted by distance (descending)")
    plt.ylabel(f"{k}-distance (distance to {k}th NN)")
    plt.title("K-Distance Graph — Select Eps at the 'Elbow'")
    plt.grid(alpha=0.4)
    plt.show()

    return k_dist

    # 二维数据:MinPts 建议取 4 → k = MinPts – 1 = 3
    k = 3
    k_dist = plot_k_distance(X_scaled, k=k)

    在这里插入图片描述

    📌 观察图中拐点位置,出现在约 0.25,则取 eps=0.25。


    3.3 执行 DBSCAN 聚类与离群值检测

    # 根据 k-distance 图选定的参数
    eps = 0.25
    min_samples = k + 1 # = 4

    dbscan = DBSCAN(
    eps=eps,
    min_samples=min_samples,
    metric='euclidean',
    algorithm='auto'
    )

    labels = dbscan.fit_predict(X_scaled)

    # 离群值标记:label == -1
    is_outlier = labels == 1
    n_clusters = len(set(labels)) (1 if 1 in labels else 0)
    n_outliers = np.sum(is_outlier)

    print(f"发现的簇数: {n_clusters}")
    print(f"检测到的离群值数量: {n_outliers}")
    print(f"核心样本数: {len(dbscan.core_sample_indices_)}")


    3.4 可视化聚类与离群值

    plt.figure(figsize=(8, 6))

    # 正常点按簇上色,离群值用红色 × 标记
    unique_labels = np.unique(labels)
    colors = plt.cm.viridis(np.linspace(0, 1, len(unique_labels)))

    for label, color in zip(unique_labels, colors):
    mask = labels == label
    if label == 1:
    # 噪声点 / 离群值
    plt.scatter(
    X_scaled[mask, 0], X_scaled[mask, 1],
    c='red', marker='x', s=50,
    label=f'Outlier ({np.sum(mask)})'
    )
    else:
    plt.scatter(
    X_scaled[mask, 0], X_scaled[mask, 1],
    c=[color], s=30,
    label=f'Cluster {label}'
    )

    plt.title(f"DBSCAN Outlier Detection (eps={eps}, MinPts={min_samples})")
    plt.xlabel("Feature 1 (standardized)")
    plt.ylabel("Feature 2 (standardized)")
    plt.legend(loc='best', fontsize=9)
    plt.grid(alpha=0.3)
    plt.show()


    在这里插入图片描述

    四、关键注意事项与调参建议

  • 必须先做特征标准化(StandardScaler),否则距离受量纲主导导致 Eps 无意义
  • MinPts 太小 → 对噪声敏感,易将稀疏区域误判为核心点;太大 → 忽略小簇
  • Eps 太大 → 不同簇被合并为一;太小 → 几乎所有点被判为噪声
  • 高维数据可用 PCA 先降维再使用 DBSCAN,或用 HDBSCAN 缓解密度不均问题
  • 若拐点不明显,可参考 k-distance 的 90%~95% 分位数 作为 Eps 初值
  • 五、小结

    • MinPts 按维度经验取 D+1 或 2D-1
    • Eps 通过 k-distance(k = MinPts – 1)图的拐点确定
    • DBSCAN 中 label == -1 即为检测到的离群值/异常点
    • sklearn 的 NearestNeighbors + DBSCAN 即可完整覆盖参数选择 → 聚类 → 异常检测的流程

    六、参考链接

    机器学习 聚类篇——DBSCAN的参数选择及其应用于离群值检测

    赞(0)
    未经允许不得转载:171主机测评 » DBSCAN 参数选择方法与离群值检测
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址