基于威斯康星乳腺癌数据集实现K-Means时遇ValueError求助
K-Means实现中ValueError问题的修复
问题原因
你的代码在构建distances数据框时维度完全搞反了:
- 计算得到的
distance是长度为699的序列(对应每个样本到单个质心的距离) - 但你错误地将
distances的行索引设为了两个质心的名称(['mu_2', 'mu_4']),导致最终distances的结构是2行、699列,而非预期的699行、2列 - 这就导致
distances['mu_2']和distances['mu_4']的长度仅为2,无法匹配df的699行,触发ValueError
修复方案
调整distances的初始化和构建逻辑,让它的行对应样本、列对应质心:
修复后的完整代码
import pandas as pd import numpy as np url = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data" df = pd.read_csv(url, header=None, na_values="?") df.columns = ['Scn', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10', 'Class'] # 处理缺失值:用列均值填充(原数据有16个缺失值,不处理会影响后续计算) data = df.drop(columns=['Scn', 'Class']).fillna(df.mean()) np.random.seed(42) # 设置固定种子保证结果可复现 centroid_indices = np.random.choice(data.index, 2, replace=False) centroids = data.loc[centroid_indices] centroids.index = ['mu_2', 'mu_4'] max_iterations = 50 iteration = 0 while iteration < max_iterations: distances = pd.DataFrame(index=data.index) # 让distances的行索引和样本一致 for centroid_name, centroid in centroids.iterrows(): # 计算每个样本到当前质心的欧氏距离 distance = ((data - centroid) ** 2).sum(axis=1) ** 0.5 distances[centroid_name] = distance # 现在distances是699行2列,可直接匹配df的行 df['Predicted_Class'] = np.where(distances['mu_2'] < distances['mu_4'], 2, 4) # 计算新质心,只取特征列的均值 new_centroids = df.groupby('Predicted_Class')[data.columns].mean() new_centroids.index = ['mu_2', 'mu_4'] # 保持索引名称一致,方便后续比较 # 检查质心是否收敛 if new_centroids.equals(centroids): break centroids = new_centroids iteration += 1 print(f"迭代次数:{iteration}") print("最终质心:") print(centroids)
额外优化点
- 添加了缺失值处理:原数据包含16个缺失值,用列均值填充避免后续计算出错
- 设置固定随机种子(
np.random.seed(42)),保证实验结果可复现 - 计算新质心时仅选取特征列(
data.columns),避免混入Scn或Class等无关列
内容的提问来源于stack exchange,提问作者Joseph Larson
相关产品推荐
相关产品推荐

