机器学习入门:DBSCAN 聚类 机器学习入门DBSCAN 聚类前言本文是“机器学习入门”系列的第九站。上一站我们学习了 K-Means 聚类它通过 K 个质心将数据划分成球形簇但需要预先指定 K 值且只能发现凸形簇。本篇我们将学习另一种完全不同的聚类算法——DBSCAN。它不需要指定簇的数量能发现任意形状的簇还能自动识别噪声点。其核心思想是将密度足够高的区域划分为簇低密度区域的点则标记为噪声。目录一、认识 DBSCAN 聚类二、DBSCAN 的核心原理三、DBSCAN vs K-Means四、DBSCAN 的优缺点五、典型应用场景六、核心 API 速查七、实战案例啤酒聚类分析八、总结一、认识 DBSCAN 聚类1.1 什么是 DBSCANDBSCANDensity-Based Spatial Clustering of Applications with Noise是一种基于密度的无监督聚类算法。它的核心特点是能根据数据的密度分布自动发现任意形状的簇同时还能识别出数据中的噪声点。通俗理解想象你在地图上标注了一堆地点。DBSCAN 要做的事情是找到那些“邻居特别多”的核心区域从这些区域向外扩散把所有能连通的密集区域圈成一个簇。而那些孤零零的、周围没什么邻居的点就被标记为“噪声”。DBSCAN 用于聚类。它不依赖标签仅凭数据本身的密度分布进行分组。1.2 为什么要用 DBSCANK-Means 有两个明显的局限必须预先指定 K 值在无监督学习中我们往往不知道数据应该分成几类。只能发现凸形簇对于环形、S 形等非凸形状的数据K-Means 效果很差。DBSCAN 正是为了解决这两个问题而生的。二、DBSCAN 的核心原理2.1 两个核心参数DBSCAN 通过两个参数来定义“密度”参数含义说明εeps邻域半径判断“邻居”的距离阈值。两个样本距离小于 ε 时认为是邻居min_samplesMinPts最小样本数判断“核心点”的密度阈值。某点 ε 邻域内至少有 min_samples 个样本时该点才被视为核心点2.2 三类样本点基于这两个参数DBSCAN 将样本点分为三类类型定义核心点Core Pointε 邻域内样本数 ≥ min_samples 的点边界点Border Pointε 邻域内样本数 min_samples但落在某个核心点的 ε 邻域内的点噪声点Noise Point既不是核心点也不是边界点的点标签为 -12.3 簇的定义与连接DBSCAN 的簇由密度相连的核心点及其边界点组成直接密度可达点 q 在核心点 p 的 ε 邻域内则 q 从 p 直接密度可达密度可达通过一串核心点从 p 可以“接力”到达 q则 q 从 p 密度可达密度相连存在点 o使得 p 和 q 都从 o 密度可达则 p 和 q 密度相连一个簇就是所有密度相连的点的最大集合。通俗理解核心点就像“感染源”它会把 ε 邻域内的所有点拉入同一个簇。如果这个簇里有其他核心点它们又会继续向外“感染”更多的点。直到遇到“边界点”或“噪声点”传播才停止。2.4 算法流程随机选择一个未访问的数据点检查该点的 ε 邻域如果邻域内点数 ≥ min_samples标记为核心点邻域内所有点加入同一簇否则标记为噪声但之后如果被核心点纳入邻域可能转为边界点对簇内的核心点递归扩展其邻域将更多点加入簇重复 1-3 步直到所有点都被访问三、DBSCAN vs K-Means对比维度K-MeansDBSCAN是否需指定 K是必须预先指定否自动发现簇簇的形状只能发现凸形球形簇可发现任意形状的簇噪声处理所有点都被分配无噪声概念自动识别噪声点标签 -1参数依赖主要依赖 K 值依赖 eps 和 min_samples较敏感密度差异对密度差异不敏感对密度差异大的数据表现不佳四、DBSCAN 的优缺点4.1 优点无需预设簇数量自动根据密度划分簇支持任意形状的簇可识别环形、S 形、不规则形状的簇能识别噪声点天然支持离群点检测对数据顺序不敏感聚类结果稳定4.2 缺点对参数 eps 和 min_samples 敏感参数选择不当会导致聚类结果差异极大不适合密度差异大的数据同一套参数无法同时适配高密度和低密度区域高维数据效果差高维空间中“距离”概念失效需先降维大规模数据效率较低传统实现时间复杂度为 O(n²)五、典型应用场景图像分割将图片中的不同区域如森林、湖泊分割成不同的簇社交网络分析识别不同的用户群体或社区异常检测远离所有簇的样本点可能是异常点地理空间数据GPS 轨迹聚类、犯罪热点分析文本挖掘将相似文档归为一组六、核心 API 速查6.1 导包方式fromsklearn.clusterimportDBSCAN6.2 核心参数详解参数名类型默认值说明epsfloat0.5邻域半径。最重要的参数决定邻居的距离阈值。eps 过大会合并不同的簇过小会拆分同一个簇min_samplesint5核心点密度阈值。eps 一定时min_samples 过大会导致核心点过少噪声增多过小会产生大量核心点簇数减少metricstreuclidean距离度量方式。常用euclidean欧氏距离、manhattan曼哈顿距离algorithmstrauto近邻搜索算法。auto自动选择kd_tree、ball_tree、bruteleaf_sizeint30KD树或球树的叶子节点大小影响建树和查询速度6.3 常用属性属性名说明core_sample_indices_核心点的索引components_所有核心点的坐标labels_每个样本的簇标签-1 表示噪声点6.4 常用方法方法名说明fit(X)训练模型fit_predict(X)训练并返回每个样本的簇标签噪声点为 -1七、实战案例啤酒聚类分析7.1 案例背景在 K-Means 篇中我们将 20 种啤酒按热量、钠含量、酒精浓度、价格聚成了 4 类。本篇尝试用 DBSCAN 对同样的数据进行分析对比两种算法的聚类结果。7.2 数据说明字段含义单位calories热量卡路里sodium钠含量毫克alcohol酒精浓度体积百分比cost价格美元数据示例品牌热量钠含量酒精浓度价格Budweiser144154.70.43Schlitz151194.90.43Lowenbrau157150.90.48Kronenbourg17075.20.73Heineken152115.00.777.3 完整代码importpandasaspdimportnumpyasnpfromsklearn.clusterimportDBSCANfromsklearn.preprocessingimportMinMaxScalerfromsklearn.metricsimportsilhouette_scoreimportmatplotlib.pyplotasplt# 设置中文字体plt.rcParams[font.sans-serif][SimHei]plt.rcParams[axes.unicode_minus]False# 读取数据beerpd.read_table(data.txt,sep ,encodingutf-8,enginepython)Xbeer[[calories,sodium,alcohol,cost]]# 01标准化scalerMinMaxScaler()X_scaledscaler.fit_transform(X)# 网格搜索eps_valuesnp.arange(0.1,1.0,0.1)# 邻域半径候选值min_samples_valuesrange(2,7)# 最小样本数候选值results[]print( 网格搜索 )forepsineps_values:formin_samplesinmin_samples_values:labelsDBSCAN(epseps,min_samplesmin_samples).fit_predict(X_scaled)n_clusterslen(set(labels))-(1if-1inlabelselse0)# 簇数排除噪声n_noiselist(labels).count(-1)# 噪声点数ifn_clusters2:# 至少2个簇才能计算轮廓系数scoresilhouette_score(X_scaled,labels)results.append({eps:eps,min_samples:min_samples,n_clusters:n_clusters,n_noise:n_noise,score:score})print(feps{eps:.1f}, min_samples{min_samples}: 簇数{n_clusters}, 噪声{n_noise}, 轮廓系数{score:.4f})# 最优参数ifresults:bestmax(results,keylambdax:x[score])# 选轮廓系数最大的print(f\n最优参数: eps{best[eps]:.1f}, min_samples{best[min_samples]})print(f最优轮廓系数:{best[score]:.4f})best_labelsDBSCAN(epsbest[eps],min_samplesbest[min_samples]).fit_predict(X_scaled)beer[cluster]best_labelsprint(f\n簇数:{best[n_clusters]})print(f噪声点:{best[n_noise]})print(\n各簇包含的品牌)forcidinsorted(beer[cluster].unique()):brandsbeer[beer[cluster]cid][name].tolist()ifcid-1:print(f噪声点:{, .join(brands)})else:print(f簇{cid}{len(brands)}种:{, .join(brands)})else:print(\n未找到有效的聚类组合) 网格搜索 eps0.2, min_samples2: 簇数3, 噪声12, 轮廓系数0.0281 eps0.3, min_samples2: 簇数3, 噪声6, 轮廓系数0.2266 eps0.3, min_samples3: 簇数3, 噪声6, 轮廓系数0.2266 eps0.3, min_samples4: 簇数2, 噪声9, 轮廓系数0.1283 eps0.4, min_samples2: 簇数2, 噪声2, 轮廓系数0.3162 eps0.4, min_samples3: 簇数2, 噪声2, 轮廓系数0.3162 eps0.4, min_samples4: 簇数2, 噪声2, 轮廓系数0.3162 eps0.5, min_samples2: 簇数2, 噪声1, 轮廓系数0.3435 eps0.5, min_samples3: 簇数2, 噪声1, 轮廓系数0.3435 eps0.5, min_samples4: 簇数2, 噪声1, 轮廓系数0.3435 最优参数: eps0.5, min_samples2 最优轮廓系数: 0.3435 簇数: 2 噪声点: 1 各簇包含的品牌 噪声点: Lowenbrau 簇 015 种: Budweiser, Schlitz, Old_Milwaukee, Augsberger, Srohs_Bohemian_Style, Miller_Lite, Budweiser_Light, Coors, Coors_Light, Michelob_Light, Pabst_Extra_Light, Hamms, Heilemans_Old_Style, Olympia_Goled_Light, Schlitz_Light 簇 14 种: Kronenbourg, Heineken, Becks, Kirin7.4 关键步骤说明步骤说明数据标准化DBSCAN 基于距离计算特征尺度不同会影响结果需先标准化参数探索尝试不同的 eps 值观察簇数和噪声点的变化选择合适参数DBSCAN 聚类使用最优 eps 和 min_samples 进行聚类八、总结核心知识点速查知识点关键概念DBSCAN基于密度的聚类发现任意形状的簇核心点ε 邻域内样本数 ≥ min_samples边界点邻域内样本不足但落在核心点的邻域内噪声点既非核心点也非边界点标签 -1eps邻域半径最关键参数min_samples核心点的密度阈值核心 API 一览用途对应模块 / 方法模型sklearn.cluster.DBSCAN训练并返回标签fit_predict(X)核心点索引core_sample_indices_簇标签-1 为噪声labels_轮廓系数sklearn.metrics.silhouette_score注意事项要点说明特征必须标准化DBSCAN 基于距离特征尺度不同会严重影响结果eps 选择过小簇被拆分噪声增多过大簇被合并min_samples 选择通常设为维度 1如二维数据设 3密度差异大同一套参数无法适配高密度和低密度区域系列直达上篇机器学习入门K-Means 聚类本篇机器学习入门DBSCAN 聚类本文下篇敬请期待