Python-sklearn-聚类
Sklearn 聚类算法
sklearn.cluster提供 K-Means、层次聚类、DBSCAN、GMM 等经典聚类算法。
🎯 基于划分的聚类
1.KMeans— K 均值聚类 ⭐
fromsklearn.clusterimportKMeans model=KMeans(n_clusters=8,# 簇的数量init='k-means++',# 'k-means++' 或 'random' 或 ndarrayn_init='auto',# 初始化运行次数('auto'=1 次,int=多次取最优)max_iter=300,# 单次运行的最大迭代次数tol=1e-4,# 收敛容忍度verbose=0,random_state=42,copy_x=True,algorithm='lloyd'# 'lloyd','elkan'(密集数据快),'full','auto')model.fit(X)# 核心属性print(model.cluster_centers_)# 簇中心 (n_clusters, n_features)print(model.labels_)# 每个样本的簇标签print(model.inertia_)# 样本到最近簇中心的平方距离之和 ⭐print(model.n_iter_)# 迭代次数print(model.n_features_in_)# 特征数# 预测新样本labels=model.predict(X_new)# 将新样本分配到最近簇# 变换(到各簇中心的距离)distances=model.transform(X)# (n_samples, n_clusters) → 可以用作降维特征# 一步到位labels=model.fit_predict(X)2.MiniBatchKMeans— 小批量 K 均值
fromsklearn.clusterimportMiniBatchKMeans model=MiniBatchKMeans(n_clusters=8,init='k-means++',max_iter=100,batch_size=1024,# 每批样本数verbose=0,random_state=42,tol=0.0,max_no_improvement=10,# 连续无改善轮数init_size=None,# 初始化的样本数n_init=3,reassignment_ratio=0.01# 重新分配中心的比例)model.fit(X)# 支持 partial_fit(在线学习)model.partial_fit(X_batch)📊 基于密度的聚类
1.DBSCAN— 密度聚类 ⭐
fromsklearn.clusterimportDBSCAN model=DBSCAN(eps=0.5,# 邻域半径min_samples=5,# 核心点所需的最小邻域点数metric='euclidean',# 距离度量metric_params=None,algorithm='auto',# 'auto','ball_tree','kd_tree','brute'leaf_size=30,# BallTree/KDTree 的叶大小p=None,# Minkowski 度量的幂参数n_jobs=None)model.fit(X)# 核心属性print(model.labels_)# -1=噪音, >=0=簇标签print(model.core_sample_indices_)# 核心样本的索引print(model.components_)# 每个核心样本的副本# 注意: DBSCAN 没有 predict 方法!# 对新数据需使用训练后的 dbscan 作为 nearest neighbors 查询调参指南:
fromsklearn.neighborsimportNearestNeighborsimportnumpyasnpimportmatplotlib.pyplotasplt# K-距离图选择合适的 epsk=5# 一般取 min_samples 值nbrs=NearestNeighbors(n_neighbors=k).fit(X)distances,indices=nbrs.kneighbors(X)k_dist=np.sort(distances[:,-1])plt.plot(k_dist)plt.xlabel('Points sorted by distance')plt.ylabel(f'{k}-NN distance')plt.title('K-distance Graph (elbow method)')plt.show()# 曲线的"肘部"即为合适的 eps2.OPTICS— 排序点识别聚类结构
fromsklearn.clusterimportOPTICS model=OPTICS(min_samples=5,max_eps=np.inf,# 最大邻域半径metric='minkowski',p=2,cluster_method='xi',# 'xi' 或 'dbscan'eps=None,# 提取簇的阈值(cluster_method='dbscan' 时需要)xi=0.05,# 最小陡度(cluster_method='xi' 时)predecessor_correction=True,min_cluster_size=None,# 最小簇大小algorithm='auto',leaf_size=30,n_jobs=None)model.fit(X)print(model.labels_)# 簇标签(-1=噪音)print(model.reachability_)# 可达距离print(model.ordering_)# 簇排序print(model.core_distances_)# 核心距离print(model.predecessor_)# 前驱索引3.HDBSCAN— 层次 DBSCAN
fromsklearn.clusterimportHDBSCAN model=HDBSCAN(min_cluster_size=5,# 最小簇大小min_samples=None,# 保守性(越大越保守)cluster_selection_epsilon=0.0,max_cluster_size=None,# 最大簇大小metric='euclidean',alpha=1.0,# 距离持久性algorithm='auto',leaf_size=40,n_jobs=None,cluster_selection_method='eom',# 'eom'(Excess of Mass) 或 'leaf'allow_single_cluster=False,store_centers=None)model.fit(X)print(model.labels_)print(model.probabilities_)# 每个样本的簇成员强度 (0~1)print(model.cluster_persistence_)# 每个簇的持久性分数# HDBSCAN 特有的方法soft_clusters=model.membership_vector()# 软聚类向量🏗️ 基于层次的聚类
1.AgglomerativeClustering— 凝聚层次聚类 ⭐
fromsklearn.clusterimportAgglomerativeClustering model=AgglomerativeClustering(n_clusters=2,# 目标簇数metric='euclidean',# 距离度量linkage='ward',# 链接准则# 'ward' — 最小方差(仅 euclidean)# 'complete' — 最大距离(最远邻)# 'average' — 平均距离# 'single' — 最小距离(最近邻)connectivity=None,# 连接性约束矩阵compute_distances=False,# 存储距离矩阵distance_threshold=None,# 距离阈值(代替 n_clusters))model.fit(X)print(model.labels_)print(model.n_clusters_)# 估计的簇数print(model.n_leaves_)# 树的叶节点数print(model.children_)# 每个合并步骤的子节点 (2, n_samples-1)print(model.distances_)# 每个合并步骤的距离(compute_distances=True)使用距离阈值而非指定 K:
model=AgglomerativeClustering(n_clusters=None,distance_threshold=0,# 设置为 0 会计算全树linkage='ward')model.fit(X)2.FeatureAgglomeration— 特征凝聚
fromsklearn.clusterimportFeatureAgglomeration model=FeatureAgglomeration(n_clusters=2,metric='euclidean',linkage='ward',pooling_func=np.mean# 合并后特征的聚合函数)X_reduced=model.fit_transform(X)print(model.labels_)# 每个原始特征的簇标签3.Birch— 层次聚类(大数据友好)
fromsklearn.clusterimportBirch model=Birch(threshold=0.5,# 子簇合并阈值branching_factor=50,# 每个节点的最大 CF 子簇数n_clusters=3,# 最终簇数compute_labels=True,copy=True)model.fit(X)print(model.labels_)print(model.root_)# 内部树的根节点print(model.subcluster_centers_)# 子簇中心# 支持 partial_fitmodel.partial_fit(X_batch)🎲 基于模型的聚类
GaussianMixture— 高斯混合模型(GMM)
fromsklearn.mixtureimportGaussianMixture model=GaussianMixture(n_components=1,# 混合成分数covariance_type='full',# 'full','tied','diag','spherical'tol=1e-3,reg_covar=1e-6,# 协方差对角线上加的正则化max_iter=100,n_init=1,# 初始化次数init_params='kmeans',# 'kmeans','k-means++','random','random_from_data'weights_init=None,means_init=None,precisions_init=None,random_state=None,warm_start=False,verbose=0,verbose_interval=10)model.fit(X)# 关键属性print(model.weights_)# 各成分的混合权重print(model.means_)# 各成分的均值print(model.covariances_)# 各成分的协方差print(model.precisions_)# 各成分的精度矩阵(协方差逆)print(model.precisions_cholesky_)# 精度矩阵的 Cholesky 分解print(model.converged_)# 是否收敛print(model.n_iter_)# 实际迭代数print(model.lower_bound_)# 对数似然的下界# 预测方法labels=model.predict(X)# 硬分配probs=model.predict_proba(X)# 软分配(后验概率)log_likelihood=model.score(X)# 每个样本的对数似然total_ll=model.score_samples(X)# 加权对数似然# 采样X_sampled,y_sampled=model.sample(n_samples=100)# AIC / BIC(模型选择)print(model.aic(X))print(model.bic(X))GMM 模型选择:
importnumpyasnp n_components=range(1,11)models=[GaussianMixture(n,random_state=42).fit(X)forninn_components]bics=[m.bic(X)forminmodels]aics=[m.aic(X)forminmodels]best_n=n_components[np.argmin(bics)]print(f"Best n_components (BIC):{best_n}")BayesianGaussianMixture— 贝叶斯 GMM
fromsklearn.mixtureimportBayesianGaussianMixture model=BayesianGaussianMixture(n_components=10,# 设置足够大的初始值covariance_type='full',tol=1e-3,reg_covar=1e-6,max_iter=1000,n_init=1,init_params='kmeans',weight_concentration_prior_type='dirichlet_process',# 'dirichlet_process' — 自动推断成分数# 'dirichlet_distribution' — 固定成分数weight_concentration_prior=None,# Dirichlet 先验浓度mean_precision_prior=None,mean_prior=None,degrees_of_freedom_prior=None,covariance_prior=None,random_state=None,warm_start=False,verbose=0)model.fit(X)print(model.weights_)# 部分权重接近 0(自动选择成分数)print(model.n_components)# 原始设定的成分数# 实际有效的成分数effective_n=np.sum(model.weights_>0.01)print(f"Effective components:{effective_n}")📈 其他聚类算法
1.MeanShift— 均值漂移
fromsklearn.clusterimportMeanShift model=MeanShift(bandwidth=None,# 带宽(None 用 estimate_bandwidth 估计)seeds=None,# 初始核位置bin_seeding=False,# 使用离散化加速min_bin_freq=1,cluster_all=True,# 是否将所有点分配给簇(False 时孤立点为 -1)n_jobs=None,max_iter=300)model.fit(X)print(model.cluster_centers_)print(model.labels_)print(model.n_iter_)# 带宽估计fromsklearn.clusterimportestimate_bandwidth bandwidth=estimate_bandwidth(X,quantile=0.3,n_samples=500,random_state=42)2.AffinityPropagation— 近邻传播
fromsklearn.clusterimportAffinityPropagation model=AffinityPropagation(damping=0.5,# 阻尼因子 (0.5~1)max_iter=200,convergence_iter=15,# 连续迭代无变化判定收敛copy=True,preference=None,# 优先度(None=相似度中值)affinity='euclidean',# 或 'precomputed'verbose=False,random_state=None)model.fit(X)print(model.cluster_centers_indices_)# 簇中心在原数据中的索引print(model.labels_)print(model.affinity_matrix_)# 相似度矩阵print(model.n_iter_)3.SpectralClustering— 谱聚类
fromsklearn.clusterimportSpectralClustering model=SpectralClustering(n_clusters=8,eigen_solver=None,# None,'arpack','lobpcg','amg'n_components=None,# 谱嵌入维度random_state=42,n_init=10,# k-means 运行次数gamma=1.0,# RBF 核参数affinity='rbf',# 'rbf','nearest_neighbors','precomputed',callablen_neighbors=10,# nearest_neighbors affinity 的邻居数eigen_tol='auto',assign_labels='kmeans',# 'kmeans','discretize','cluster_qr'degree=3,# 多项式核的次数coef0=1# 多项式核/ sigmoid 核的独立项)model.fit(X)print(model.labels_)print(model.affinity_matrix_)# 亲和矩阵4.SpectralBiclustering/SpectralCoclustering— 谱双聚类
fromsklearn.clusterimportSpectralBiclustering,SpectralCoclustering# 双聚类(同时对行和列聚类)model=SpectralBiclustering(n_clusters=3,method='bistochastic',# 'bistochastic','scale','log'n_components=6,n_best=3,svd_method='randomized',n_svd_vecs=None,mini_batch=False,init='k-means++',n_init=10,random_state=42)model.fit(X)print(model.row_labels_)# 行标签print(model.column_labels_)# 列标签# 共聚类(仅用于文档-词矩阵)model=SpectralCoclustering(n_clusters=3,random_state=42)model.fit(X)print(model.row_labels_)print(model.column_labels_)🎯 选择簇数 K
肘部法则(Elbow Method)
fromsklearn.clusterimportKMeansimportmatplotlib.pyplotasplt inertias=[]K_range=range(1,11)forkinK_range:km=KMeans(n_clusters=k,random_state=42,n_init=10)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()轮廓系数
fromsklearn.metricsimportsilhouette_score silhouettes=[]forkinrange(2,11):km=KMeans(n_clusters=k,random_state=42,n_init=10)labels=km.fit_predict(X)sil=silhouette_score(X,labels)silhouettes.append(sil)best_k=K_range[np.argmax(silhouettes)]📝 算法选择指南
| 场景 | 推荐 |
|---|---|
| 一般用途、快速 | KMeans |
| 大数据集在线学习 | MiniBatchKMeans |
| 任意形状簇、含噪音 | DBSCAN |
| 变密度簇 | HDBSCAN/OPTICS |
| 层次结构 | AgglomerativeClustering |
| 软聚类、概率 | GaussianMixture |
| 自动推断簇数 | BayesianGaussianMixture |
| 非凸簇 | SpectralClustering |
| K 已知、球形簇 | KMeans |
[[sklearn-总览|← 返回总览]]
