Scikit-learn 与 PyClust 实战:乳腺癌数据聚类中K值选择与特征降维的3个关键步骤

📅 2026/7/6 11:08:18
Scikit-learn 与 PyClust 实战:乳腺癌数据聚类中K值选择与特征降维的3个关键步骤
Scikit-learn与PyClust实战乳腺癌数据聚类中K值选择与特征降维的3个关键步骤1. 数据准备与预处理在开始乳腺癌数据的聚类分析之前我们需要对原始数据进行系统化的预处理。威斯康星州乳腺癌诊断数据集包含569个样本每个样本有30个特征这些特征描述了细胞核的形态特征如半径、纹理、周长等。首先我们加载数据并进行初步探索from sklearn.datasets import load_breast_cancer import pandas as pd # 加载乳腺癌数据集 data load_breast_cancer() df pd.DataFrame(data.data, columnsdata.feature_names) # 查看数据概览 print(f数据集形状: {df.shape}) print(f特征示例:\n{df.iloc[:, :5].head()})关键预处理步骤缺失值处理检查并处理数据中的缺失值特征相关性分析识别并移除高度相关的特征数据标准化使不同尺度的特征具有可比性from sklearn.preprocessing import StandardScaler from sklearn.feature_selection import VarianceThreshold # 移除低方差特征 selector VarianceThreshold(threshold0.05) df_reduced selector.fit_transform(df) # 标准化数据 scaler StandardScaler() X_scaled scaler.fit_transform(df_reduced)注意在乳腺癌数据集中许多特征是从不同角度测量的相同属性如半径、面积等这些特征往往高度相关需要进行特征选择以避免冗余。2. K值确定与聚类算法选择2.1 肘部法则与轮廓系数确定最佳聚类数K是聚类分析的关键步骤。我们结合肘部法则和轮廓系数两种方法进行综合评估from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score import matplotlib.pyplot as plt import numpy as np # 准备评估指标 inertia [] silhouette_scores [] K_range range(2, 11) for k in K_range: kmeans KMeans(n_clustersk, random_state42) labels kmeans.fit_predict(X_scaled) inertia.append(kmeans.inertia_) silhouette_scores.append(silhouette_score(X_scaled, labels)) # 绘制肘部法则图 plt.figure(figsize(12, 5)) plt.subplot(1, 2, 1) plt.plot(K_range, inertia, bo-) plt.xlabel(Number of clusters (K)) plt.ylabel(Inertia) plt.title(Elbow Method) # 绘制轮廓系数图 plt.subplot(1, 2, 2) plt.plot(K_range, silhouette_scores, ro-) plt.xlabel(Number of clusters (K)) plt.ylabel(Silhouette Score) plt.title(Silhouette Analysis) plt.tight_layout() plt.show()2.2 K-means与K-medoids对比Scikit-learn提供了K-means实现而PyClust库则实现了K-medoids算法。两种算法的主要区别在于中心点的选择特性K-meansK-medoids中心点均值点实际数据点对异常值敏感度高低计算复杂度低高适用数据类型数值型数值型/其他距离度量K-medoids实现示例from pyclust import KMedoids # 使用K-medoids聚类 kmed KMedoids(n_clusters3, distanceeuclidean, max_iter1000) kmed_labels kmed.fit_predict(X_scaled) # 评估K-medoids结果 kmed_silhouette silhouette_score(X_scaled, kmed_labels) print(fK-medoids轮廓系数: {kmed_silhouette:.3f})2.3 聚类效果评估除了轮廓系数外我们还可以使用Calinski-Harabasz指数和Davies-Bouldin指数来评估聚类质量from sklearn.metrics import calinski_harabasz_score, davies_bouldin_score def evaluate_clustering(X, labels): print(f轮廓系数: {silhouette_score(X, labels):.3f}) print(fCalinski-Harabasz指数: {calinski_harabasz_score(X, labels):.3f}) print(fDavies-Bouldin指数: {davies_bouldin_score(X, labels):.3f}) # 评估K-means聚类 kmeans KMeans(n_clusters3, random_state42) kmeans_labels kmeans.fit_predict(X_scaled) print(K-means评估结果:) evaluate_clustering(X_scaled, kmeans_labels) # 评估K-medoids聚类 print(\nK-medoids评估结果:) evaluate_clustering(X_scaled, kmed_labels)3. 特征降维与可视化3.1 主成分分析(PCA)PCA是一种线性降维技术可以帮助我们理解数据的主要变化方向from sklearn.decomposition import PCA # 应用PCA pca PCA(n_components2) X_pca pca.fit_transform(X_scaled) # 可视化PCA结果 plt.figure(figsize(10, 6)) plt.scatter(X_pca[:, 0], X_pca[:, 1], ckmeans_labels, cmapviridis, alpha0.6) plt.xlabel(Principal Component 1) plt.ylabel(Principal Component 2) plt.title(PCA Visualization of Breast Cancer Clusters) plt.colorbar(labelCluster) plt.show() # 查看主成分解释的方差比 print(f主成分解释方差比: {pca.explained_variance_ratio_})3.2 t-SNE非线性降维对于高维数据的可视化t-SNE通常能提供更好的聚类分离效果from sklearn.manifold import TSNE # 应用t-SNE tsne TSNE(n_components2, perplexity30, random_state42) X_tsne tsne.fit_transform(X_scaled) # 可视化t-SNE结果 plt.figure(figsize(10, 6)) plt.scatter(X_tsne[:, 0], X_tsne[:, 1], ckmeans_labels, cmapviridis, alpha0.6) plt.xlabel(t-SNE Component 1) plt.ylabel(t-SNE Component 2) plt.title(t-SNE Visualization of Breast Cancer Clusters) plt.colorbar(labelCluster) plt.show()3.3 降维后的聚类分析我们可以在降维后的空间重新进行聚类并比较结果# 在PCA空间进行聚类 pca_kmeans KMeans(n_clusters3, random_state42) pca_labels pca_kmeans.fit_predict(X_pca) # 比较原始空间和PCA空间的聚类结果 from sklearn.metrics import adjusted_rand_score ari_score adjusted_rand_score(kmeans_labels, pca_labels) print(f原始空间与PCA空间聚类结果的调整Rand指数: {ari_score:.3f}) # 可视化PCA空间的聚类结果 plt.figure(figsize(10, 6)) plt.scatter(X_pca[:, 0], X_pca[:, 1], cpca_labels, cmapviridis, alpha0.6) plt.xlabel(Principal Component 1) plt.ylabel(Principal Component 2) plt.title(Clustering in PCA Space) plt.colorbar(labelCluster) plt.show()4. 完整流程整合与优化4.1 构建端到端聚类流程将前述步骤整合为一个完整的分析流程from sklearn.pipeline import Pipeline from sklearn.compose import ColumnTransformer # 构建完整管道 preprocessor ColumnTransformer( transformers[ (scaler, StandardScaler(), list(range(X_scaled.shape[1]))) ]) cluster_pipeline Pipeline([ (preprocessor, preprocessor), (pca, PCA(n_components0.95)), # 保留95%的方差 (cluster, KMeans(n_clusters3, random_state42)) ]) # 执行完整流程 cluster_pipeline.fit(df) labels cluster_pipeline.predict(df) # 评估最终结果 print(完整流程评估结果:) evaluate_clustering(cluster_pipeline[pca].transform(cluster_pipeline[preprocessor].transform(df)), labels)4.2 参数调优与模型选择使用网格搜索优化聚类参数from sklearn.model_selection import GridSearchCV # 定义参数网格 param_grid { pca__n_components: [0.85, 0.90, 0.95], cluster__n_clusters: [2, 3, 4], cluster__init: [k-means, random] } # 创建网格搜索对象 grid_search GridSearchCV(cluster_pipeline, param_grid, cv5, scoringsilhouette) grid_search.fit(df) # 输出最佳参数 print(f最佳参数: {grid_search.best_params_}) print(f最佳轮廓系数: {grid_search.best_score_:.3f})4.3 结果解释与临床应用聚类分析在乳腺癌数据中的应用可以帮助识别不同的疾病亚型良性/恶性分类验证将聚类结果与真实诊断标签对比特征重要性分析识别对聚类贡献最大的特征临床意义解读将统计发现转化为医学见解# 聚类结果与真实标签对比 from sklearn.metrics import classification_report # 假设我们将聚类0和1合并为良性聚类2为恶性根据医学知识调整 predicted_labels np.where(labels 2, 1, 0) print(classification_report(data.target, predicted_labels)) # 分析各特征对主成分的贡献 pca_loadings pd.DataFrame( cluster_pipeline[pca].components_.T, columns[fPC{i1} for i in range(cluster_pipeline[pca].n_components_)], indexdf.columns ) print(主成分载荷矩阵前5个特征:) print(pca_loadings.iloc[:, 0].abs().sort_values(ascendingFalse).head(5))在实际项目中我发现PCA降维后保留约90-95%的方差通常能在降维效果和信息保留之间取得良好平衡。对于乳腺癌数据纹理特征和凹度特征往往对区分不同聚类有重要贡献。