使用sklearn做K-means聚类时样本未围绕质心分组问题求助
K-means聚类结果异常问题排查与解决
核心原因
你使用6830维的超高维基因表达数据做K-means聚类,聚类计算是在全维度空间完成的,但你可视化时仅提取了前两个原始特征维度绘图,这两个维度承载的信息不足,无法体现高维空间内的聚类分布,所以出现了样本看起来没有围绕质心分布的视觉偏差,这大概率不是聚类计算本身的错误。
其他可能影响聚类效果的原因:
- 超高维下欧氏距离区分度下降:K-means基于欧氏距离计算相似度,维度超过1000后欧氏距离的区分度会大幅降低,聚类效果天然受影响
- K值选择无依据:直接指定K=4,未验证该类别数是否匹配数据的真实分布
- 未做噪声过滤:全量6830个基因中存在大量无区分度的噪声特征,会干扰聚类结果
解决方法
1. 先降维再聚类+可视化
优先对高维数据做降维预处理,再完成聚类和可视化,示例代码如下:
import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.decomposition import PCA # PCA降维,保留能解释95%数据方差的维度,也可直接指定降为2/3维方便可视化 pca = PCA(n_components=0.95, random_state=123) reduced_data = pca.fit_transform(standardize.values) # 在降维后的数据上做K-means聚类 km = KMeans(n_clusters=4, n_init=150, random_state=123) km.fit(reduced_data) # 可视化取降维后的前两个维度 fig, ax = plt.subplots(1, figsize=(14,5)) ax.scatter(reduced_data[:,0], reduced_data[:,1], c = km.labels_, cmap=plt.cm.plasma_r) ax.set_title('K-Means Clustering Results with K=4 (PCA Preprocessed)') ax.scatter(km.cluster_centers_[:,0], km.cluster_centers_[:,1], marker='+', s=100, c='k', linewidth=2) plt.show()
如果需要更清晰的聚类边界可视化效果,可替换PCA为UMAP降维:
import umap reducer = umap.UMAP(n_neighbors=15, min_dist=0.1, random_state=123) reduced_data = reducer.fit_transform(standardize.values) # 后续聚类和可视化逻辑和上述代码一致
2. 验证最优K值
不要直接指定K=4,可通过手肘法、轮廓系数法选择匹配数据分布的最优K值,手肘法示例代码:
sse = [] k_candidates = range(2, 10) for k in k_candidates: km = KMeans(n_clusters=k, n_init=150, random_state=123) km.fit(reduced_data) sse.append(km.inertia_) # 绘制手肘图,拐点对应的K即为最优聚类数 plt.plot(k_candidates, sse, 'o-') plt.xlabel('Number of clusters (K)') plt.ylabel('Sum of squared errors') plt.show()
3. 特征过滤
可先筛选出方差排名前1000~2000的基因再做聚类,过滤无区分度的噪声特征,提升聚类效果。
4. 替换聚类算法
如果以上操作完成后聚类效果仍不符合预期,可尝试替换K-means为更适配生物数据的聚类算法,比如层次聚类、谱聚类。
内容的提问来源于stack exchange,提问作者Milos
相关产品推荐
相关产品推荐

