在数据分析中,什么是聚类分析?常见的聚类算法有哪些?

发布时间:2026/7/1 20:33:05
在数据分析中,什么是聚类分析?常见的聚类算法有哪些? 聚类分析概念与常见算法一、什么是聚类分析聚类分析是一种无监督学习方法将数据样本按相似性自动分组——同组内尽量相似不同组间尽量不同。与分类不同聚类没有预定义的标签分组完全由数据自身结构决定。原始数据无标签 聚类结果 · · · · · · ① ② · · · → ① ② ② · · ② ② · · ① ② · · ① ② 目标组内高相似 组间高差异核心概念概念含义簇Cluster聚类产生的一个组簇内距离同一簇内样本间的距离越小越好簇间距离不同簇之间的距离越大越好相似度度量衡量样本像不像的规则距离/相似系数二、常见距离度量距离的选择直接影响聚类结果需根据数据特点选用。距离公式特点适用场景欧氏距离直线距离最常用连续变量、量纲一致曼哈顿距离城市街区距离稀疏数据、异常值多余弦相似度方向而非大小文本向量、高维稀疏汉明距离不同维度数分类/二值变量fromscipy.spatial.distanceimportpdist,squareform# 欧氏距离矩阵dist_matrixsquareform(pdist(X,metriceuclidean))# 余弦距离cos_distsquareform(pdist(X,metriccosine))三、常见聚类算法总览对比算法核心思想簇形状需指定K速度典型场景K-Means最小化簇内距离球形是快均匀球形簇K-Medoids以真实样本为中心球形是中有异常值层次聚类逐步合并/分裂任意否慢小样本、需树状图DBSCAN密度连通任意形状否中任意形状、含噪声GMM概率混合模型椭球形是中概率归属、重叠簇谱聚类图分割任意形状是慢非凸簇、图数据1. K-Means — 最经典思想将 n 个样本分成 K 个簇使每个样本到所属簇中心的距离之和最小。算法流程 1. 随机选 K 个初始中心点 2. 将每个样本分配到最近的中心 → 形成K个簇 3. 重新计算每个簇的中心均值 4. 重复步骤 2-3 直到收敛fromsklearn.clusterimportKMeans kmeansKMeans(n_clusters3,n_init10,random_state42)labelskmeans.fit_predict(X)# 簇中心centerskmeans.cluster_centers_# 每个样本到最近中心的距离惯性inertiakmeans.inertia_如何确定 K# 方法一肘部法则Elbow Methodinertias[]K_rangerange(2,11)forkinK_range:kmKMeans(n_clustersk,n_init10,random_state42)km.fit(X)inertias.append(km.inertia_)plt.plot(K_range,inertias,bo-)plt.xlabel(K)plt.ylabel(Inertia)plt.title(Elbow Method)plt.show()# 拐点处即为最优 K# 方法二轮廓系数Silhouette Score— 更可靠fromsklearn.metricsimportsilhouette_score scores[]forkinK_range:kmKMeans(n_clustersk,n_init10,random_state42)labelskm.fit_predict(X)scores.append(silhouette_score(X,labels))plt.plot(K_range,scores,ro-)plt.xlabel(K)plt.ylabel(Silhouette Score)plt.show()# 分数最高处即为最优 K优点简单快速大规模数据适用缺点只能发现球形簇对初始中心敏感用n_init10缓解对异常值敏感必须预先指定 K2. K-Medoids — 鲁棒版 K-Means中心点是真实存在的一个样本而非均值对异常值更鲁棒。# pip install scikit-learn-extrafromsklearn_extra.clusterimportKMedoids kmedoidsKMedoids(n_clusters3,random_state42)labelskmedoids.fit_predict(X)3. 层次聚类 — 树状结构不需要预设 K生成一棵树在任意高度切割即可得到不同数量的簇。凝聚式自底向上 每个样本自成一簇 → 合并最近的两簇 → 重复直到只剩一簇 分裂式自顶向下 全部样本一簇 → 分裂最不均匀的簇 → 重复直到每簇一个样本fromsklearn.clusterimportAgglomerativeClusteringfromscipy.cluster.hierarchyimportdendrogram,linkage# 树状图 — 确定最优簇数Zlinkage(X,methodward)# ward/complete/average/singleplt.figure(figsize(12,5))dendrogram(Z)plt.axhline(yZ[-3,2],colorr,ls--)# 切3类plt.show()# 聚类hcAgglomerativeClustering(n_clusters3,linkageward)labelshc.fit_predict(X)** linkage 方法选择**方法合并策略特点Ward合并后总方差增量最小倾向球形簇最常用Complete两簇最远样本距离最小倾向紧凑簇Average两簇所有样本平均距离最小折中Single两簇最近样本距离最小倾向链状可能拉长优点不需预设K、树状图可解释、任意形状缺点O(n³) 复杂度大规模数据不可用4. DBSCAN — 发现任意形状的簇基于密度的聚类在密集区域连成一片即为一个簇稀疏区域标记为噪声。核心概念 - ε (eps)邻域半径 - MinPts邻域内最少点数 一个点如果 ε 邻域内 ≥ MinPts 个点 → 核心点 核心点之间可以通过密集区域连起来 → 形成一个簇 既不是核心点也不在核心点邻域内 → 噪声点-1 标签fromsklearn.clusterimportDBSCAN dbscanDBSCAN(eps0.5,min_samples5)labelsdbscan.fit_predict(X)# -1 表示噪声点n_clusterslen(set(labels)-{-1})n_noise(labels-1).sum()print(f发现{n_clusters}个簇{n_noise}个噪声点)如何调 eps# K-distance 图法fromsklearn.neighborsimportNearestNeighbors nnNearestNeighbors(n_neighbors5)nn.fit(X)distances,_nn.kneighbors(X)k_distnp.sort(distances[:,-1])plt.plot(k_dist)plt.ylabel(5-NN Distance)plt.xlabel(Points (sorted))plt.show()# 拐点处即为合适的 eps优点不需预设簇数能发现任意形状的簇自动识别噪声/异常点缺点对 eps 和 MinPts 敏感密度差异大的簇效果差高维数据距离失效维度灾难5. GMM — 概率软聚类假设数据由多个高斯分布混合生成每个样本属于各簇的概率不同软聚类。fromsklearn.mixtureimportGaussianMixture gmmGaussianMixture(n_components3,random_state42)labelsgmm.fit_predict(X)# 软聚类每个样本属于各簇的概率probsgmm.predict_proba(X)print(probs[:5])# 如 [0.02, 0.95, 0.03]# 用 BIC 选 Kbics[]forkinrange(2,11):gmGaussianMixture(n_componentsk,random_state42)gm.fit(X)bics.append(gm.bic(X))plt.plot(range(2,11),bics)plt.xlabel(K)plt.ylabel(BIC)plt.show()# BIC 最低处为最优 K优点软聚类概率归属、能捕捉椭球形簇缺点假设高斯分布、可能收敛到局部最优6. 谱聚类 — 处理非凸簇将数据构建为图通过图拉普拉斯矩阵的特征值分解来分割。fromsklearn.clusterimportSpectralClustering scSpectralClustering(n_clusters3,affinityrbf,random_state42)labelssc.fit_predict(X)优点能处理非凸形状如两个同心圆环缺点计算量大不适合大规模数据四、聚类评估指标由于没有真实标签无监督评估依赖内部指标。指标衡量什么越好范围轮廓系数簇内紧密度 vs 簇间分离度↑-1 ~ 1Calinski-Harabasz簇间方差 / 簇内方差↑0 ~ ∞Davies-Bouldin簇内散度 / 簇间距离↓0 ~ ∞fromsklearn.metricsimportsilhouette_score,calinski_harabasz_score,davies_bouldin_score labelskm.fit_predict(X)silsilhouette_score(X,labels)# 越大越好chcalinski_harabasz_score(X,labels)# 越大越好dbdavies_bouldin_score(X,labels)# 越小越好print(f轮廓系数:{sil:.4f})print(fCH指数:{ch:.2f})print(fDB指数:{db:.4f})轮廓系数解读 0.7 强结构聚类效果好 0.5~0.7 合理结构 0.25~0.5 弱结构可能不是最佳聚类 0.25 无明显结构簇不显著五、算法选择指南数据特征 → 推荐算法 簇形状规则 / 大数据量 / 需要快速 → K-Means 存在异常值 / 中心需为真实样本 → K-Medoids 需要树状结构 / 可解释性 / 小样本 → 层次聚类 簇形状不规则 / 有噪声 → DBSCAN 需要概率归属 / 簇有重叠 → GMM 非凸形状如同心圆/月牙形 → 谱聚类 / DBSCAN 高维稀疏数据文本等 → 先降维 → 再 K-Means / 谱聚类六、实战对比不同算法fromsklearn.datasetsimportmake_moons,make_blobsfromsklearn.clusterimportKMeans,DBSCAN,SpectralClusteringfromsklearn.mixtureimportGaussianMixturefromsklearn.preprocessingimportStandardScalerfromsklearn.metricsimportsilhouette_score# 生成非凸数据月牙形X,_make_moons(n_samples500,noise0.05,random_state42)XStandardScaler().fit_transform(X)algorithms{K-Means:KMeans(n_clusters2,n_init10,random_state42),DBSCAN:DBSCAN(eps0.3,min_samples5),GMM:GaussianMixture(n_components2,random_state42),Spectral:SpectralClustering(n_clusters2,affinityrbf),}fig,axesplt.subplots(1,4,figsize(20,5))forax,(name,algo)inzip(axes,algorithms.items()):labelsalgo.fit_predict(X)scatterax.scatter(X[:,0],X[:,1],clabels,cmapviridis,s10)nlen(set(labels)-{-1})silsilhouette_score(X,labels)ifn2else-1ax.set_title(f{name}\nclusters{n}, sil{sil:.3f})plt.tight_layout()plt.show()# 结果K-Means 和 GMM 把月牙切成两半错误# DBSCAN 和谱聚类正确识别两个月牙速查总结聚类分析四步法 1. 选距离连续→欧氏稀疏→余弦分类→汉明 2. 选算法 球形均匀 → K-Means 任意形状 → DBSCAN 需要树状图 → 层次聚类 需要概率 → GMM 非凸形状 → 谱聚类 3. 定簇数肘部法则 / 轮廓系数 / BIC 4. 评估轮廓系数 CH指数 DB指数 一句话K-Means是默认起点 形状不规则用DBSCAN 需要解释用层次聚类 评估靠轮廓系数。