向数组追加k-means聚类中心值时出现数据重复问题咨询
问题说明
你没有错误使用append方法,当前结果和预期不符来自两个原因:
- 循环次数设置错误:你写的
range(1,3)是左闭右开区间,实际只会执行2次循环,和你计划运行3次算法的目标不一致,要跑3次需要写成range(3)或者range(1,4)。 - 对返回结果的结构认知有偏差:
km.cluster_centers_本身就是形状为(聚类数, 特征数)的二维numpy数组,你每次循环把当次运行得到的二维数组追加到列表中,最终得到的「包含多个numpy数组的列表」是符合代码逻辑的正常结果,不是重复追加内容。你贴出的两个数组数值排列顺序不同,是因为每次循环都随机打乱了输入特征的列顺序,聚类中心的列对应打乱后的特征顺序,不属于值重复问题。
对应方案
根据你的存储需求选对应实现即可:
- 如果只需要获取单次k-means运行的聚类中心二维数组,不需要提前创建列表循环追加,模型拟合完成后直接取
km.cluster_centers_,就是你预期的二维数组结构。 - 如果确实需要存储多次k-means运行的所有聚类中心,不需要更换数据结构,两种处理方式都可以:
- 保留现有列表结构:通过列表索引就能取出对应轮次的二维聚类中心数组,比如
center_array[0]就是第一次运行得到的4行聚类中心结果,结构和你给出的预期样例完全一致。 - 合并为高维numpy数组:所有循环运行完成后,执行
np.array(center_array)就能把列表内的多个二维数组合并为形状为(运行次数, 聚类数, 特征数)的三维numpy数组,更方便后续做批量数值计算。
- 保留现有列表结构:通过列表索引就能取出对应轮次的二维聚类中心数组,比如
修正后参考代码
import numpy as np from sklearn.cluster import KMeans from sklearn.preprocessing import MinMaxScaler # 初始化归一化工具 mms = MinMaxScaler() run_times = 3 center_list = [] for i in range(run_times): # 复制原数据避免修改原始数据集 X = dataML.copy() # 按固定随机种子打乱特征列顺序 shuffled_cols = np.random.default_rng(seed=i).permutation(X.columns.values) X = X[shuffled_cols] print(X.head()) # 数据归一化 Xnorm = mms.fit_transform(X) # 训练k-means模型 km = KMeans(n_clusters=4, n_init=10, max_iter=30, random_state=42) y_kmeans = km.fit_predict(Xnorm) # 追加当次计算得到的聚类中心 center_list.append(km.cluster_centers_) # 取第一次运行的聚类中心,即为预期的二维数组 first_run_center = center_list[0] # 如需合并所有轮次结果为三维数组可执行以下代码 all_centers = np.array(center_list)
注意:由于你每次循环都会打乱输入特征的列顺序,不同轮次得到的聚类中心列顺序和原始特征列顺序不对应,解读结果时需要匹配当次打乱后的特征顺序。
内容的提问来源于stack exchange,提问作者P.Brito
相关产品推荐
相关产品推荐

