求助:修复基于MRI数据的K-means聚类Python脚本问题
问题解决方案
问题1:聚类数远低于设定值
原因分析
- 特征维度错误:代码中将3D图像reshape为
(-1, 3),实际是把每个体素的**空间坐标(x,y,z)**作为聚类特征,而非体素的强度值。空间坐标的分布特性决定了无法生成100个有效聚类。 - 迭代参数设置不合理:
n_init=1(仅1次初始化)和max_iter=1(仅1次迭代),KMeans算法没有足够的收敛次数,无法达到设定的100个聚类。
修复步骤
- 将特征维度修正为体素强度:3D图像应reshape为
(-1, 1),每个样本对应一个体素的强度值;若为4D多模态图像,则对应(-1, 模态数)。 - 调整KMeans参数:恢复
n_init默认值10、max_iter默认值300,确保算法有足够次数收敛到设定聚类数。
问题2:生成的NIfTI显示为3x3网格而非单图
原因分析
代码中labels.reshape(-1, 290, 292)手动指定维度顺序,与原NIfTI文件的维度顺序不匹配,导致图像轴被打乱,显示时出现网格错位。
修复步骤
- 使用原数据的形状直接reshape聚类标签:
labels.reshape(ztkmeans.shape),确保新图像的维度、轴顺序与原文件完全一致。
修正后的完整代码
# 加载NIfTI文件(假设kmeansnifti已通过nibabel.load加载) ztkmeans = kmeansnifti.get_fdata() # 修正特征维度:将3D体素强度转为单特征样本矩阵 # 若为4D多模态数据,改为reshape(-1, ztkmeans.shape[-1]) ztk2d = ztkmeans.reshape(-1, 1) n_clusters = 100 to_kmeans = km( init='k-means++', n_clusters=n_clusters, n_init=10, # 多次初始化保证聚类稳定性 max_iter=300, # 保证算法充分收敛 tol=0.0001, verbose=1, random_state=None, copy_x=True, algorithm='lloyd' ) kmeans = to_kmeans.fit(ztk2d) labels = kmeans.labels_ # 修正reshape,与原数据形状完全一致 labels_reshaped = labels.reshape(ztkmeans.shape) # 创建新NIfTI文件,保留原文件的空间信息 kmeans_img = nibabel.Nifti1Image(labels_reshaped, kmeansnifti.affine, kmeansnifti.header) # 保存文件 save_path = f"{cruise}/{Patient[i]}/{ereg[b]}/kmeans.nii.gz" print(f'Saving kmeans_img as {save_path}') nibabel.save(kmeans_img, save_path) print('Done')
内容的提问来源于stack exchange,提问作者Björn
相关产品推荐
相关产品推荐

